summaryrefslogtreecommitdiffstats
path: root/Python/Python-ast.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/Python-ast.c')
0 files changed, 0 insertions, 0 deletions
2446'>bug_3362446 Tcl is a high-level, general-purpose, interpreted, dynamic programming language. It was designed with the goal of being very simple but powerful.
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat
-rw-r--r--.fossil-settings/binary-glob3
-rw-r--r--.fossil-settings/crnl-glob0
-rw-r--r--.fossil-settings/ignore-glob24
-rw-r--r--.project11
-rw-r--r--.settings/org.eclipse.core.resources.prefs2
-rw-r--r--.settings/org.eclipse.core.runtime.prefs2
-rw-r--r--ChangeLog2855
-rw-r--r--ChangeLog.20004
-rw-r--r--ChangeLog.20012
-rw-r--r--ChangeLog.20032
-rw-r--r--README31
-rw-r--r--changes476
-rw-r--r--compat/dirent2.h2
-rw-r--r--compat/dlfcn.h2
-rw-r--r--compat/fake-rfc2553.c6
-rw-r--r--compat/string.h2
-rw-r--r--compat/unistd.h1
-rw-r--r--compat/zlib/CMakeLists.txt115
-rw-r--r--compat/zlib/ChangeLog268
-rw-r--r--compat/zlib/FAQ12
-rw-r--r--compat/zlib/INDEX13
-rw-r--r--compat/zlib/Makefile.in111
-rw-r--r--compat/zlib/README24
-rw-r--r--compat/zlib/adler32.c70
-rw-r--r--compat/zlib/as400/bndsrc (renamed from compat/zlib/old/as400/bndsrc)83
-rw-r--r--compat/zlib/as400/compile.clp110
-rw-r--r--compat/zlib/as400/readme.txt (renamed from compat/zlib/old/as400/readme.txt)14
-rw-r--r--compat/zlib/as400/zlib.inc (renamed from compat/zlib/old/as400/zlib.inc)160
-rw-r--r--compat/zlib/compress.c4
-rwxr-xr-xcompat/zlib/configure521
-rw-r--r--compat/zlib/contrib/README.contrib1
-rw-r--r--compat/zlib/contrib/ada/buffer_demo.adb2
-rw-r--r--compat/zlib/contrib/ada/mtest.adb2
-rw-r--r--compat/zlib/contrib/ada/read.adb2
-rw-r--r--compat/zlib/contrib/ada/test.adb2
-rw-r--r--compat/zlib/contrib/ada/zlib-streams.adb2
-rw-r--r--compat/zlib/contrib/ada/zlib-streams.ads2
-rw-r--r--compat/zlib/contrib/ada/zlib-thin.adb2
-rw-r--r--compat/zlib/contrib/ada/zlib-thin.ads2
-rw-r--r--compat/zlib/contrib/ada/zlib.adb2
-rw-r--r--compat/zlib/contrib/ada/zlib.ads2
-rw-r--r--compat/zlib/contrib/asm586/README.58643
-rw-r--r--compat/zlib/contrib/asm586/match.S364
-rw-r--r--compat/zlib/contrib/asm686/match.S16
-rw-r--r--compat/zlib/contrib/blast/blast.c8
-rw-r--r--compat/zlib/contrib/blast/blast.h8
-rw-r--r--compat/zlib/contrib/delphi/ZLib.pas2
-rw-r--r--compat/zlib/contrib/delphi/zlibd32.mak4
-rw-r--r--compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs4
-rw-r--r--compat/zlib/contrib/infback9/infback9.c4
-rw-r--r--compat/zlib/contrib/infback9/inftree9.c6
-rw-r--r--compat/zlib/contrib/iostream2/zstream.h2
-rw-r--r--compat/zlib/contrib/masm686/match.asm413
-rw-r--r--compat/zlib/contrib/masmx64/gvmat64.objbin4119 -> 0 bytes
-rw-r--r--compat/zlib/contrib/masmx64/inffasx64.objbin5913 -> 0 bytes
-rw-r--r--compat/zlib/contrib/masmx86/gvmat32.asm972
-rw-r--r--compat/zlib/contrib/masmx86/gvmat32.objbin10241 -> 0 bytes
-rw-r--r--compat/zlib/contrib/masmx86/gvmat32c.c62
-rw-r--r--compat/zlib/contrib/masmx86/inffas32.asm9
-rw-r--r--compat/zlib/contrib/masmx86/inffas32.objbin14893 -> 0 bytes
-rw-r--r--compat/zlib/contrib/masmx86/match686.asm1
-rwxr-xr-xcompat/zlib/contrib/masmx86/mkasm.bat3
-rw-r--r--compat/zlib/contrib/minizip/ChangeLogUnzip67
-rw-r--r--compat/zlib/contrib/minizip/Makefile.am45
-rw-r--r--compat/zlib/contrib/minizip/configure.ac32
-rw-r--r--compat/zlib/contrib/minizip/crypt.h8
-rw-r--r--compat/zlib/contrib/minizip/ioapi.c22
-rw-r--r--compat/zlib/contrib/minizip/ioapi.h10
-rw-r--r--compat/zlib/contrib/minizip/iowin32.c98
-rw-r--r--compat/zlib/contrib/minizip/miniunz.c38
-rw-r--r--compat/zlib/contrib/minizip/miniunzip.163
-rw-r--r--compat/zlib/contrib/minizip/minizip.146
-rw-r--r--compat/zlib/contrib/minizip/minizip.c39
-rw-r--r--compat/zlib/contrib/minizip/minizip.pc.in12
-rw-r--r--compat/zlib/contrib/minizip/mztools.c24
-rw-r--r--compat/zlib/contrib/minizip/mztools.h6
-rw-r--r--compat/zlib/contrib/minizip/unzip.c24
-rw-r--r--compat/zlib/contrib/minizip/unzip.h4
-rw-r--r--compat/zlib/contrib/minizip/zip.c15
-rw-r--r--compat/zlib/contrib/pascal/zlibd32.mak4
-rw-r--r--compat/zlib/contrib/pascal/zlibpas.pas42
-rw-r--r--compat/zlib/contrib/puff/Makefile40
-rw-r--r--compat/zlib/contrib/puff/puff.c257
-rw-r--r--compat/zlib/contrib/puff/puff.h10
-rw-r--r--compat/zlib/contrib/puff/pufftest.c165
-rw-r--r--compat/zlib/contrib/puff/zeros.rawbin1213 -> 2517 bytes
-rw-r--r--compat/zlib/contrib/testzlib/testzlib.c4
-rw-r--r--compat/zlib/contrib/vstudio/readme.txt19
-rw-r--r--compat/zlib/contrib/vstudio/vc10/miniunz.vcxproj.user3
-rw-r--r--compat/zlib/contrib/vstudio/vc10/minizip.vcxproj.user3
-rw-r--r--compat/zlib/contrib/vstudio/vc10/testzlib.vcxproj.user3
-rw-r--r--compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj12
-rw-r--r--compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.user3
-rw-r--r--compat/zlib/contrib/vstudio/vc10/zlib.rc10
-rw-r--r--compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj16
-rw-r--r--compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.user3
-rw-r--r--compat/zlib/contrib/vstudio/vc10/zlibvc.def15
-rw-r--r--compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj46
-rw-r--r--compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.user3
-rw-r--r--compat/zlib/contrib/vstudio/vc11/miniunz.vcxproj314
-rw-r--r--compat/zlib/contrib/vstudio/vc11/minizip.vcxproj311
-rw-r--r--compat/zlib/contrib/vstudio/vc11/testzlib.vcxproj426
-rw-r--r--compat/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj314
-rw-r--r--compat/zlib/contrib/vstudio/vc11/zlib.rc (renamed from compat/zlib/contrib/vstudio/vc7/zlib.rc)12
-rw-r--r--compat/zlib/contrib/vstudio/vc11/zlibstat.vcxproj464
-rw-r--r--compat/zlib/contrib/vstudio/vc11/zlibvc.def (renamed from compat/zlib/contrib/vstudio/vc7/zlibvc.def)57
-rw-r--r--compat/zlib/contrib/vstudio/vc11/zlibvc.sln (renamed from compat/zlib/contrib/vstudio/vc8/zlibvc.sln)95
-rw-r--r--compat/zlib/contrib/vstudio/vc11/zlibvc.vcxproj688
-rw-r--r--compat/zlib/contrib/vstudio/vc7/miniunz.vcproj126
-rw-r--r--compat/zlib/contrib/vstudio/vc7/minizip.vcproj126
-rw-r--r--compat/zlib/contrib/vstudio/vc7/testzlib.vcproj126
-rw-r--r--compat/zlib/contrib/vstudio/vc7/zlibstat.vcproj246
-rw-r--r--compat/zlib/contrib/vstudio/vc7/zlibvc.sln78
-rw-r--r--compat/zlib/contrib/vstudio/vc7/zlibvc.vcproj445
-rw-r--r--compat/zlib/contrib/vstudio/vc8/miniunz.vcproj566
-rw-r--r--compat/zlib/contrib/vstudio/vc8/minizip.vcproj563
-rw-r--r--compat/zlib/contrib/vstudio/vc8/testzlib.vcproj948
-rw-r--r--compat/zlib/contrib/vstudio/vc8/testzlibdll.vcproj567
-rw-r--r--compat/zlib/contrib/vstudio/vc8/zlib.rc32
-rw-r--r--compat/zlib/contrib/vstudio/vc8/zlibstat.vcproj870
-rw-r--r--compat/zlib/contrib/vstudio/vc8/zlibvc.def92
-rw-r--r--compat/zlib/contrib/vstudio/vc8/zlibvc.vcproj1219
-rw-r--r--compat/zlib/contrib/vstudio/vc9/zlib.rc10
-rw-r--r--compat/zlib/contrib/vstudio/vc9/zlibvc.def15
-rw-r--r--compat/zlib/crc32.c85
-rw-r--r--compat/zlib/crc32.h2
-rw-r--r--compat/zlib/deflate.c265
-rw-r--r--compat/zlib/deflate.h14
-rw-r--r--compat/zlib/doc/algorithm.txt2
-rw-r--r--compat/zlib/examples/enough.c39
-rw-r--r--compat/zlib/examples/gun.c11
-rw-r--r--compat/zlib/examples/gzappend.c22
-rw-r--r--compat/zlib/examples/gzjoin.c13
-rw-r--r--compat/zlib/examples/gzlog.c21
-rw-r--r--compat/zlib/examples/gzlog.h6
-rw-r--r--compat/zlib/examples/zran.c11
-rw-r--r--compat/zlib/gzguts.h103
-rw-r--r--compat/zlib/gzlib.c197
-rw-r--r--compat/zlib/gzread.c431
-rw-r--r--compat/zlib/gzwrite.c196
-rw-r--r--compat/zlib/infback.c16
-rw-r--r--compat/zlib/inffast.c6
-rw-r--r--compat/zlib/inffixed.h6
-rw-r--r--compat/zlib/inflate.c136
-rw-r--r--compat/zlib/inftrees.c54
-rw-r--r--compat/zlib/make_vms.com403
-rw-r--r--compat/zlib/msdos/Makefile.bor4
-rw-r--r--compat/zlib/msdos/Makefile.msc4
-rw-r--r--compat/zlib/msdos/Makefile.tc4
-rw-r--r--compat/zlib/old/Makefile.emx (renamed from compat/zlib/win32/Makefile.emx)0
-rw-r--r--compat/zlib/old/as400/compile.clp123
-rw-r--r--compat/zlib/old/visualc6/README.txt73
-rw-r--r--compat/zlib/old/visualc6/example.dsp278
-rw-r--r--compat/zlib/old/visualc6/minigzip.dsp278
-rw-r--r--compat/zlib/old/visualc6/zlib.dsp621
-rw-r--r--compat/zlib/old/visualc6/zlib.dsw59
-rw-r--r--compat/zlib/qnx/package.qpg10
-rw-r--r--compat/zlib/test/example.c (renamed from compat/zlib/example.c)92
-rw-r--r--compat/zlib/test/infcover.c671
-rw-r--r--compat/zlib/test/minigzip.c (renamed from compat/zlib/minigzip.c)215
-rw-r--r--compat/zlib/treebuild.xml4
-rw-r--r--compat/zlib/trees.c56
-rw-r--r--compat/zlib/uncompr.c4
-rw-r--r--compat/zlib/win32/Makefile.bor4
-rw-r--r--compat/zlib/win32/Makefile.gcc72
-rw-r--r--compat/zlib/win32/Makefile.msc82
-rw-r--r--compat/zlib/win32/README-WIN32.txt8
-rw-r--r--compat/zlib/win32/README.txt17
-rw-r--r--compat/zlib/win32/zdll.libbin13438 -> 15658 bytes
-rw-r--r--compat/zlib/win32/zlib.def16
-rwxr-xr-x[-rw-r--r--]compat/zlib/win32/zlib1.dllbin100352 -> 107520 bytes
-rw-r--r--compat/zlib/win32/zlib1.rc2
-rw-r--r--compat/zlib/win64/libz.dll.abin0 -> 46874 bytes
-rw-r--r--compat/zlib/win64/zdll.libbin0 -> 15288 bytes
-rwxr-xr-xcompat/zlib/win64/zlib1.dllbin0 -> 112640 bytes
-rw-r--r--compat/zlib/zconf.h203
-rw-r--r--compat/zlib/zconf.h.cmakein203
-rw-r--r--compat/zlib/zconf.h.in203
-rw-r--r--compat/zlib/zlib.318
-rw-r--r--compat/zlib/zlib.3.pdfbin8686 -> 8734 bytes
-rw-r--r--compat/zlib/zlib.h345
-rw-r--r--compat/zlib/zlib.map15
-rw-r--r--compat/zlib/zlib.pc.cmakein13
-rw-r--r--compat/zlib/zutil.c28
-rw-r--r--compat/zlib/zutil.h105
-rw-r--r--doc/Access.32
-rw-r--r--doc/AddErrInfo.328
-rw-r--r--doc/Alloc.32
-rw-r--r--doc/AllowExc.32
-rw-r--r--doc/AppInit.32
-rw-r--r--doc/AssocData.32
-rw-r--r--doc/Async.32
-rw-r--r--doc/BackgdErr.32
-rw-r--r--doc/Backslash.32
-rw-r--r--doc/BoolObj.36
-rw-r--r--doc/ByteArrObj.348
-rw-r--r--doc/CallDel.32
-rw-r--r--doc/Cancel.32
-rw-r--r--doc/ChnlStack.32
-rw-r--r--doc/Class.36
-rw-r--r--doc/CmdCmplt.32
-rw-r--r--doc/Concat.32
-rw-r--r--doc/CrtChannel.310
-rw-r--r--doc/CrtChnlHdlr.32
-rw-r--r--doc/CrtCloseHdlr.32
-rw-r--r--doc/CrtCommand.314
-rw-r--r--doc/CrtFileHdlr.32
-rw-r--r--doc/CrtInterp.39
-rw-r--r--doc/CrtMathFnc.313
-rw-r--r--doc/CrtObjCmd.322
-rw-r--r--doc/CrtSlave.324
-rw-r--r--doc/CrtTimerHdlr.32
-rw-r--r--doc/CrtTrace.32
-rw-r--r--doc/DString.32
-rw-r--r--doc/DetachPids.32
-rw-r--r--doc/DictObj.336
-rw-r--r--doc/DoOneEvent.32
-rw-r--r--doc/DoWhenIdle.32
-rw-r--r--doc/DoubleObj.328
-rw-r--r--doc/DumpActiveMemory.32
-rw-r--r--doc/Encoding.32
-rw-r--r--doc/Ensemble.36
-rw-r--r--doc/Environment.34
-rw-r--r--doc/Eval.322
-rw-r--r--doc/Exit.32
-rw-r--r--doc/ExprLong.310
-rw-r--r--doc/ExprLongObj.314
-rw-r--r--doc/FileSystem.3143
-rw-r--r--doc/FindExec.34
-rw-r--r--[-rwxr-xr-x]doc/GetCwd.32
-rw-r--r--doc/GetHostName.32
-rw-r--r--doc/GetIndex.320
-rw-r--r--doc/GetInt.32
-rw-r--r--doc/GetOpnFl.32
-rw-r--r--doc/GetStdChan.34
-rw-r--r--doc/GetTime.326
-rw-r--r--[-rwxr-xr-x]doc/GetVersion.32
-rw-r--r--doc/Hash.312
-rw-r--r--doc/Init.32
-rw-r--r--doc/InitStubs.38
-rw-r--r--doc/IntObj.333
-rw-r--r--doc/Interp.32
-rw-r--r--doc/Limit.32
-rw-r--r--doc/LinkVar.32
-rw-r--r--doc/ListObj.3119
-rw-r--r--doc/Load.35
-rw-r--r--doc/Method.37
-rw-r--r--doc/NRE.324
-rw-r--r--doc/Namespace.34
-rw-r--r--doc/Notifier.34
-rw-r--r--doc/OOInitStubs.354
-rw-r--r--doc/Object.3180
-rw-r--r--doc/ObjectType.365
-rw-r--r--doc/OpenFileChnl.330
-rw-r--r--doc/OpenTcp.32
-rw-r--r--doc/Panic.32
-rw-r--r--doc/ParseArgs.36
-rw-r--r--doc/ParseCmd.36
-rw-r--r--doc/PkgRequire.32
-rw-r--r--doc/Preserve.32
-rw-r--r--doc/PrintDbl.32
-rw-r--r--doc/RecEvalObj.38
-rw-r--r--doc/RecordEval.38
-rw-r--r--doc/RegConfig.34
-rw-r--r--doc/RegExp.320
-rw-r--r--doc/SaveResult.36
-rw-r--r--doc/SetChanErr.312
-rw-r--r--doc/SetErrno.32
-rw-r--r--doc/SetRecLmt.32
-rw-r--r--doc/SetResult.344
-rw-r--r--doc/SetVar.310
-rw-r--r--doc/Signal.32
-rw-r--r--doc/Sleep.32
-rw-r--r--doc/SourceRCFile.32
-rw-r--r--doc/SplitList.32
-rw-r--r--doc/SplitPath.34
-rw-r--r--doc/StaticPkg.32
-rw-r--r--doc/StdChannels.32
-rw-r--r--doc/StrMatch.32
-rw-r--r--doc/StringObj.3108
-rw-r--r--doc/SubstObj.38
-rw-r--r--doc/TCL_MEM_DEBUG.34
-rw-r--r--doc/Tcl.n59
-rw-r--r--doc/TclZlib.346
-rw-r--r--doc/Tcl_Main.32
-rw-r--r--doc/Thread.314
-rw-r--r--doc/ToUpper.32
-rw-r--r--doc/TraceCmd.32
-rw-r--r--doc/TraceVar.32
-rw-r--r--doc/Translate.32
-rw-r--r--doc/UniCharIsAlpha.32
-rw-r--r--doc/UpVar.32
-rw-r--r--doc/Utf.32
-rw-r--r--doc/WrongNumArgs.316
-rw-r--r--doc/after.n2
-rw-r--r--doc/append.n2
-rw-r--r--doc/apply.n2
-rw-r--r--doc/array.n2
-rw-r--r--doc/bgerror.n7
-rw-r--r--doc/binary.n32
-rw-r--r--doc/break.n2
-rw-r--r--doc/case.n2
-rw-r--r--doc/catch.n7
-rw-r--r--doc/cd.n2
-rw-r--r--doc/chan.n38
-rw-r--r--doc/class.n2
-rw-r--r--doc/clock.n2
-rw-r--r--doc/close.n25
-rw-r--r--doc/concat.n2
-rw-r--r--doc/continue.n2
-rw-r--r--doc/copy.n23
-rw-r--r--doc/coroutine.n58
-rw-r--r--doc/dde.n35
-rw-r--r--doc/define.n193
-rw-r--r--doc/dict.n50
-rw-r--r--doc/encoding.n36
-rw-r--r--doc/eof.n2
-rw-r--r--doc/error.n2
-rw-r--r--doc/eval.n5
-rw-r--r--doc/exec.n2
-rw-r--r--doc/exit.n2
-rw-r--r--doc/expr.n39
-rw-r--r--doc/fconfigure.n6
-rw-r--r--doc/fcopy.n29
-rw-r--r--doc/file.n9
-rw-r--r--doc/fileevent.n19
-rw-r--r--doc/filename.n2
-rw-r--r--doc/flush.n2
-rw-r--r--doc/for.n2
-rw-r--r--doc/foreach.n2
-rw-r--r--doc/format.n2
-rw-r--r--doc/gets.n12
-rw-r--r--doc/glob.n2
-rw-r--r--doc/global.n2
-rw-r--r--doc/history.n2
-rw-r--r--doc/http.n2
-rw-r--r--doc/if.n2
-rw-r--r--doc/incr.n2
-rw-r--r--doc/info.n96
-rw-r--r--doc/interp.n6
-rw-r--r--doc/join.n2
-rw-r--r--doc/lappend.n2
-rw-r--r--doc/lassign.n2
-rw-r--r--doc/library.n12
-rw-r--r--doc/lindex.n2
-rw-r--r--doc/linsert.n2
-rw-r--r--doc/list.n2
-rw-r--r--doc/llength.n2
-rw-r--r--doc/lmap.n85
-rw-r--r--doc/load.n24
-rw-r--r--doc/lrange.n2
-rw-r--r--doc/lrepeat.n2
-rw-r--r--doc/lreplace.n2
-rw-r--r--doc/lreverse.n2
-rw-r--r--doc/lsearch.n2
-rw-r--r--[-rwxr-xr-x]doc/lset.n2
-rw-r--r--doc/lsort.n2
-rw-r--r--doc/mathfunc.n6
-rw-r--r--doc/mathop.n17
-rw-r--r--doc/memory.n2
-rw-r--r--doc/msgcat.n56
-rw-r--r--doc/my.n4
-rw-r--r--doc/namespace.n9
-rw-r--r--doc/next.n23
-rw-r--r--doc/object.n29
-rw-r--r--doc/open.n2
-rw-r--r--doc/package.n2
-rw-r--r--doc/packagens.n2
-rw-r--r--doc/pid.n2
-rw-r--r--doc/pkgMkIndex.n2
-rw-r--r--doc/platform.n26
-rw-r--r--doc/platform_shell.n2
-rw-r--r--doc/prefix.n2
-rw-r--r--doc/proc.n6
-rw-r--r--doc/puts.n2
-rw-r--r--doc/pwd.n2
-rw-r--r--doc/re_syntax.n42
-rw-r--r--doc/read.n2
-rw-r--r--doc/refchan.n2
-rw-r--r--doc/regexp.n2
-rw-r--r--doc/registry.n2
-rw-r--r--doc/regsub.n2
-rw-r--r--doc/rename.n2
-rw-r--r--doc/return.n6
-rw-r--r--doc/safe.n10
-rw-r--r--doc/scan.n6
-rw-r--r--doc/seek.n8
-rw-r--r--doc/self.n4
-rw-r--r--doc/set.n2
-rw-r--r--doc/socket.n25
-rw-r--r--doc/source.n2
-rw-r--r--doc/split.n2
-rw-r--r--doc/string.n96
-rw-r--r--doc/subst.n2
-rw-r--r--doc/switch.n2
-rw-r--r--doc/tailcall.n2
-rw-r--r--doc/tclsh.112
-rw-r--r--doc/tcltest.n2
-rw-r--r--doc/tclvars.n15
-rw-r--r--doc/tell.n2
-rw-r--r--doc/throw.n4
-rw-r--r--doc/time.n2
-rw-r--r--doc/tm.n2
-rw-r--r--doc/trace.n4
-rw-r--r--doc/transchan.n2
-rw-r--r--doc/try.n4
-rw-r--r--doc/unknown.n2
-rw-r--r--doc/unload.n2
-rw-r--r--doc/unset.n2
-rw-r--r--doc/update.n2
-rw-r--r--doc/uplevel.n2
-rw-r--r--doc/upvar.n2
-rw-r--r--doc/variable.n2
-rw-r--r--doc/vwait.n2
-rw-r--r--doc/while.n2
-rw-r--r--doc/zlib.n138
-rw-r--r--generic/regc_color.c7
-rw-r--r--generic/regc_lex.c35
-rw-r--r--generic/regc_locale.c970
-rw-r--r--generic/regc_nfa.c339
-rw-r--r--generic/regcomp.c16
-rw-r--r--generic/regcustom.h2
-rw-r--r--generic/regerrs.h1
-rw-r--r--generic/regex.h1
-rw-r--r--generic/regexec.c7
-rw-r--r--generic/regguts.h9
-rw-r--r--generic/tcl.decls20
-rw-r--r--generic/tcl.h220
-rw-r--r--generic/tclAlloc.c20
-rw-r--r--generic/tclAssembly.c207
-rw-r--r--generic/tclBasic.c1573
-rw-r--r--generic/tclBinary.c564
-rw-r--r--generic/tclCkalloc.c69
-rw-r--r--generic/tclClock.c50
-rw-r--r--generic/tclCmdAH.c290
-rw-r--r--generic/tclCmdIL.c467
-rw-r--r--generic/tclCmdMZ.c261
-rw-r--r--generic/tclCompCmds.c3941
-rw-r--r--generic/tclCompCmdsGR.c3171
-rw-r--r--generic/tclCompCmdsSZ.c2338
-rw-r--r--generic/tclCompExpr.c590
-rw-r--r--generic/tclCompile.c1958
-rw-r--r--generic/tclCompile.h395
-rw-r--r--generic/tclConfig.c119
-rw-r--r--generic/tclDTrace.d16
-rw-r--r--generic/tclDate.c2
-rw-r--r--generic/tclDecls.h158
-rw-r--r--generic/tclDictObj.c620
-rw-r--r--generic/tclEncoding.c26
-rw-r--r--generic/tclEnsemble.c823
-rw-r--r--generic/tclEnv.c108
-rw-r--r--generic/tclEvent.c24
-rw-r--r--generic/tclExecute.c3054
-rw-r--r--generic/tclFCmd.c163
-rw-r--r--generic/tclFileName.c318
-rw-r--r--generic/tclFileSystem.h55
-rw-r--r--generic/tclGet.c4
-rw-r--r--generic/tclHash.c4
-rw-r--r--generic/tclIO.c1471
-rw-r--r--generic/tclIO.h125
-rw-r--r--generic/tclIOCmd.c222
-rw-r--r--generic/tclIOGT.c131
-rw-r--r--generic/tclIORChan.c584
-rw-r--r--generic/tclIORTrans.c304
-rw-r--r--generic/tclIOSock.c91
-rw-r--r--generic/tclIOUtil.c454
-rw-r--r--generic/tclIndexObj.c202
-rw-r--r--generic/tclInt.decls158
-rw-r--r--generic/tclInt.h482
-rw-r--r--generic/tclIntDecls.h172
-rw-r--r--generic/tclIntPlatDecls.h223
-rw-r--r--generic/tclInterp.c218
-rw-r--r--generic/tclLink.c21
-rw-r--r--generic/tclListObj.c33
-rw-r--r--generic/tclLiteral.c99
-rw-r--r--generic/tclLoad.c170
-rw-r--r--generic/tclLoadNone.c40
-rw-r--r--generic/tclMain.c140
-rw-r--r--generic/tclNamesp.c517
-rw-r--r--generic/tclNotify.c6
-rw-r--r--generic/tclOO.c705
-rw-r--r--generic/tclOO.decls20
-rw-r--r--generic/tclOO.h27
-rw-r--r--generic/tclOOBasic.c339
-rw-r--r--generic/tclOOCall.c31
-rw-r--r--generic/tclOODecls.h101
-rw-r--r--generic/tclOODefineCmds.c1274
-rw-r--r--generic/tclOOInfo.c177
-rw-r--r--generic/tclOOInt.h49
-rw-r--r--generic/tclOOIntDecls.h62
-rw-r--r--generic/tclOOMethod.c94
-rw-r--r--generic/tclOOStubLib.c73
-rw-r--r--generic/tclObj.c159
-rw-r--r--generic/tclOptimize.c444
-rw-r--r--generic/tclPanic.c31
-rw-r--r--generic/tclParse.c77
-rw-r--r--generic/tclParse.h17
-rw-r--r--generic/tclPathObj.c353
-rw-r--r--generic/tclPipe.c103
-rw-r--r--generic/tclPkg.c125
-rw-r--r--generic/tclPkgConfig.c4
-rw-r--r--generic/tclPlatDecls.h18
-rw-r--r--generic/tclPort.h15
-rw-r--r--generic/tclProc.c234
-rw-r--r--generic/tclRegexp.c18
-rw-r--r--generic/tclResult.c107
-rw-r--r--generic/tclScan.c61
-rw-r--r--[-rwxr-xr-x]generic/tclStrToD.c19
-rw-r--r--generic/tclStringObj.c211
-rw-r--r--generic/tclStringTrim.h43
-rw-r--r--generic/tclStubInit.c336
-rw-r--r--generic/tclStubLib.c46
-rw-r--r--generic/tclStubLibTbl.c58
-rw-r--r--generic/tclTest.c474
-rw-r--r--generic/tclTestObj.c19
-rw-r--r--generic/tclThread.c8
-rw-r--r--generic/tclThreadAlloc.c47
-rw-r--r--generic/tclThreadJoin.c4
-rw-r--r--generic/tclThreadTest.c37
-rw-r--r--generic/tclTimer.c20
-rw-r--r--generic/tclTomMath.decls6
-rw-r--r--generic/tclTomMath.h1
-rw-r--r--generic/tclTomMathDecls.h22
-rw-r--r--generic/tclTomMathInt.h1
-rw-r--r--generic/tclTomMathInterface.c6
-rw-r--r--generic/tclTomMathStubLib.c28
-rw-r--r--generic/tclTrace.c82
-rw-r--r--generic/tclUniData.c1978
-rw-r--r--generic/tclUtf.c119
-rw-r--r--generic/tclUtil.c1010
-rw-r--r--generic/tclVar.c400
-rw-r--r--generic/tclZlib.c2153
-rw-r--r--library/auto.tcl99
-rw-r--r--library/clock.tcl39
-rw-r--r--library/dde/pkgIndex.tcl10
-rw-r--r--[-rwxr-xr-x]library/encoding/tis-620.enc0
-rw-r--r--library/history.tcl2
-rw-r--r--library/http/http.tcl141
-rw-r--r--library/http/pkgIndex.tcl2
-rw-r--r--library/init.tcl114
-rw-r--r--library/msgcat/msgcat.tcl150
-rw-r--r--library/msgcat/pkgIndex.tcl2
-rw-r--r--[-rwxr-xr-x]library/msgs/af.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/af_za.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ar.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ar_in.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ar_jo.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ar_lb.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ar_sy.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/be.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/bg.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/bn.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/bn_in.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ca.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/cs.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/da.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/de.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/de_at.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/de_be.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/el.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/en_au.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/en_be.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/en_bw.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/en_ca.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/en_gb.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/en_hk.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/en_ie.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/en_in.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/en_nz.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/en_ph.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/en_sg.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/en_za.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/en_zw.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/eo.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_ar.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_bo.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_cl.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_co.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_cr.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_do.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_ec.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_gt.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_hn.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_mx.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_ni.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_pa.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_pe.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_pr.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_py.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_sv.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_uy.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/es_ve.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/et.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/eu.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/eu_es.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/fa.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/fa_in.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/fa_ir.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/fi.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/fo.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/fo_fo.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/fr.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/fr_be.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/fr_ca.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/fr_ch.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ga.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ga_ie.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/gl.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/gl_es.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/gv.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/gv_gb.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/he.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/hi.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/hi_in.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/hr.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/hu.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/id.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/id_id.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/is.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/it.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/it_ch.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ja.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/kl.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/kl_gl.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ko.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ko_kr.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/kok.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/kok_in.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/kw.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/kw_gb.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/lt.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/lv.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/mk.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/mr.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/mr_in.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ms.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ms_my.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/mt.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/nb.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/nl.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/nl_be.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/nn.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/pl.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/pt.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/pt_br.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ro.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ru.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ru_ua.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/sh.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/sk.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/sl.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/sq.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/sr.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/sv.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/sw.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ta.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/ta_in.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/te.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/te_in.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/th.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/tr.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/uk.msg2
-rw-r--r--[-rwxr-xr-x]library/msgs/vi.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/zh.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/zh_cn.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/zh_hk.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/zh_sg.msg0
-rw-r--r--[-rwxr-xr-x]library/msgs/zh_tw.msg0
-rw-r--r--library/package.tcl28
-rw-r--r--library/parray.tcl2
-rw-r--r--library/platform/pkgIndex.tcl2
-rw-r--r--library/platform/platform.tcl4
-rw-r--r--library/platform/shell.tcl2
-rwxr-xr-xlibrary/reg/pkgIndex.tcl10
-rw-r--r--library/safe.tcl153
-rw-r--r--library/tcltest/pkgIndex.tcl2
-rw-r--r--library/tcltest/tcltest.tcl222
-rw-r--r--library/tm.tcl19
-rw-r--r--[-rwxr-xr-x]library/tzdata/Africa/Asmara0
-rw-r--r--library/tzdata/Africa/Cairo4
-rw-r--r--library/tzdata/Africa/Casablanca136
-rw-r--r--library/tzdata/Africa/Dar_es_Salaam4
-rw-r--r--library/tzdata/Africa/Gaborone3
-rw-r--r--library/tzdata/Africa/Juba5
-rw-r--r--library/tzdata/Africa/Kampala4
-rw-r--r--library/tzdata/Africa/Nairobi4
-rw-r--r--library/tzdata/Africa/Tripoli177
-rw-r--r--library/tzdata/America/Anguilla7
-rw-r--r--library/tzdata/America/Araguaina3
-rw-r--r--library/tzdata/America/Argentina/San_Luis2
-rw-r--r--library/tzdata/America/Aruba8
-rw-r--r--library/tzdata/America/Asuncion174
-rw-r--r--[-rwxr-xr-x]library/tzdata/America/Atikokan2
-rw-r--r--library/tzdata/America/Bahia3
-rw-r--r--library/tzdata/America/Barbados6
-rw-r--r--[-rwxr-xr-x]library/tzdata/America/Blanc-Sablon2
-rw-r--r--library/tzdata/America/Bogota6
-rw-r--r--library/tzdata/America/Cayman4
-rw-r--r--library/tzdata/America/Costa_Rica6
-rw-r--r--library/tzdata/America/Creston8
-rw-r--r--library/tzdata/America/Curacao4
-rw-r--r--library/tzdata/America/Dawson_Creek2
-rw-r--r--library/tzdata/America/Dominica7
-rw-r--r--library/tzdata/America/Edmonton2
-rw-r--r--library/tzdata/America/Glace_Bay2
-rw-r--r--library/tzdata/America/Goose_Bay357
-rw-r--r--library/tzdata/America/Grand_Turk4
-rw-r--r--library/tzdata/America/Grenada7
-rw-r--r--library/tzdata/America/Guadeloupe7
-rw-r--r--library/tzdata/America/Halifax2
-rw-r--r--library/tzdata/America/Havana180
-rw-r--r--[-rwxr-xr-x]library/tzdata/America/Indiana/Petersburg0
-rw-r--r--[-rwxr-xr-x]library/tzdata/America/Indiana/Tell_City0
-rw-r--r--[-rwxr-xr-x]library/tzdata/America/Indiana/Vincennes0
-rw-r--r--[-rwxr-xr-x]library/tzdata/America/Indiana/Winamac0
-rw-r--r--library/tzdata/America/Jamaica6
-rw-r--r--library/tzdata/America/Marigot6
-rw-r--r--library/tzdata/America/Metlakatla232
-rw-r--r--[-rwxr-xr-x]library/tzdata/America/Moncton2
-rw-r--r--library/tzdata/America/Montreal2
-rw-r--r--library/tzdata/America/Montserrat7
-rw-r--r--library/tzdata/America/Nassau4
-rw-r--r--library/tzdata/America/Nipigon2
-rw-r--r--[-rwxr-xr-x]library/tzdata/America/North_Dakota/New_Salem0
-rw-r--r--library/tzdata/America/Port-au-Prince176
-rw-r--r--library/tzdata/America/Rainy_River2
-rw-r--r--library/tzdata/America/Regina2
-rw-r--r--[-rwxr-xr-x]library/tzdata/America/Resolute373
-rw-r--r--library/tzdata/America/Santiago352
-rw-r--r--library/tzdata/America/Sitka4
-rw-r--r--library/tzdata/America/St_Barthelemy6
-rw-r--r--library/tzdata/America/St_Johns357
-rw-r--r--library/tzdata/America/St_Kitts7
-rw-r--r--library/tzdata/America/St_Lucia8
-rw-r--r--library/tzdata/America/St_Thomas7
-rw-r--r--library/tzdata/America/St_Vincent8
-rw-r--r--library/tzdata/America/Swift_Current2
-rw-r--r--library/tzdata/America/Toronto2
-rw-r--r--library/tzdata/America/Tortola7
-rw-r--r--library/tzdata/America/Vancouver2
-rw-r--r--library/tzdata/America/Virgin6
-rw-r--r--library/tzdata/America/Winnipeg2
-rw-r--r--library/tzdata/Antarctica/Casey2
-rw-r--r--library/tzdata/Antarctica/Davis2
-rw-r--r--library/tzdata/Antarctica/Macquarie9
-rw-r--r--library/tzdata/Antarctica/McMurdo258
-rw-r--r--library/tzdata/Antarctica/Palmer360
-rw-r--r--library/tzdata/Antarctica/South_Pole6
-rw-r--r--library/tzdata/Asia/Aden4
-rw-r--r--library/tzdata/Asia/Amman176
-rw-r--r--library/tzdata/Asia/Damascus176
-rw-r--r--library/tzdata/Asia/Dili2
-rw-r--r--library/tzdata/Asia/Gaza368
-rw-r--r--library/tzdata/Asia/Hebron277
-rw-r--r--library/tzdata/Asia/Hong_Kong4
-rw-r--r--library/tzdata/Asia/Jakarta12
-rw-r--r--library/tzdata/Asia/Jayapura4
-rw-r--r--library/tzdata/Asia/Jerusalem198
-rw-r--r--library/tzdata/Asia/Khandyga72
-rw-r--r--library/tzdata/Asia/Makassar4
-rw-r--r--library/tzdata/Asia/Muscat4
-rw-r--r--library/tzdata/Asia/Pontianak12
-rw-r--r--library/tzdata/Asia/Rangoon4
-rw-r--r--library/tzdata/Asia/Shanghai4
-rw-r--r--library/tzdata/Asia/Ust-Nera70
-rw-r--r--library/tzdata/Asia/Yerevan177
-rw-r--r--library/tzdata/Atlantic/Bermuda4
-rw-r--r--[-rwxr-xr-x]library/tzdata/Atlantic/Faroe0
-rw-r--r--library/tzdata/Atlantic/Stanley179
-rw-r--r--[-rwxr-xr-x]library/tzdata/Australia/Eucla0
-rw-r--r--library/tzdata/Europe/Busingen5
-rw-r--r--[-rwxr-xr-x]library/tzdata/Europe/Guernsey0
-rw-r--r--[-rwxr-xr-x]library/tzdata/Europe/Isle_of_Man0
-rw-r--r--[-rwxr-xr-x]library/tzdata/Europe/Jersey0
-rw-r--r--library/tzdata/Europe/Kaliningrad2
-rw-r--r--library/tzdata/Europe/Minsk179
-rw-r--r--[-rwxr-xr-x]library/tzdata/Europe/Podgorica0
-rw-r--r--library/tzdata/Europe/Vaduz246
-rw-r--r--library/tzdata/Europe/Vienna4
-rw-r--r--[-rwxr-xr-x]library/tzdata/Europe/Volgograd0
-rw-r--r--library/tzdata/Europe/Zurich4
-rw-r--r--library/tzdata/Pacific/Apia178
-rw-r--r--library/tzdata/Pacific/Easter352
-rw-r--r--library/tzdata/Pacific/Fakaofo3
-rw-r--r--library/tzdata/Pacific/Fiji181
-rw-r--r--library/tzdata/Pacific/Honolulu1
-rw-r--r--library/tzdata/Pacific/Johnston6
-rw-r--r--library/word.tcl10
-rw-r--r--macosx/README4
-rw-r--r--macosx/Tcl.xcode/project.pbxproj2
-rw-r--r--macosx/Tcl.xcodeproj/project.pbxproj2
-rw-r--r--macosx/tclMacOSXFCmd.c61
-rw-r--r--pkgs/README58
-rw-r--r--pkgs/package.list.txt35
-rw-r--r--tests/all.tcl2
-rw-r--r--tests/assemble.test3
-rw-r--r--tests/assocd.test33
-rw-r--r--tests/async.test9
-rw-r--r--tests/autoMkindex.test32
-rw-r--r--tests/basic.test35
-rw-r--r--tests/binary.test197
-rw-r--r--tests/chan.test2
-rw-r--r--tests/chanio.test45
-rw-r--r--tests/clock.test196
-rw-r--r--tests/cmdAH.test25
-rw-r--r--tests/cmdIL.test22
-rw-r--r--tests/cmdInfo.test11
-rw-r--r--tests/compExpr-old.test3
-rw-r--r--tests/compExpr.test3
-rw-r--r--tests/compile.test103
-rw-r--r--tests/coroutine.test172
-rw-r--r--tests/dcall.test11
-rw-r--r--tests/dict.test617
-rw-r--r--tests/dstring.test3
-rw-r--r--tests/encoding.test18
-rw-r--r--tests/env.test30
-rw-r--r--tests/error.test162
-rw-r--r--tests/event.test12
-rw-r--r--tests/exec.test2
-rw-r--r--tests/execute.test3
-rw-r--r--tests/expr-old.test17
-rw-r--r--tests/expr.test3
-rw-r--r--tests/fCmd.test142
-rw-r--r--tests/fileName.test12
-rw-r--r--tests/fileSystem.test58
-rw-r--r--tests/for.test376
-rw-r--r--tests/foreach.test20
-rw-r--r--tests/format.test7
-rw-r--r--tests/get.test3
-rw-r--r--tests/http.test109
-rw-r--r--tests/httpd10
-rw-r--r--tests/indexObj.test41
-rw-r--r--tests/info.test486
-rw-r--r--tests/init.test2
-rw-r--r--tests/interp.test31
-rw-r--r--tests/io.test142
-rw-r--r--tests/ioCmd.test550
-rw-r--r--tests/ioTrans.test241
-rw-r--r--tests/iogt.test39
-rw-r--r--tests/lindex.test3
-rw-r--r--tests/link.test3
-rw-r--r--tests/listObj.test7
-rw-r--r--tests/lmap.test471
-rw-r--r--tests/load.test33
-rw-r--r--tests/lrange.test14
-rw-r--r--tests/lset.test3
-rw-r--r--[-rwxr-xr-x]tests/lsetComp.test0
-rw-r--r--tests/main.test26
-rw-r--r--tests/misc.test10
-rw-r--r--tests/msgcat.test60
-rw-r--r--tests/namespace.test24
-rw-r--r--[-rwxr-xr-x]tests/notify.test3
-rw-r--r--tests/nre.test29
-rw-r--r--tests/obj.test7
-rw-r--r--tests/oo.test861
-rw-r--r--tests/ooNext2.test10
-rw-r--r--tests/parse.test60
-rw-r--r--tests/parseExpr.test77
-rw-r--r--tests/parseOld.test25
-rw-r--r--tests/pkgMkIndex.test16
-rw-r--r--tests/platform.test30
-rw-r--r--tests/proc.test9
-rw-r--r--tests/reg.test159
-rw-r--r--tests/regexp.test61
-rw-r--r--tests/registry.test18
-rw-r--r--tests/rename.test10
-rw-r--r--tests/resolver.test203
-rw-r--r--tests/result.test9
-rw-r--r--tests/safe.test312
-rw-r--r--tests/scan.test772
-rw-r--r--tests/set-old.test5
-rw-r--r--tests/set.test8
-rw-r--r--tests/socket.test80
-rw-r--r--tests/source.test23
-rw-r--r--tests/stack.test6
-rw-r--r--tests/string.test127
-rw-r--r--tests/stringComp.test51
-rw-r--r--tests/stringObj.test19
-rw-r--r--tests/subst.test4
-rw-r--r--tests/switch.test22
-rw-r--r--tests/tailcall.test3
-rw-r--r--[-rwxr-xr-x]tests/tcltest.test17
-rw-r--r--tests/thread.test1602
-rw-r--r--tests/tm.test2
-rw-r--r--tests/trace.test432
-rw-r--r--tests/unixFCmd.test18
-rw-r--r--tests/unixFile.test3
-rw-r--r--tests/unixForkEvent.test45
-rw-r--r--tests/unixInit.test16
-rw-r--r--tests/unixNotfy.test20
-rw-r--r--tests/unknown.test10
-rw-r--r--tests/unload.test3
-rw-r--r--tests/upvar.test46
-rw-r--r--tests/utf.test71
-rw-r--r--tests/util.test143
-rw-r--r--tests/var.test88
-rw-r--r--tests/winDde.test296
-rw-r--r--tests/winFCmd.test103
-rw-r--r--tests/winFile.test21
-rw-r--r--tests/winNotify.test3
-rw-r--r--tests/winPipe.test28
-rw-r--r--tests/winTime.test3
-rw-r--r--tests/zlib.test318
-rw-r--r--tools/README3
-rw-r--r--[-rwxr-xr-x]tools/encoding/ebcdic.txt0
-rw-r--r--[-rwxr-xr-x]tools/encoding/tis-620.txt0
-rw-r--r--tools/genStubs.tcl47
-rw-r--r--tools/man2help2.tcl2
-rw-r--r--tools/str2c4
-rw-r--r--tools/tcl.wse.in2376
-rw-r--r--tools/tclSplash.bmpbin162030 -> 0 bytes
-rw-r--r--tools/tclmin.wse247
-rw-r--r--tools/tcltk-man2html-utils.tcl441
-rwxr-xr-xtools/tcltk-man2html.tcl479
-rw-r--r--tools/uniClass.tcl41
-rw-r--r--tools/uniParse.tcl123
-rw-r--r--unix/Makefile.in230
-rw-r--r--unix/README5
-rwxr-xr-xunix/configure1207
-rw-r--r--unix/configure.in80
-rw-r--r--unix/dltest/Makefile.in15
-rw-r--r--unix/dltest/pkgb.c50
-rw-r--r--unix/dltest/pkgooa.c141
-rwxr-xr-xunix/install-sh4
-rw-r--r--unix/tcl.m4349
-rw-r--r--unix/tcl.pc.in8
-rw-r--r--unix/tcl.spec2
-rw-r--r--unix/tclAppInit.c22
-rw-r--r--unix/tclConfig.h.in57
-rw-r--r--unix/tclConfig.sh.in4
-rw-r--r--unix/tclLoadDl.c42
-rw-r--r--unix/tclLoadDyld.c286
-rw-r--r--unix/tclLoadNext.c28
-rw-r--r--unix/tclLoadOSF.c27
-rw-r--r--unix/tclLoadShl.c40
-rw-r--r--unix/tclUnixChan.c491
-rw-r--r--unix/tclUnixCompat.c324
-rw-r--r--unix/tclUnixFCmd.c349
-rw-r--r--unix/tclUnixFile.c154
-rw-r--r--unix/tclUnixInit.c94
-rw-r--r--unix/tclUnixNotfy.c317
-rw-r--r--unix/tclUnixPipe.c129
-rw-r--r--unix/tclUnixPort.h78
-rw-r--r--unix/tclUnixSock.c334
-rw-r--r--unix/tclUnixTest.c77
-rw-r--r--unix/tclUnixThrd.c4
-rw-r--r--unix/tclUnixTime.c118
-rw-r--r--unix/tclXtNotify.c37
-rw-r--r--unix/tclXtTest.c9
-rw-r--r--unix/tclooConfig.sh4
-rw-r--r--win/Makefile.in165
-rw-r--r--win/README51
-rw-r--r--[-rwxr-xr-x]win/buildall.vc.bat41
-rw-r--r--win/cat.c6
-rw-r--r--win/coffbase.txt2
-rwxr-xr-xwin/configure1692
-rw-r--r--win/configure.in390
-rw-r--r--win/makefile.bc42
-rw-r--r--win/makefile.vc111
-rw-r--r--win/nmakehlp.c88
-rw-r--r--win/rules.vc47
-rw-r--r--win/tcl.m4514
-rw-r--r--win/tclAppInit.c62
-rw-r--r--win/tclConfig.sh.in2
-rw-r--r--win/tclWin32Dll.c147
-rw-r--r--win/tclWinChan.c152
-rw-r--r--win/tclWinConsole.c449
-rw-r--r--win/tclWinDde.c538
-rw-r--r--win/tclWinError.c77
-rw-r--r--win/tclWinFCmd.c132
-rw-r--r--win/tclWinFile.c756
-rw-r--r--win/tclWinInit.c119
-rw-r--r--win/tclWinInt.h105
-rw-r--r--win/tclWinLoad.c264
-rw-r--r--win/tclWinPipe.c131
-rw-r--r--win/tclWinPort.h135
-rw-r--r--win/tclWinReg.c181
-rw-r--r--win/tclWinSerial.c174
-rw-r--r--win/tclWinSock.c859
-rw-r--r--win/tclWinTest.c86
-rw-r--r--win/tclWinThrd.c84
-rw-r--r--win/tclWinTime.c120
-rw-r--r--win/tclooConfig.sh4
-rw-r--r--win/tclsh.exe.manifest.in33
-rw-r--r--win/tclsh.rc13
986 files changed, 59012 insertions, 42563 deletions
diff --git a/.fossil-settings/binary-glob b/.fossil-settings/binary-glob
new file mode 100644
index 0000000..ca85874
--- /dev/null
+++ b/.fossil-settings/binary-glob
@@ -0,0 +1,3 @@
+*.bmp
+*.gif
+*.png
diff --git a/.fossil-settings/crnl-glob b/.fossil-settings/crnl-glob
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.fossil-settings/crnl-glob
diff --git a/.fossil-settings/ignore-glob b/.fossil-settings/ignore-glob
new file mode 100644
index 0000000..9ed86b1
--- /dev/null
+++ b/.fossil-settings/ignore-glob
@@ -0,0 +1,24 @@
+*.a
+*.dll
+*.dylib
+*.exe
+*.exp
+*.lib
+*.o
+*.obj
+*.res
+*.sl
+*.so
+*/Makefile
+*/config.cache
+*/config.log
+*/config.status
+*/tclConfig.sh
+*/tclsh*
+*/tcltest*
+*/versions.vc
+unix/dltest.marker
+unix/tcl.pc
+unix/pkgs/*
+win/pkgs/*
+win/tcl.hpj
diff --git a/.project b/.project
new file mode 100644
index 0000000..358cc74
--- /dev/null
+++ b/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>tcl8.6</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ </buildSpec>
+ <natures>
+ </natures>
+</projectDescription>
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/.settings/org.eclipse.core.runtime.prefs b/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..5a0ad22
--- /dev/null
+++ b/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/ChangeLog b/ChangeLog
index b8832e6..bb441a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,2371 @@
+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"
+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
+a better first place to look now.
+============================================================================
+
+2013-09-19 Don Porter <dgp@users.sourceforge.net>
+
+ *** 8.6.1 TAGGED FOR RELEASE ***
+
+ * generic/tcl.h: Bump version number to 8.6.1.
+ * library/init.tcl:
+ * unix/configure.in:
+ * win/configure.in:
+ * unix/tcl.spec:
+ * README:
+
+ * unix/configure: autoconf-2.59
+ * win/configure:
+
+2013-09-19 Donal Fellows <dkf@users.sf.net>
+
+ * doc/next.n (METHOD SEARCH ORDER): Bug [3606943]: Corrected
+ description of method search order.
+
+2013-09-18 Donal Fellows <dkf@users.sf.net>
+
+ Bump TclOO version to 1.0.1 for release.
+
+2013-09-17 Donal Fellows <dkf@users.sf.net>
+
+ * generic/tclBinary.c (BinaryEncodeUu, BinaryDecodeUu): [Bug 2152292]:
+ Corrected implementation of the core of uuencode handling so that the
+ line length processing is correctly applied.
+ ***POTENTIAL INCOMPATIBILITY***
+ Existing code that was using the old versions and working around the
+ limitations will now need to do far less. The -maxlen option now has
+ strict limits on the range of supported lengths; this is a limitation
+ of the format itself.
+
+2013-09-09 Donal Fellows <dkf@users.sf.net>
+
+ * generic/tclOOMethod.c (CloneProcedureMethod): [Bug 3609693]: Strip
+ the internal representation of method bodies during cloning in order
+ to ensure that any bound references to instance variables are removed.
+
+2013-09-01 Donal Fellows <dkf@users.sf.net>
+
+ * generic/tclBinary.c (BinaryDecodeHex): [Bug b98fa55285]: Ensure that
+ whitespace at the end of a string don't cause the decoder to drop the
+ last decoded byte.
+
+2013-08-03 Donal Fellows <dkf@users.sf.net>
+
+ * library/auto.tcl: [Patch 3611643]: Allow TclOO classes to be found
+ by the autoloading mechanism.
+
+2013-08-02 Donal Fellows <dkf@users.sf.net>
+
+ * generic/tclOODefineCmds.c (ClassSuperSet): Bug [9d61624b3d]: Stop
+ crashes when emptying the superclass slot, even when doing elaborate
+ things with metaclasses.
+
+2013-08-01 Harald Oehlmann <oehhar@users.sf.net>
+
+ * tclUnixNotify.c (Tcl_InitNotifier): Bug [a0bc856dcd]: Start notifier
+ thread again if we were forked, to solve Rivet bug 55153.
+
+2013-07-05 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/tzdata/Africa/Casablanca:
+ * library/tzdata/America/Asuncion:
+ * library/tzdata/Antarctica/Macquarie:
+ * library/tzdata/Asia/Gaza:
+ * library/tzdata/Asia/Hebron:
+ * library/tzdata/Asia/Jerusalem:
+ http://www.iana.org/time-zones/repository/releases/tzdata2013d.tar.gz
+
+2013-07-03 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * unix/tclXtNotify.c: Bug [817249]: bring tclXtNotify.c up to date with
+ Tcl_SetNotifier() change.
+
+2013-07-02 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * unix/tcl.m4: Bug [32afa6e256]: dirent64 check is incorrect in tcl.m4
+ * unix/configure: (thanks to Brian Griffin)
+
+2013-06-27 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclConfig.c: Bug [9b2e636361]: Tcl_CreateInterp() needs
+ * generic/tclMain.c: initialized encodings.
+
+2013-06-18 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclEvent.c: Bug [3611974]: InitSubsystems multiple thread
+ issue.
+
+2013-06-17 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/regc_locale.c: Bug [a876646efe]: re_expr character class
+ [:cntrl:] should contain \u0000 - \u001f
+
+2013-06-09 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmdsSZ.c (TclCompileTryCmd): [Bug 779d38b996]:
+ Rewrote the [try] compiler to generate better code in some cases and
+ to behave correctly in others; when an error happens during the
+ processing of an exception-trap clause or a finally clause, the
+ *original* return options are now captured in a -during option, even
+ when fully compiled.
+
+2013-06-05 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclExecute.c (INST_EXPAND_DROP): [Bugs 2835313, 3614226]:
+ New opcode to allow resetting the stack to get rid of an expansion,
+ restoring the stack to a known state in the process.
+ * generic/tclCompile.c, generic/tclCompCmds.c: Adjusted the compilers
+ for [break] and [continue] to get stack cleanup right in the majority
+ of cases.
+ * tests/for.test (for-7.*): Set of tests for these evil cases.
+
+2013-06-04 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * unix/tcl.m4: Eliminate NO_VIZ macro as current zlib uses HAVE_HIDDEN
+ instead. One more last-moment fix for FreeBSD by Pietro Cerutti
+
+2013-06-03 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c: fix for perf bug detected by Kieran
+ (https://groups.google.com/forum/?fromgroups#!topic/comp.lang.tcl/vfpI3bc-DkQ),
+ diagnosed by dgp to be a close relative of [Bug 781585], which was
+ fixed by commit [f46fb50cb3]. This bug was introduced by myself in
+ commit [cbfe055d8c].
+
+2013-06-03 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmds.c (TclCompileBreakCmd, TclCompileContinueCmd):
+ Added code to allow [break] and [continue] to be issued as a jump (in
+ the most common cases) rather than using the more expensive exception
+ processing path in the bytecode engine. [Bug 3614226]: Partial fix for
+ the issues relating to cleaning up the stack when dealing with [break]
+ and [continue].
+
+2013-05-27 Harald Oehlmann <oehhar@users.sf.net>
+
+ * library/msgcat/msgcat.tcl: [Bug 3036566]: Also get locale from
+ registry key HCU\Control Panel\Desktop : PreferredUILanguages to honor
+ installed language packs on Vista+.
+ Bumped msgcat version to 1.5.2
+
+2013-05-22 Andreas Kupries <andreask@activestate.com>
+
+ * tclCompile.c: Removed duplicate const qualifier causing the HP
+ native cc to error out.
+
+2013-05-22 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclUtf.c (TclUtfCasecmp): [Bug 3613609]: Replace problematic
+ uses of strcasecmp with a proper UTF-8-aware version. Affects both
+ [lsearch -nocase] and [lsort -nocase].
+
+2013-05-22 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/file.n: [Bug 3613671]: Added note to portability section on the
+ fact that [file owned] does not produce useful results on Windows.
+
+2013-05-20 Donal K. Fellows <dkf@users.sf.net>
+
+ * unix/tclUnixFCmd.c (DefaultTempDir): [Bug 3613567]: Corrected logic
+ for checking return code of access() system call, which was inverted.
+
+2013-05-19 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * unix/tcl.m4: Fix for FreeBSD, and remove support for older
+ * unix/configure: FreeBSD versions. Patch by Pietro Cerutti.
+
+2013-05-18 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmdsGR.c: Split tclCompCmds.c again to keep size of
+ code down.
+
+2013-05-16 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclBasic.c: Add panic in order to detect incompatible
+ mingw32 sys/stat.h and sys/time.h headers.
+
+2013-05-13 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * compat/zlib/*: Upgrade to zlib 1.2.8
+
+2013-05-10 Donal K. Fellows <dkf@users.sf.net>
+
+ Optimizations and general bytecode generation improvements.
+ * generic/tclCompCmds.c (TclCompileAppendCmd, TclCompileLappendCmd):
+ (TclCompileReturnCmd): Make these generate bytecode in more cases.
+ (TclCompileListCmd): Make this able to push a literal when it can.
+ * generic/tclCompile.c (TclSetByteCodeFromAny, PeepholeOptimize):
+ Added checks to see if we can apply some simple cross-command-boundary
+ optimizations, and defined a small number of such optimizations.
+ (TclCompileScript): Added the special ability to compile the list
+ command with expansion ([list {*}blah]) into bytecode that does not
+ call an external command.
+
+2013-05-06 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclStubInit.c: Add support for Cygwin64, which has a 64-bit
+ * generic/tclDecls.h: "long" type. Binary compatibility with win64
+ requires that all stub entries use 32-bit long's, therefore the need
+ for various wrapper functions/macros. For Tcl 9 a better solution is
+ needed, but that cannot be done without introducing binary
+ incompatibility.
+
+2013-04-30 Andreas Kupries <andreask@activestate.com>
+
+ * library/platform/platform.tcl (::platform::LibcVersion):
+ * library/platform/pkgIndex.tcl: Followup to the 2013-01-30 change.
+ The RE become too restrictive again. SuSe added a timestamp after the
+ version. Loosened up a bit. Bumped package to version 1.0.12.
+
+2013-04-29 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmds.c (TclCompileArraySetCmd): Generate better code
+ when the list of things to set is a literal.
+
+2013-04-25 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclDecls.h: Implement Tcl_NewBooleanObj, Tcl_DbNewBooleanObj
+ and Tcl_SetBooleanObj as macros using Tcl_NewIntObj, Tcl_DbNewLongObj
+ and Tcl_SetIntObj. Starting with Tcl 8.5, this is exactly the same, it
+ only eliminates code duplication.
+ * generic/tclInt.h: Eliminate use of NO_WIDE_TYPE everywhere: It's
+ exactly the same as TCL_WIDE_INT_IS_LONG
+
+2013-04-19 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclDecls.h: Implement many Tcl_*Var* functions and
+ Tcl_GetIndexFromObj as (faster/stack-saving) macros around resp their
+ Tcl_*Var*2 equivalent and Tcl_GetIndexFromObjStruct.
+
+2013-04-12 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclDecls.h: Implement Tcl_Pkg* functions as
+ (faster/stack-saving) macros around Tcl_Pkg*Ex functions.
+
+2013-04-08 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/regc_color.c: [Bug 3610026]: Stop crash when the number of
+ * generic/regerrs.h: "colors" in a regular expression overflows a
+ * generic/regex.h: short int. Thanks to Heikki Linnakangas for
+ * generic/regguts.h: the report and the patch.
+ * tests/regexp.test:
+
+2013-04-04 Reinhard Max <max@suse.de>
+
+ * library/http/http.tcl (http::geturl): Allow URLs that don't have a
+ path, but a query query, e.g. http://example.com?foo=bar
+ * Bump the http package to 2.8.7.
+
+2013-03-22 Venkat Iyer <venkat@comit.com>
+ * library/tzdata/Africa/Cairo: Update to tzdata2013b.
+ * library/tzdata/Africa/Casablanca:
+ * library/tzdata/Africa/Gaborone:
+ * library/tzdata/Africa/Tripoli:
+ * library/tzdata/America/Asuncion:
+ * library/tzdata/America/Barbados:
+ * library/tzdata/America/Bogota:
+ * library/tzdata/America/Costa_Rica:
+ * library/tzdata/America/Curacao:
+ * library/tzdata/America/Nassau:
+ * library/tzdata/America/Port-au-Prince:
+ * library/tzdata/America/Santiago:
+ * library/tzdata/Antarctica/Palmer:
+ * library/tzdata/Asia/Aden:
+ * library/tzdata/Asia/Hong_Kong:
+ * library/tzdata/Asia/Muscat:
+ * library/tzdata/Asia/Rangoon:
+ * library/tzdata/Asia/Shanghai:
+ * library/tzdata/Atlantic/Bermuda:
+ * library/tzdata/Europe/Vienna:
+ * library/tzdata/Pacific/Easter:
+ * library/tzdata/Pacific/Fiji:
+ * library/tzdata/Asia/Khandyga: (new)
+ * library/tzdata/Asia/Ust-Nera: (new)
+ * library/tzdata/Europe/Busingen: (new)
+
+2013-03-21 Don Porter <dgp@users.sourceforge.net>
+
+ * library/auto.tcl: [Bug 2102614]: Add ensemble indexing support to
+ * tests/autoMkindex.test: [auto_mkindex]. Thanks Brian Griffin.
+
+2013-03-19 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclFCmd.c: [Bug 3597000]: Consistent [file copy] result.
+ * tests/fileSystem.test:
+
+2013-03-19 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinFile.c: [Bug 3608360]: Incompatible behaviour of "file
+ exists".
+
+2013-03-18 Donal K. Fellows <dkf@users.sf.net>
+
+ * tests/cmdAH.test (cmdAH-19.12): [Bug 3608360]: Added test to ensure
+ that we never ever allow [file exists] to do globbing.
+
+2013-03-12 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * unix/tcl.m4: Patch by Andrew Shadura, providing better support for
+ three architectures they have in Debian.
+
+2013-03-11 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompile.c: [Bugs 3607246,3607372]: Unbalanced refcounts
+ * generic/tclLiteral.c: of literals in the global literal table.
+
+2013-03-06 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/regc_nfa.c: [Bugs 3604074,3606683]: Rewrite of the
+ * generic/regcomp.c: fixempties() routine (and supporting routines)
+ to completely eliminate the infinite loop hazard. Thanks to Tom Lane
+ for the much improved solution.
+
+2013-02-28 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclLiteral.c: Revise TclReleaseLiteral() to tolerate a NULL
+ interp argument.
+
+ * generic/tclCompile.c: Update callers and revise mistaken comments.
+ * generic/tclProc.c:
+
+2013-02-27 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/regcomp.c: [Bug 3606139]: missing error check allows
+ * tests/regexp.test: regexp to crash Tcl. Thanks to Tom Lane for
+ providing the test-case and the patch.
+
+2013-02-26 Donal K. Fellows <dkf@users.sf.net>
+
+ * tests/chanio.test (chan-io-28.7): [Bug 3605120]: Stop test from
+ hanging when run standalone.
+
+2013-02-26 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclObj.c: Don't panic if Tcl_ConvertToType is called for a
+ type that doesn't have a setFromAnyProc, create a proper error message.
+
+2013-02-25 Donal K. Fellows <dkf@users.sf.net>
+
+ * tests/binary.test (binary-41.*): [Bug 3605721]: Test independence
+ fixes. Thanks to Rolf Ade for pointing out the problem.
+
+2013-02-25 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/assocd.test: [Bugs 3605719,3605720]: Test independence.
+ * tests/basic.test: Thanks Rolf Ade for patches.
+
+2013-02-23 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * compat/fake-rfc2553.c: [Bug 3599194]: compat/fake-rfc2553.c is
+ broken.
+
+2013-02-22 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclAssembly.c: Shift more burden of smart cleanup
+ * generic/tclCompile.c: onto the TclFreeCompileEnv() routine.
+ Stop crashes when the hookProc raises an error.
+
+2013-02-20 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclNamesp.c: [Bug 3605447]: Make sure the -clear option
+ * tests/namespace.test: to [namespace export] always clears, whether
+ or not new export patterns are specified.
+
+2013-02-20 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinDde.c: [Bug 3605401]: Compiler error with latest mingw-w64
+ headers.
+
+2013-02-19 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclTrace.c: [Bug 2438181]: Incorrect error reporting in
+ * tests/trace.test: traces. Test-case and fix provided by Poor
+ Yorick.
+
+2013-02-15 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/regc_nfa.c: [Bug 3604074]: Fix regexp optimization to
+ * tests/regexp.test: stop hanging on the expression
+ ((((((((a)*)*)*)*)*)*)*)* . Thanks to Bjørn Grathwohl for discovery.
+
+2013-02-14 Harald Oehlmann <oehhar@users.sf.net>
+
+ * library/msgcat/msgcat.tcl: [Bug 3604576]: Catch missing registry
+ entry "HCU\Control Panel\International".
+ Bumped msgcat version to 1.5.1
+
+2013-02-11 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclZlib.c (ZlibTransformOutput): [Bug 3603553]: Ensure that
+ data gets written to the underlying stream by compressing transforms
+ when the amount of data to be written is one buffer's-worth; problem
+ was particularly likely to occur when compressing large quantities of
+ not-very-compressible data. Many thanks to Piera Poggio (vampiera) for
+ reporting.
+
+2013-02-09 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclOOBasic.c (TclOO_Object_VarName): [Bug 3603695]: Change
+ the way that the 'varname' method is implemented so that there are no
+ longer problems with interactions due to the resolver. Thanks to
+ Taylor Venable <tcvena@gmail.com> for identifying the problem.
+
+2013-02-08 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/regc_nfa.c (duptraverse): [Bug 3603557]: Increase the
+ maximum depth of recursion used when duplicating an automaton in
+ response to encountering a "wild" RE that hit the previous limit.
+ Allow the limit (DUPTRAVERSE_MAX_DEPTH) to be set by defining its
+ value in the Makefile. Problem reported by Jonathan Mills.
+
+2013-02-05 Don Porter <dgp@users.sourceforge.net>
+
+ * win/tclWinFile.c: [Bug 3603434]: Make sure TclpObjNormalizePath()
+ properly declares "a:/" to be normalized, even when no "A:" drive is
+ present on the system.
+
+2013-02-05 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclLoadNone.c (TclpLoadMemory): [Bug 3433012]: Added dummy
+ version of this function to use in the event that a platform thinks it
+ can load from memory but cannot actually do so due to it being
+ disabled at configuration time.
+
+2013-02-04 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmds.c (TclCompileArraySetCmd): [Bug 3603163]: Stop
+ crash in weird case where [eval] is used to make [array set] get
+ confused about whether there is a local variable table or not. Thanks
+ to Poor Yorick for identifying a reproducible crashing case.
+
+2013-01-30 Andreas Kupries <andreask@activestate.com>
+
+ * library/platform/platform.tcl (::platform::LibcVersion): See
+ * library/platform/pkgIndex.tcl: [Bug 3599098]: Fixed the RE
+ * unix/Makefile.in: extracting the version to avoid issues with
+ * win/Makefile.in: recent changes to the glibc banner. Now targeting a
+ less variable part of the string. Bumped package to version 1.0.11.
+
+2013-01-28 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmds.c (TclCompileArraySetCmd)
+ (TclCompileArrayUnsetCmd, TclCompileDictAppendCmd)
+ (TclCompileDictCreateCmd, CompileDictEachCmd, TclCompileDictIncrCmd)
+ (TclCompileDictLappendCmd, TclCompileDictMergeCmd)
+ (TclCompileDictUnsetCmd, TclCompileDictUpdateCmd)
+ (TclCompileDictWithCmd, TclCompileInfoCommandsCmd):
+ * generic/tclCompCmdsSZ.c (TclCompileStringMatchCmd)
+ (TclCompileStringMapCmd): Improve the code generation in cases where
+ full compilation is impossible but a full ensemble invoke is provably
+ not necessary.
+
+2013-01-26 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * unix/tclUnixCompat.c: [Bug 3601804]: platformCPUID segmentation
+ fault on Darwin.
+
+2013-01-23 Donal K. Fellows <dkf@users.sf.net>
+
+ * library/http/http.tcl (http::geturl): [Bug 2911139]: Do not do vwait
+ for connect to avoid reentrancy problems (except when operating
+ without a -command option). Internally, this means that all sockets
+ created by the http package will always be operated in asynchronous
+ mode.
+
+2013-01-21 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclInt.decls: Put back Tcl[GS]etStartupScript(Path|FileName)
+ in private stub table, so extensions using this (like Tk 8.4) will
+ continue to work in all Tcl 8.x versions. Extensions using this
+ still cannot be compiled against Tcl 8.6 headers.
+
+2013-01-18 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclPort.h: [Bug 3598300]: unix: tcl.h does not include
+ sys/stat.h
+
+2013-01-17 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmds.c (PushVarName): [Bug 3600328]: Added mechanism
+ for suppressing compilation of variables when we couldn't cope with
+ the results. Useful for some [array] subcommands.
+ * generic/tclEnsemble.c (CompileToCompiledCommand): Must restore the
+ compilation environment when a command compiler fails.
+
+2013-01-16 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclZlib.c (TclZlibInit): [Bug 3601086]: Register the config
+ info in the iso8859-1 encoding as that is guaranteed to be present.
+
+2013-01-16 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * Makefile.in: Allow win32 build with -DTCL_NO_DEPRECATED, just as
+ * generic/tcl.h: in the UNIX build. Define Tcl_EvalObj and
+ * generic/tclDecls.h: Tcl_GlobalEvalObj as macros, even when
+ * generic/tclBasic.c: TCL_NO_DEPRECATED is defined, so Tk can benefit
+ from it too.
+
+2013-01-14 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tcl.m4: More flexible search for win32 tclConfig.sh, backported
+ from TEA (not actually used in Tcl, only for Tk)
+
+2013-01-14 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclInt.decls: Put back Tcl_[GS]etStartupScript in internal
+ stub table, so extensions using this, compiled against 8.5 headers
+ still run in Tcl 8.6.
+
+2013-01-13 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * doc/fileevent.n: [Bug 3436609]: Clarify readable fileevent "false
+ positives" in the case of multibyte encodings/transforms.
+
+2013-01-13 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclIntDecls.h: If TCL_NO_DEPRECATED is defined, make sure
+ that TIP #139 functions all are taken from the public stub table, even
+ if the inclusion is through tclInt.h.
+
+2013-01-12 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclInt.decls: Put back TclBackgroundException in internal
+ stub table, so extensions using this, compiled against 8.5 headers
+ still run in Tcl 8.6.
+
+2013-01-09 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * library/http/http.tcl: [Bug 3599395]: http assumes status line is a
+ proper Tcl list.
+
+2013-01-08 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinFile.c: [Bug 3092089]: [file normalize] can remove path
+ components. [Bug 3587096]: win vista/7: "can't find init.tcl" when
+ called via junction without folder list access.
+
+2013-01-07 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclOOStubLib.c: Restrict the stub library to only use
+ * generic/tclTomMathStubLib.c: Tcl_PkgRequireEx, Tcl_ResetResult and
+ Tcl_AppendResult, not any other function. This puts least restrictions
+ on eventual Tcl 9 stubs re-organization, and it works on the widest
+ range of Tcl versions.
+
+2013-01-06 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * library/http/http.tcl: Don't depend on Spencer-specific regexp
+ * tests/env.test: syntax (/u and /U) any more in unrelated places.
+ * tests/exec.test:
+ Bump http package to 2.8.6.
+
+2013-01-04 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclEnsemble.c (CompileBasicNArgCommand): Added very simple
+ compiler (which just compiles to a normal invoke of the implementation
+ command) for many ensemble subcommands where we can prove that there
+ is no way for scripts to detect the difference even through error
+ handling or [info level]/[info frame]. This improves the code produced
+ from some ensembles (e.g., [info], [string]) to the point where the
+ ensemble is now not normally seen at the bytecode level at all.
+
+2013-01-04 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclInt.h: Insure that PURIFY builds cannot exploit the
+ * generic/tclExecute.c: Tcl stack to hide mem defects.
+
+2013-01-03 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/fconfigure.n, doc/CrtChannel.3: Updated to reflect the fact that
+ the minimum buffer size is one byte, not ten. Identified by Schelte
+ Bron on the Tcler's Chat.
+
+ * generic/tclExecute.c (TEBCresume:INST_INVOKE_REPLACE):
+ * generic/tclEnsemble.c (TclCompileEnsemble): Added new mechanism to
+ allow for more efficient dispatch of non-bytecode-compiled subcommands
+ of bytecode-compiled ensembles. This can provide substantial speed
+ benefits in some cases.
+
+2013-01-02 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclEnsemble.c: Remove stray calls to Tcl_Alloc and friends:
+ * generic/tclExecute.c: the core should only use ckalloc to allow
+ * generic/tclIORTrans.c: MEM_DEBUG to work properly.
+ * generic/tclTomMathInterface.c:
+
+2012-12-31 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/string.n: Noted the obsolescence of the 'bytelength',
+ 'wordstart' and 'wordend' subcommands, and moved them to later in the
+ file.
+
+2012-12-27 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclListObj.c: [Bug 3598580]: Tcl_ListObjReplace may release
+ deleted elements too early.
+
+2012-12-22 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * generic/tclUtil.c: [Bug 3598150]: Stop leaking allocated space when
+ objifying a zero-length DString. Spotted by afredd.
+
+2012-12-21 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * unix/dltest/pkgb.c: Inline compat Tcl_GetDefaultEncodingDir.
+ * generic/tclStubLib.c: Eliminate unnecessary static HasStubSupport()
+ and isDigit() functions, just do the same inline.
+
+2012-12-18 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmdsSZ.c (TclSubstCompile): Improved the sequence of
+ instructions issued for [subst] when dealing with simple variable
+ references.
+
+2012-12-14 Don Porter <dgp@users.sourceforge.net>
+
+ *** 8.6.0 TAGGED FOR RELEASE ***
+
+ * changes: updates for 8.6.0
+
+2012-12-13 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclZlib.c: Repair same issue with misusing the
+ * tests/zlib.test: 'fire and forget' nature of Tcl_ObjSetVar2
+ in the new TIP 400 implementation.
+
+2012-12-13 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCmdAH.c: (CatchObjCmdCallback): do not decrRefCount
+ * tests/cmdAH.test: the newValuePtr sent to Tcl_ObjSetVar2:
+ TOSV2 is 'fire and forget', it decrs on its own.
+ Fix for [Bug 3595576], found by andrewsh.
+
+2012-12-13 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tcl.h: Fix Tcl_DecrRefCount macro such that it doesn't
+ access its objPtr parameter twice any more.
+
+2012-12-11 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tcl.h: Bump version number to 8.6.0.
+ * library/init.tcl:
+ * unix/configure.in:
+ * win/configure.in:
+ * unix/tcl.spec:
+ * README:
+
+ * unix/configure: autoconf-2.59
+ * win/configure:
+
+2012-12-10 Donal K. Fellows <dkf@users.sf.net>
+
+ * tools/tcltk-man2html.tcl (plus-pkgs): Increased robustness of
+ version number detection code to deal with packages whose names are
+ prefixes of other packages.
+ * unix/Makefile.in (dist): Added pkgs/package.list.txt to distribution
+ builds to ensure that 'make html' will work better.
+
+2012-12-09 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * tests/chan.test: Clean up unwanted eofchar side-effect of chan-4.6
+ leading to a spurious "'" at end of chan.test under certain conditions
+ (see [Bug 3389289] and [Bug 3389251]).
+
+ * doc/expr.n: [Bug 3594188]: Clarifications about commas.
+
+2012-12-08 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * generic/tclIO.c: Fix busyloop at exit under TCL_FINALIZE_ON_EXIT
+ when there are unflushed nonblocking channels. Thanks Miguel for
+ spotting.
+
+2012-12-07 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * unix/dltest/pkgb.c: Turn pkgb.so into a Tcl9 interoperability test
+ library: Whatever Tcl9 looks like, loading pkgb.so in Tcl 9 should
+ either result in an error-message, either succeed, but never crash.
+
+2012-11-28 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclZlib.c (ZlibStreamSubcmd): [Bug 3590483]: Use a mechanism
+ for complex option resolution that has fewer problems with more
+ finicky compilers.
+
+2012-11-26 Reinhard Max <max@suse.de>
+
+ * unix/tclUnixSock.c: Factor out creation of the -sockname and
+ -peername lists from TcpGetOptionProc() to TcpHostPortList(). Make it
+ robust against implementations of getnameinfo() that error out if
+ reverse mapping fails instead of falling back to the numeric
+ representation.
+
+2012-11-20 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclBinary.c (BinaryDecode64): [Bug 3033307]: Corrected
+ handling of trailing whitespace when decoding base64. Thanks to Anton
+ Kovalenko for reporting, and Andy Goth for the fix and tests.
+
+2012-11-19 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclExecute.c (INST_STR_RANGE_IMM): [Bug 3588366]: Corrected
+ implementation of bounds restriction for end-indexed compiled [string
+ range]. Thanks to Emiliano Gavilan for diagnosis and fix.
+
+2012-11-15 Jan Nijtmans <nijtmans@users.sf.net>
+
+ IMPLEMENTATION OF TIP#416
+
+ New Options for 'load': -global and -lazy
+
+ * generic/tcl.h:
+ * generic/tclLoad.c
+ * unix/tclLoadDl.c
+ * unix/tclLoadDyld.c
+ * tests/load.test
+ * doc/Load.3
+ * doc/load.n
+
+2012-11-14 Donal K. Fellows <dkf@users.sf.net>
+
+ * unix/tclUnixFCmd.c (TclUnixOpenTemporaryFile): [Bug 2933003]: Factor
+ out all the code to do temporary file creation so that it is possible
+ to make it correct in one place. Allow overriding of the back-stop
+ default temporary file location at compile time by setting the
+ TCL_TEMPORARY_FILE_DIRECTORY #def to a string containing the directory
+ name (defaults to "/tmp" as that is the most common default).
+
+2012-11-13 Joe Mistachkin <joe@mistachkin.com>
+
+ * win/tclWinInit.c: also search for the library directory (init.tcl,
+ encodings, etc) relative to the build directory associated with the
+ source checkout.
+
+2012-11-10 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c: re-enable bcc-tailcall, after fixing an
+ * generic/tclExecute.c: infinite loop in the TCL_COMPILE_DEBUG mode
+
+
+2012-11-07 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/tzdata/Africa/Casablanca:
+ * library/tzdata/America/Araguaina:
+ * library/tzdata/America/Bahia:
+ * library/tzdata/America/Havana:
+ * library/tzdata/Asia/Amman:
+ * library/tzdata/Asia/Gaza:
+ * library/tzdata/Asia/Hebron:
+ * library/tzdata/Asia/Jerusalem:
+ * library/tzdata/Pacific/Apia:
+ * library/tzdata/Pacific/Fakaofo:
+ * library/tzdata/Pacific/Fiji: Import tzdata2012i.
+
+2012-11-06 Donal K. Fellows <dkf@users.sf.net>
+
+ * library/http/http.tcl (http::Finish): [Bug 3581754]: Ensure that
+ callbacks are done at most once to prevent problems with timeouts on a
+ keep-alive connection (combined with reentrant http package use)
+ causing excessive stack growth. Not a fix for the underlying problem,
+ but ensures that pain will be mostly kept away from users.
+ Bump http package to 2.8.5.
+
+2012-11-05 Donal K. Fellows <dkf@users.sf.net>
+
+ Added bytecode compilation of many Tcl commands. Some of these are
+ total compilations and some are only partial (i.e., only compile in
+ some cases). The (sub-)commands affected are:
+ * array: exists, set, unset
+ * dict: create, exists, merge
+ * format: (simple cases only)
+ * info: commands, coroutine, level, object
+ * info object: class, isa object, namespace
+ * namespace: current, code, qualifiers, tail, which
+ * regsub: (only cases convertable to simple [string map])
+ * self: (only no-argument and [self object] cases)
+ * string: first, last, map, range
+ * tailcall:
+ * yield:
+
+ [This was work originally done on the 'dkf-compile-misc-info' branch.]
+
+2012-11-05 Jan Nijtmans <nijtmans@users.sf.net>
+
+ IMPLEMENTATION OF TIP#413
+
+ Align the [string trim] and [string is space] commands, such that
+ [string trim] by default trims all characters for which [string is
+ space] returns 1, augmented with the NUL character.
+
+ * generic/tclUtf.c: Add NEL, BOM and two more characters to [string is
+ space]
+ * generic/tclCmdMZ.c: Modify [string trim] for Unicode modifications.
+ * generic/regc_locale.c: Regexp engine must match [string is space]
+ * doc/string.n
+ * tests/string.test
+ ***POTENTIAL INCOMPATIBILITY***
+ Code that relied on characters not previously trimmed being not
+ removed will notice a difference; it is believed that this is rare,
+ but a workaround to get the behavior in Tcl 8.5 is to use " \t\n\r" as
+ an explicit trim set.
+
+2012-10-31 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/Makefile.in: Dde version number to 1.4.0, ready for Tcl 8.6.0rc1
+ * win/makefile.vc
+ * win/tclWinDde.c
+ * library/dde/pkgIndex.tcl
+ * tests/winDde.test
+
+2012-10-24 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmds.c (TclCompileDictUnsetCmd): Added compilation of
+ the [dict unset] command (for scalar var in LVT only).
+
+2012-10-23 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclInt.h: Add "flags" parameter from Tcl_LoadFile to
+ * generic/tclIOUtil.c: to various internal functions, so these
+ * generic/tclLoadNone.c: flags are available through the whole
+ * unix/tclLoad*.c: filesystem for (future) internal use.
+ * win/tclWinLoad.c:
+
+2012-10-17 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c (TclNRCoroutineObjCmd): insure that numlevels
+ are properly set, fix bug discovered by dkf and reported at
+ http://code.activestate.com/lists/tcl-core/12213/
+
+2012-10-16 Donal K. Fellows <dkf@users.sf.net>
+
+ IMPLEMENTATION OF TIP#405
+
+ New commands for applying a transformation to the elements of a list
+ to produce another list (the [lmap] command) and to the mappings of a
+ dictionary to produce another dictionary (the [dict map] command). In
+ both cases, a [continue] will cause the skipping of an element/pair,
+ and a [break] will terminate the construction early and successfully.
+
+ * generic/tclCmdAH.c (Tcl_LmapObjCmd, TclNRLmapCmd): Implementation of
+ the new [lmap] command, based on (and sharing much of) [foreach].
+ * generic/tclDictObj.c (DictMapNRCmd): Implementation of the new [dict
+ map] subcommand, based on (and sharing much of) [dict for].
+ * generic/tclCompCmds.c (TclCompileLmapCmd, TclCompileDictMapCmd):
+ Compilation engines for [lmap] and [dict map].
+
+ IMPLEMENTATION OF TIP#400
+
+ * generic/tclZlib.c: Allow the specification of a compression
+ dictionary (a binary blob used to seed the compression engine) in both
+ streams and channel transformations. Also some reorganization to allow
+ for getting gzip header dictionaries and controlling buffering levels
+ in channel transformations (allowing a trade-off between formal
+ correctness and speed).
+ (Tcl_ZlibStreamSetCompressionDictionary): New C API to allow setting
+ the compression dictionary without using a Tcl script.
+
+2012-10-14 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclDictObj.c: [Bug 3576509]: ::tcl::Bgerror crashes with
+ * generic/tclEvent.c: invalid arguments. Better fix, which helps
+ for all Tcl_DictObjGet() calls in Tcl's source code.
+
+2012-10-13 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclEvent.c: [Bug 3576509]: tcl::Bgerror crashes with invalid
+ arguments
+
+2012-10-06 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/Makefile.in: [Bug 2459774]: tcl/win/Makefile.in not compatible
+ with msys 0.8.
+
+2012-10-03 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclIO.c: When checking for std channels being closed,
+ compare the channel state, not the channel itself so that stacked
+ channels do not cause trouble.
+
+2012-09-26 Reinhard Max <max@suse.de>
+
+ * generic/tclIOSock.c (TclCreateSocketAddress): Work around a bug in
+ getaddrinfo() on OSX that caused name resolution to fail for [socket
+ -server foo -myaddr localhost 0].
+
+2012-09-20 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/configure.in: New import libraries for zlib 1.2.7, usable for
+ * win/configure: all win32/win64 compilers
+ * compat/zlib/win32/zdll.lib:
+ * compat/zlib/win64/zdll.lib:
+
+ * win/tclWinDde.c: [FRQ 3527238]: Full unicode support for dde. Dde
+ version is now 1.4.0b2.
+ ***POTENTIAL INCOMPATIBILITY***
+
+2012-09-19 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tcl.h: Make Tcl_Interp a fully opaque structure if
+ TCL_NO_DEPRECATED is set (TIP 330 and 336).
+ * win/nmakehlp.c: Let "nmakehlp -V" start searching digits after the
+ found match (suggested by Harald Oehlmann).
+
+2012-09-07 Harald Oehlmann <oehhar@users.sf.net>
+
+ *** 8.6b3 TAGGED FOR RELEASE ***
+
+ IMPLEMENTATION OF TIP#404.
+
+ * library/msgcat/msgcat.tcl: [FRQ 3544988]: New commands [mcflset]
+ * library/msgcat/pkgIndex.tcl: and [mcflmset] to set mc entries with
+ * unix/Makefile.in: implicit message file locale.
+ * win/Makefile.in: Bump to 1.5.0.
+
+2012-08-25 Donal K. Fellows <dkf@users.sf.net>
+
+ * library/msgs/uk.msg: [Bug 3561330]: Use the correct full name of
+ March in Ukrainian. Thanks to Mikhail Teterin for reporting.
+
+2012-08-23 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclBinary.c: [Bug 3496014]: Unecessary memset() in
+ Tcl_SetByteArrayObj().
+
+2012-08-20 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclPathObj.c: [Bug 3559678]: Fix bad filename normalization
+ when the last component is the empty string.
+
+2012-08-20 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinPort.h: Remove wrapper macro for ntohs(): unnecessary,
+ because it doesn't require an initialized winsock_2 library. See:
+ <http://msdn.microsoft.com/en-us/library/windows/desktop/ms740075%28v=vs.85%29.aspx>
+ * win/tclWinSock.c:
+ * generic/tclStubInit.c:
+
+2012-08-17 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/nmakehlp.c: Add "-V<num>" option, in order to be able to detect
+ partial version numbers.
+
+2012-08-15 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/buildall.vc.bat: Only build the threaded builds by default
+ * win/rules.vc: Some code cleanup
+
+2010-08-13 Stuart Cassoff <stwo@users.sourceforge.net>
+
+ * unix/tclUnixCompat.c: [Bug 3555454]: Rearrange a bit to quash
+ 'declared but never defined' compiler warnings.
+
+2012-08-13 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * compat/zlib/win64/zlib1.dll: Add 64-bit build of zlib1.dll, and use
+ * compat/zlib/win64/zdll.lib: it for the dynamic mingw-w64 build.
+ * win/Makefile.in:
+ * win/configure.in:
+ * win/configure:
+
+2012-08-09 Reinhard Max <max@suse.de>
+
+ * tests/http.test: Fix http-3.29 for machines without IPv6 support.
+
+2010-08-08 Stuart Cassoff <stwo@users.sourceforge.net>
+
+ * unix/tclUnixCompat.c: Change one '#ifdef' to '#if defined()' for
+ improved consistency within the file.
+
+2012-08-08 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclfileName.c: [Bug #1536227]: Cygwin network pathname
+ * tests/fileName.test: support
+
+2012-08-07 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclIOUtil.c: [Bug 3554250]: Overlooked one field of cleanup
+ in the thread exit handler for the filesystem subsystem.
+
+2012-07-31 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclInterp.c (Tcl_GetInterpPath):
+ * unix/tclUnixPipe.c (TclGetAndDetachPids, Tcl_PidObjCmd):
+ * win/tclWinPipe.c (TclGetAndDetachPids, Tcl_PidObjCmd):
+ Purge use of Tcl_AppendElement, and corrected conversion of PIDs to
+ integer objects.
+
+2012-07-31 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/nmakehlp.c: Add -Q option from sampleextension.
+ * win/Makefile.in: [FRQ 3544967]: Missing objectfiles in static lib
+ * win/makefile.vc: (Thanks to Jos Decoster).
+
+2012-07-29 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/Makefile.in: No longer build tcltest.exe to run the tests,
+ but use tclsh86.exe in combination with tcltest86.dll to do that.
+ * tests/*.test: load tcltest86.dll if necessary.
+
+2012-07-28 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * tests/clock.test: [Bug 3549770]: Multiple test failures running
+ * tests/registry.test: tcltest outside build tree
+ * tests/winDde.test:
+
+2012-07-27 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclUniData.c: Support Unicode 6.2 (Add Turkish lira sign)
+ * generic/regc_locale.c:
+
+2012-07-25 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * win/tclWinPipe.c: [Bug 3547994]: Abandon the synchronous Windows
+ pipe driver to its fate when needed to honour TIP#398.
+
+2012-07-24 Trevor Davel <twylite@crypt.co.za>
+
+ * win/tclWinSock.c: [Bug: 3545363]: Loop over multiple underlying file
+ descriptors for a socket where required (TcpCloseProc, SocketProc).
+ Refactor socket/descriptor setup to manage linked list operations in
+ one place. Fix memory leak in socket close (TcpCloseProc) and related
+ dangling pointers in SocketEventProc.
+
+2012-07-19 Reinhard Max <max@suse.de>
+
+ * win/tclWinSock.c (TcpAccept): [Bug: 3545363]: Use a large enough
+ buffer for accept()ing IPv6 connections. Fix conversion of host and
+ port for passing to the accept proc to be independent of the IP
+ version.
+
+2012-07-23 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * generic/tclIO.c: [Bug 3545365]: Never try a bg-flush on a dead
+ channel, just like before 2011-08-17.
+
+2012-07-19 Joe Mistachkin <joe@mistachkin.com>
+
+ * generic/tclTest.c: Fix several more missing mutex-locks in
+ TestasyncCmd.
+
+2012-07-19 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * generic/tclTest.c: [Bug 3544685]: Missing mutex-lock in
+ TestasyncCmd since 2011-08-19. Unbounded gratitude to Stuart
+ Cassoff for spotting it.
+
+2012-07-17 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/makefile.vc: [Bug 3544932]: Visual studio compiler check fails
+
+2012-07-16 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclUtil.c (UpdateStringOfEndOffset): [Bug 3544658]: Stop
+ 1-byte overrun in memcpy, that object placement rules made harmless
+ but which still caused compiler complaints.
+
+2012-07-16 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * library/reg/pkgIndex.tcl: Make registry 1.3 package dynamically
+ loadable when ::tcl::pkgconfig is available.
+
+2012-07-11 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinReg.c: [Bug 3362446]: registry keys command fails
+ with 8.5/8.6. Follow Microsofts example better in order to prevent
+ problems when using HKEY_PERFORMANCE_DATA.
+
+2012-07-10 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * unix/tclUnixNotfy.c: [Bug 3541646]: Don't panic on triggerPipe
+ overrun.
+
+2012-07-10 Donal K. Fellows <dkf@users.sf.net>
+
+ * win/tclWinSock.c (InitializeHostName): Corrected logic that
+ extracted the name of the computer from the gethostname call so that
+ it would use the name on success, not failure. Also ensured that the
+ buffer size is exactly that recommended by Microsoft.
+
+2012-07-08 Reinhard Max <max@suse.de>
+
+ * library/http/http.tcl: [Bug 3531209]: Add fix and test for URLs that
+ * tests/http.test: contain literal IPv6 addresses.
+
+2012-07-05 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/tclUnixPipe.c: [Bug 1189293]: Make "<<" binary safe.
+ * win/tclWinPipe.c:
+
+2012-07-03 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclUtil.c (TclDStringAppendObj, TclDStringAppendDString):
+ * generic/tclInt.h (TclDStringAppendLiteral, TclDStringClear):
+ * generic/tclCompile.h (TclDStringAppendToken): Added wrappers to make
+ common cases of appending to Tcl_DStrings simpler to write. Prompted
+ by looking at [FRQ 1357401] (these are an _internal_ implementation of
+ that FRQ).
+
+2012-06-29 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * library/msgcat/msgcat.tcl: Add tn, ro_MO and ru_MO to msgcat.
+
+2012-06-29 Harald Oehlmann <oehhar@users.sf.net>
+
+ * library/msgcat/msgcat.tcl: [Bug 3536888]: Locale guessing of
+ * library/msgcat/pkgIndex.tcl: msgcat fails on (some) Windows 7. Bump
+ * unix/Makefile.in: to 1.4.5
+ * win/Makefile.in:
+
+2012-06-29 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/GetIndex.3: Reinforced the description of the requirement for
+ the tables of names to index over to be static, following posting to
+ tcl-core by Brian Griffin about a bug caused by Tktreectrl not obeying
+ this rule correctly. This does not represent a functionality change,
+ merely a clearer documentation of a long-standing constraint.
+
+2012-06-26 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * unix/tcl.m4: Let Cygwin shared build link with
+ * unix/configure.in: zlib1.dll, not cygz.dll (two less
+ * unix/configure: dependencies on cygwin-specific dll's)
+ * unix/Makefile.in:
+
+2012-06-26 Reinhard Max <max@suse.de>
+
+ * generic/tclIOSock.c: Use EAI_SYSTEM only if it exists.
+ * unix/tclUnixSock.c:
+
+2012-06-25 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclFileSystem.h: [Bug 3024359]: Make sure that the
+ * generic/tclIOUtil.c: per-thread cache of the list of file systems
+ * generic/tclPathObj.c: currently registered is only updated at times
+ when no active loops are traversing it. Also reduce the amount of
+ epoch storing and checking to where it can make a difference.
+
+2012-06-25 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCmdAH.c (EncodingDirsObjCmd): [Bug 3537605]: Do the right
+ thing when reporting errors with the number of arguments.
+
+2012-06-25 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclfileName.c: [Patch 1536227]: Cygwin network pathname
+ * tests/fileName.test: support.
+
+2012-06-23 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * unix/tclUnixNotfy.c: [Bug 3508771]: Cygwin notifier for handling
+ win32 events.
+
+2012-06-22 Reinhard Max <max@suse.de>
+
+ * generic/tclIOSock.c: Rework the error message generation of [socket],
+ * unix/tclUnixSock.c: so that the error code of getaddrinfo is used
+ * win/tclWinSock.c: instead of errno unless it is EAI_SYSTEM.
+
+2012-06-21 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinReg.c: [Bug 3362446]: registry keys command fails
+ * tests/registry.test: with 8.5/8.6
+
+2012-06-11 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c: [Bug 3532959]: Make sure the lifetime
+ * generic/tclProc.c: management of entries in the linePBodyPtr
+ * tests/proc.test: hash table can tolerate either order of
+ teardown, interp first, or Proc first.
+
+2012-06-08 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/configure.in: Update autogoo for gettimeofday().
+ * unix/tclUnixPort.h: Thanks Joe English.
+ * unix/configure: autoconf 2.13
+
+ * unix/tclUnixPort.h: [Bug 3530533]: Centralize #include <pthread.h>
+ * unix/tclUnixThrd.c: in the tclUnixPort.h header so that old unix
+ systems that need inclusion in all compilation units are supported.
+
+2012-06-08 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinDde.c: Revise the "null data" check: null strings are
+ possible, but empty binary arrays are not.
+ * tests/winDde.test: Add test-case (winDde-9.4) for transferring
+ null-strings with dde. Convert tests to tcltest-2 syntax.
+
+2012-06-06 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclZlib.c (TclZlibInit): Declare that Tcl is publishing the
+ zlib package (version 2.0) as part of its bootstrap process. This will
+ have an impact on tclkit (which includes zlib 1.1) but otherwise be
+ very low impact.
+
+2012-06-06 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * unix/tclUnixInit.c: On Cygwin, use win32 API in stead of uname()
+ to determine the tcl_platform variables.
+
+2012-05-31 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclZlib.c: [Bug 3530536]: zlib-7.4 fails on IRIX64
+ * tests/zlib.test:
+ * doc/zlib.n: Document that [stream checksum] doesn't do
+ what's expected for "inflate" and "deflate" formats
+
+2012-05-31 Donal K. Fellows <dkf@users.sf.net>
+
+ * library/safe.tcl (safe::AliasFileSubcommand): Don't assume that
+ slaves have corresponding commands, as that is not true for
+ sub-subinterpreters (used in Tk's test suite).
+
+ * doc/safe.n: [Bug 1997845]: Corrected formatting so that generated
+ HTML can link properly.
+
+ * tests/socket.test (socket*-13.1): Prevented intermittent test
+ failure due to race condition.
+
+2012-05-29 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/expr.n, doc/mathop.n: [Bug 2931407]: Clarified semantics of
+ division and remainder operators.
+
+2012-05-29 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinDde.c: [Bug 3525762]: Encoding handling in dde.
+ * win/Makefile.in: Fix "make genstubs" when cross-compiling on UNIX
+
+2012-05-28 Donal K. Fellows <dkf@users.sf.net>
+
+ * library/safe.tcl (safe::AliasFileSubcommand): [Bug 3529949]: Made a
+ more sophisticated method for preventing information leakage; it
+ changes references to "~user" into "./~user", which is safe.
+
+2012-05-25 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/namespace.n, doc/Ensemble.3: [Bug 3528418]: Document what is
+ going on with respect to qualification of command prefixes in ensemble
+ subcommand maps.
+
+ * generic/tclIO.h (SYNTHETIC_EVENT_TIME): Factored out the definition
+ of the amount of time that should be waited before firing a synthetic
+ event on a channel.
+
+2012-05-25 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinDde.c: [Bug 473946]: Special characters were not correctly
+ sent, now for XTYP_EXECUTE as well as XTYP_REQUEST.
+ * win/Makefile.in: Fix "make genstubs" when cross-compiling on UNIX
+
+2012-05-24 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * tools/genStubs.tcl: Take cygwin handling of X11 into account.
+ * generic/tcl*Decls.h: re-generated
+ * generic/tclStubInit.c: Implement TclpIsAtty, Cygwin only.
+ * doc/dde.n: Doc fix: "dde execute iexplore" doesn't work
+ without -async, because iexplore doesn't return a value
+
+2012-05-24 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * tools/genStubs.tcl: Let cygwin share stub table with win32
+ * win/tclWinSock.c: implement TclpInetNtoa for win32
+ * generic/tclInt.decls: Revert most of [3caedf05df], since when
+ we let cygwin share the win32 stub table this is no longer necessary
+ * generic/tcl*Decls.h: re-generated
+ * doc/dde.n: 1.3 -> 1.4
+
+2012-05-23 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclZlib.c (ZlibTransformInput): [Bug 3525907]: Ensure that
+ decompressed input is flushed through the transform correctly when the
+ input stream gets to the end. Thanks to Alexandre Ferrieux and Andreas
+ Kupries for their work on this.
+
+2012-05-21 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclFileName.c: When using Tcl_SetObjLength() calls to
+ * generic/tclPathObj.c: grow and shrink the objPtr->bytes
+ buffer, care must be taken that the value cannot possibly become pure
+ Unicode. Calling Tcl_AppendToObj() has the possibility of making such
+ a conversion. Bug found while valgrinding the trunk.
+
+2012-05-21 Jan Nijtmans <nijtmans@users.sf.net>
+
+ IMPLEMENTATION OF TIP#106
+
+ * win/tclWinDde.c: Added encoding-related abilities to
+ * library/dde/pkgIndex.tcl: the [dde] command. The dde package's
+ * tests/winDde.test: version is now 1.4.0.
+ * doc/dde.n:
+
+2012-05-20 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclOOBasic.c (TclOO_Class_Constructor): [Bug 2023112]: Cut
+ the amount of hackiness in class constructors, and refactor some of
+ the error message handling from [oo::define] to be saner in the face
+ of odd happenings.
+
+2012-05-17 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCmdMZ.c (Tcl_SwitchObjCmd): [Bug 3106532]: Corrected
+ resulting indexes from -indexvar option to be usable with [string
+ range]; this was always the intention (and is consistent with [regexp
+ -indices] too).
+ ***POTENTIAL INCOMPATIBILITY***
+ Uses of [switch -regexp -indexvar] that previously compensated for the
+ wrong offsets (by subtracting 1 from the end indices) now do not need
+ to do so as the value is correct.
+
+ * library/safe.tcl (safe::InterpInit): Ensure that the module path is
+ constructed in the correct order.
+ (safe::AliasGlob): [Bug 2964715]: More extensive handling of what
+ globbing is required to support package loading.
+
+ * doc/expr.n: [Bug 3525462]: Corrected statement about what happens
+ when comparing "0y" and "0x12"; the previously documented behavior was
+ actually a subtle bug (now long-corrected).
+
+2012-05-16 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCmdAH.c (TclMakeFileCommandSafe): [Bug 3445787]: Improve
+ the compatibility of safe interpreters' version of 'file' with that of
+ unsafe interpreters.
+ * library/safe.tcl (::safe::InterpInit): Teach the safe-interp scripts
+ about how to expose 'file' properly.
+
+2012-05-13 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinDde.c: Protect against receiving strings without ending
+ \0, as external applications (or Tcl with TIP #106) could generate
+ that.
+
+2012-05-10 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinDde.c: [Bug 473946]: Special characters not correctly sent
+ * library/dde/pkgIndex.tcl: Increase version to 1.3.3
+
+2012-05-10 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * {win,unix}/configure{,.in}: [Bug 2812981]: Clean up bundled
+ packages' build directory from within Tcl's ./configure, to avoid
+ stale configuration.
+
+2012-05-09 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclIORChan.c: [Bug 3522560]: Fixed the crash, enabled the
+ test case. Modified [chan postevent] to properly inject the event(s)
+ into the owner thread's event queue for execution in the correct
+ context. Renamed the ForwardOpTo...Thread() function to match with our
+ terminology.
+
+ * tests/ioCmd.test: [Bug 3522560]: Added a test which crashes the core
+ if it were not disabled as knownBug. For a reflected channel
+ transfered to a different thread the [chan postevent] run in the
+ handler thread tries to execute the owner threads's fileevent scripts
+ by itself, wrongly reaching across thread boundaries.
+
+2012-04-28 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * generic/tclIO.c: Properly close nonblocking channels even when
+ not flushing them.
+
+2012-05-03 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * compat/zlib/*: Upgrade to zlib 1.2.7 (pre-built dll is still 1.2.5,
+ will be upgraded as soon as the official build is available)
+
+2012-05-03 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/socket.test: [Bug 3428754]: Test socket-14.2 tolerate
+ [socket -async] connection that connects synchronously.
+
+ * unix/tclUnixSock.c: [Bug 3428753]: Fix [socket -async] connections
+ that manage to connect synchronously.
+
+2012-05-02 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/configure.in: Better detection and implementation for
+ * generic/configure: cpuid instruction on Intel-derived
+ * generic/tclUnixCompat.c: processors, both 32-bit and 64-bit.
+ * generic/tclTest.c: Move cpuid testcase from win-specific to
+ * win/tclWinTest.c: generic tests, as it should work on all
+ * tests/platform.test: Intel-related platforms now.
+
+2012-04-30 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * tests/ioCmd.test: [Bug 3522560]: Tame deadlocks in broken refchan
+ tests.
+
+2012-04-28 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ IMPLEMENTATION OF TIP#398
+
+ * generic/tclIO.c: Quickly Exit with Non-Blocking Blocked Channels
+ * tests/io.test : *** POTENTIAL INCOMPATIBILITY ***
+ * doc/close.n : (compat flag available)
+
+2012-04-27 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclPort.h: Move CYGWIN-specific stuff from tclPort.h to
+ * generic/tclEnv.c: tclUnixPort.h, where it belongs.
+ * unix/tclUnixPort.h:
+ * unix/tclUnixFile.c:
+
+2012-04-27 Donal K. Fellows <dkf@users.sf.net>
+
+ * library/init.tcl (auto_execok): Allow shell builtins to be detected
+ even if they are upper-cased.
+
+2012-04-26 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclStubInit.c: Get rid of _ANSI_ARGS_ and CONST
+ * generic/tclIO.c:
+ * generic/tclIOCmd.c:
+ * generic/tclTest.c:
+ * unix/tclUnixChan.c:
+
+2012-04-25 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclUtil.c (TclDStringToObj): Added internal function to make
+ the fairly-common operation of converting a DString into an Obj a more
+ efficient one; for long strings, it can just transfer the ownership of
+ the buffer directly. Replaces this:
+ obj=Tcl_NewStringObj(Tcl_DStringValue(&ds),Tcl_DStringLength(&ds));
+ Tcl_DStringFree(&ds);
+ with this:
+ obj=TclDStringToObj(&ds);
+
+2012-04-24 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclInt.decls: [Bug 3508771]: load tclreg.dll in cygwin
+ tclsh
+ * generic/tclIntPlatDecls.h: Implement TclWinGetSockOpt,
+ * generic/tclStubInit.c: TclWinGetServByName and TclWinCPUID for
+ * generic/tclUnixCompat.c: Cygwin.
+ * unix/configure.in:
+ * unix/configure:
+ * unix/tclUnixCompat.c:
+
+2012-04-18 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/tzdata/Africa/Casablanca:
+ * library/tzdata/America/Port-au-Prince:
+ * library/tzdata/Asia/Damascus:
+ * library/tzdata/Asia/Gaza:
+ * library/tzdata/Asia/Hebron: tzdata2012c
+
+2012-04-16 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/FileSystem.3 (Tcl_FSOpenFileChannelProc): [Bug 3518244]: Fixed
+ documentation of this filesystem callback function; it must not
+ register its created channel - that's the responsibility of the caller
+ of Tcl_FSOpenFileChannel - as that leads to reference leaks.
+
+2012-04-15 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclEnsemble.c (NsEnsembleImplementationCmdNR):
+ * generic/tclIOUtil.c (Tcl_FSEvalFileEx): Cut out levels of the C
+ stack by going direct to the relevant internal evaluation function.
+
+ * generic/tclZlib.c (ZlibTransformSetOption): [Bug 3517696]: Make
+ flushing work correctly in a pushed compressing channel transform.
+
+2012-04-12 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclInt.decls: [Bug 3514475]: Remove TclpGetTimeZone and
+ * generic/tclIntDecls.h: TclpGetTZName
+ * generic/tclIntPlatDecls.h:
+ * generic/tclStubInit.c:
+ * unix/tclUnixTime.c:
+ * unix/tclWinTilemc:
+
+2012-04-11 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinInit.c: [Bug 3448512]: clock scan "1958-01-01" fails
+ * win/tcl.m4: only in debug compilation.
+ * win/configure:
+ * unix/tcl.m4: Use NDEBUG consistantly meaning: no debugging.
+ * unix/configure:
+ * generic/tclBasic.c:
+ * library/dde/pkgIndex.tcl: Use [::tcl::pkgconfig get debug] instead
+ * library/reg/pkgIndex.tcl: of [info exists ::tcl_platform(debug)]
+
+2012-04-10 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tcl.h (TCL_DEPRECATED_API): [Bug 2458976]: Added macro that
+ can be used to mark parts of Tcl's API as deprecated. Currently only
+ used for fields of Tcl_Interp, which TIPs 330 and 336 have deprecated
+ with a migration strategy; we want to encourage people to move away
+ from those fields.
+
+2012-04-09 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclOODefineCmds.c (ClassVarsSet, ObjVarsSet): [Bug 3396896]:
+ Ensure that the lists of variable names used to drive variable
+ resolution will never have the same name twice.
+
+ * generic/tclVar.c (AppendLocals): [Bug 2712377]: Fix problem with
+ reporting of declared variables in methods. It's really a problem with
+ how [info vars] interacts with variable resolvers; this is just a bit
+ of a hack so it is no longer a big problem.
+
+2012-04-04 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclOO.c (Tcl_NewObjectInstance, TclNRNewObjectInstance):
+ [Bug 3514761]: Fixed bogosity with automated argument description
+ handling when constructing an instance of a class that is itself a
+ member of an ensemble. Thanks to Andreas Kupries for identifying that
+ this was a problem case at all!
+ (Tcl_CopyObjectInstance): Fix potential bleed-over of ensemble
+ information into [oo::copy].
+
+2012-04-04 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinSock.c: [Bug 510001]: TclSockMinimumBuffers needs
+ * generic/tclIOSock.c: platform implementation.
+ * generic/tclInt.decls:
+ * generic/tclIntDecls.h:
+ * generic/tclStubInit.c:
+
+2012-04-03 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclStubInit.c: Remove the TclpGetTZName implementation for
+ * generic/tclIntDecls.h: Cygwin (from 2012-04-02 commit), re-generated
+ * generic/tclIntPlatDecls.h:
+
+2012-04-02 Donal K. Fellows <dkf@users.sf.net>
+
+ IMPLEMENTATION OF TIP#396.
+
+ * generic/tclBasic.c (builtInCmds, TclNRYieldToObjCmd): Convert the
+ formerly-unsupported yieldm and yieldTo commands into [yieldto].
+
+2012-04-02 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclInt.decls: [Bug 3508771]: load tclreg.dll in cygwin tclsh
+ * generic/tclIntPlatDecls.h: Implement TclWinGetTclInstance,
+ * generic/tclStubInit.c: TclpGetTZName, and various more
+ win32-specific internal functions for Cygwin, so win32 extensions
+ using those can be loaded in the cygwin version of tclsh.
+
+2012-03-30 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * unix/tcl.m4: [Bug 3511806]: Compiler checks too early
+ * unix/configure.in: This change allows to build the cygwin and
+ * unix/tclUnixPort.h: mingw32 ports of Tcl/Tk to build out-of-the-box
+ * win/tcl.m4: using a native or cross-compiler.
+ * win/configure.in:
+ * win/tclWinPort.h:
+ * win/README Document how to build win32 or win64 executables
+ with Linux, Cygwin or Darwin.
+
+2012-03-29 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclCmdMZ.c (StringIsCmd): Faster mem-leak free
+ implementation of [string is entier].
+
+2012-03-27 Donal K. Fellows <dkf@users.sf.net>
+
+ IMPLEMENTATION OF TIP#395.
+
+ * generic/tclCmdMZ.c (StringIsCmd): Implementation of the [string is
+ entier] check. Code by Jos Decoster.
+
+2012-03-27 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tcl.h: [Bug 3508771]: Wrong Tcl_StatBuf used on MinGW.
+ * generic/tclFCmd.c: [Bug 2015723]: Duplicate inodes from file stat
+ * generic/tclCmdAH.c: on windows (but now for cygwin as well).
+ * generic/tclOODefineCmds.c: minor gcc warning
+ * win/tclWinPort.h: Use lower numbers, preventing integer overflow.
+ Remove the workaround for mingw-w64 [Bug 3407992]. It's long fixed.
+
+2012-03-27 Donal K. Fellows <dkf@users.sf.net>
+
+ IMPLEMENTATION OF TIP#397.
+
+ * generic/tclOO.c (Tcl_CopyObjectInstance): [Bug 3474460]: Make the
+ target object name optional when copying classes. [RFE 3485060]: Add
+ callback method ("<cloned>") so that scripted control over copying is
+ easier.
+ ***POTENTIAL INCOMPATIBILITY***
+ If you'd previously been using the "<cloned>" method name, this now
+ has a standard semantics and call interface. Only a problem if you are
+ also using [oo::copy].
+
+2012-03-26 Donal K. Fellows <dkf@users.sf.net>
+
+ IMPLEMENTATION OF TIP#380.
+
+ * doc/define.n, doc/object.n, generic/tclOO.c, generic/tclOOBasic.c:
+ * generic/tclOOCall.c, generic/tclOODefineCmds.c, generic/tclOOInt.h:
+ * tests/oo.test: Switch definitions of lists of things in objects and
+ classes to a slot-based approach, which gives a lot more flexibility
+ and programmability at the script-level. Introduce new [::oo::Slot]
+ class which is the implementation of these things.
+
+ ***POTENTIAL INCOMPATIBILITY***
+ The unknown method handler now may be asked to deal with the case
+ where no method name is provided at all. The default implementation
+ generates a compatible error message, and any override that forces the
+ presence of a first argument (i.e., a method name) will continue to
+ function as at present as well, so this is a pretty small change.
+
+ * generic/tclOOBasic.c (TclOO_Object_Destroy): Made it easier to do a
+ tailcall inside a normally-invoked destructor; prevented leakage out
+ to calling command.
+
+2012-03-25 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclInt.decls: [Bug 3508771]: load tclreg.dll in cygwin
+ * generic/tclIntPlatDecls.h: tclsh. Implement TclWinConvertError,
+ * generic/tclStubInit.c: TclWinConvertWSAError, and various more
+ * unix/Makefile.in: win32-specific internal functions for
+ * unix/tcl.m4: Cygwin, so win32 extensions using those
+ * unix/configure: can be loaded in the cygwin version of
+ * win/tclWinError.c: tclsh.
+
+2012-03-23 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclInt.decls: Revert some cygwin-related signature
+ * generic/tclIntPlatDecls.h: changes from [835f8e1e9d] (2010-01-22).
+ * win/tclWinError.c: They were an attempt to make the cygwin
+ port compile again, but since cygwin is
+ based on unix this serves no purpose any
+ more.
+ * win/tclWinSerial.c: Use EAGAIN in stead of EWOULDBLOCK,
+ * win/tclWinSock.c: because in VS10+ the value of
+ EWOULDBLOCK is no longer the same as
+ EAGAIN.
+ * unix/Makefile.in: Add tclWinError.c to the CYGWIN build.
+ * unix/tcl.m4:
+ * unix/configure:
+
+2012-03-20 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tcl.decls: [Bug 3508771]: load tclreg.dll in cygwin
+ * generic/tclInt.decls: tclsh. Implement TclWinGetPlatformId,
+ * generic/tclIntPlatDecls.h: Tcl_WinUtfToTChar, Tcl_WinTCharToUtf (and
+ * generic/tclPlatDecls.h: a dummy TclWinCPUID) for Cygwin, so win32
+ * generic/tclStubInit.c: extensions using those can be loaded in
+ * unix/tclUnixCompat.c: the cygwin version of tclsh.
+
+2012-03-19 Venkat Iyer <venkat@comit.com>
+
+ * library/tzdata/America/Atikokan: Update to tzdata2012b.
+ * library/tzdata/America/Blanc-Sablon:
+ * library/tzdata/America/Dawson_Creek:
+ * library/tzdata/America/Edmonton:
+ * library/tzdata/America/Glace_Bay:
+ * library/tzdata/America/Goose_Bay:
+ * library/tzdata/America/Halifax:
+ * library/tzdata/America/Havana:
+ * library/tzdata/America/Moncton:
+ * library/tzdata/America/Montreal:
+ * library/tzdata/America/Nipigon:
+ * library/tzdata/America/Rainy_River:
+ * library/tzdata/America/Regina:
+ * library/tzdata/America/Santiago:
+ * library/tzdata/America/St_Johns:
+ * library/tzdata/America/Swift_Current:
+ * library/tzdata/America/Toronto:
+ * library/tzdata/America/Vancouver:
+ * library/tzdata/America/Winnipeg:
+ * library/tzdata/Antarctica/Casey:
+ * library/tzdata/Antarctica/Davis:
+ * library/tzdata/Antarctica/Palmer:
+ * library/tzdata/Asia/Yerevan:
+ * library/tzdata/Atlantic/Stanley:
+ * library/tzdata/Pacific/Easter:
+ * library/tzdata/Pacific/Fakaofo:
+ * library/tzdata/America/Creston: (new)
+
+2012-03-19 Reinhard Max <max@suse.de>
+
+ * unix/tclUnixSock.c (Tcl_OpenTcpServer): Use the values returned
+ by getaddrinfo() for all three arguments to socket() instead of
+ only using ai_family. Try to keep the most meaningful error while
+ iterating over the result list, because using the last error can
+ be misleading.
+
+2012-03-15 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tcl.h: [Bug 3288345]: Wrong Tcl_StatBuf used on Cygwin
+ * unix/tclUnixFile.c:
+ * unix/tclUnixPort.h:
+ * win/cat.c: Remove cygwin stuff no longer needed
+ * win/tclWinFile.c:
+ * win/tclWinPort.h:
+
+2012-03-12 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinFile.c: [Bug 3388350]: mingw64 compiler warnings
+
+2012-03-11 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/*.n, doc/*.3: A number of small spelling and wording fixes.
+
+2012-03-08 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/info.n: Various minor fixes (prompted by Andreas Kupries
+ * doc/socket.n: detecting a spelling mistake).
+
+2012-03-07 Andreas Kupries <andreask@activestate.com>
+
+ * library/http/http.tcl: [Bug 3498327]: Generate upper-case
+ * library/http/pkgIndex.tcl: hexadecimal output for compliance
+ * tests/http.test: with RFC 3986. Bumped version to 2.8.4.
+ * unix/Makefile.in:
+ * win/Makefile.in:
+
+2012-03-06 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinPort.h: Compatibility with older Visual Studio versions.
+
+2012-03-04 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclLoad.c: Patch from the cygwin folks
+ * unix/tcl.m4:
+ * unix/configure: (re-generated)
+
+2012-03-02 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclBinary.c (Tcl_SetByteArrayObj): [Bug 3496014]: Only zero
+ out the memory block if it is not being immediately overwritten. (Our
+ caller might still overwrite, but we should at least avoid
+ known-useless work.)
+
+2012-02-29 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclIOUtil.c: [Bug 3466099]: BOM in Unicode
+ * generic/tclEncoding.c:
+ * tests/source.test:
+
+2012-02-23 Donal K. Fellows <dkf@users.sf.net>
+
+ * tests/reg.test (14.21-23): Add tests relating to Bug 1115587. Actual
+ bug is characterised by test marked with 'knownBug'.
+
+2012-02-17 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclIOUtil.c: [Bug 2233954]: AIX: compile error
+ * unix/tclUnixPort.h:
+
+2012-02-16 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclExecute.c (INST_LIST_RANGE_IMM): Enhance implementation
+ so that shortening a (not multiply-referenced) list by lopping the end
+ off with [lrange] or [lreplace] is efficient.
+
+2012-02-15 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmds.c (TclCompileLreplaceCmd): Added a compilation
+ strategy for [lreplace] that tackles the cases which are equivalent to
+ a static [lrange].
+ (TclCompileLrangeCmd): Add compiler for [lrange] with constant indices
+ so we can take advantage of existing TCL_LIST_RANGE_IMM opcode.
+ (TclCompileLindexCmd): Improve coverage of constant-index-style
+ compliation using technique developed for [lrange] above.
+
+ (TclCompileDictForCmd): [Bug 3487626]: Fix crash in compilation of
+ [dict for] when its implementation command is used directly rather
+ than through the ensemble.
+
+2012-02-09 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclStringObj.c: Converted the memcpy() calls in append
+ operations to memmove() calls. This adds safety in the case of
+ overlapping copies, and improves performance on some benchmarks.
+
+2012-02-06 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclEnsemble.c: [Bug 3485022]: TclCompileEnsemble() avoid
+ * tests/trace.test: compile when exec traces set.
+
+2012-02-06 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclTrace.c: [Bug 3484621]: Ensure that execution traces on
+ * tests/trace.test: bytecoded commands bump the interp's compile
+ epoch.
+
+2012-02-02 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclUniData.c: [FRQ 3464401]: Support Unicode 6.1
+ * generic/regc_locale.c:
+
+2012-02-02 Don Porter <dgp@users.sourceforge.net>
+
+ * win/tclWinFile.c: [Bugs 2974459,2879351,1951574,1852572,
+ 1661378,1613456]: Revisions to the NativeAccess() routine that queries
+ file permissions on Windows native filesystems. Meant to fix numerous
+ bugs where [file writable|readable|executable] "lies" about what
+ operations are possible, especially when the file resides on a Samba
+ share.
+
+2012-02-01 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/AddErrInfo.3: [Bug 3482614]: Documentation nit.
+
+2012-01-30 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmds.c (TclCompileCatchCmd): Added a more efficient
+ bytecode generator for the case where 'catch' is used without any
+ variable arguments; don't capture the result just to discard it.
+
+2012-01-26 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCmdAH.c: [Bug 3479689]: New internal routine
+ * generic/tclFCmd.c: TclJoinPath(). Refactor all the
+ * generic/tclFileName.c: *Join*Path* routines to give them more
+ * generic/tclInt.h: useful interfaces that are easier to
+ * generic/tclPathObj.c: manage getting the refcounts right.
+
+2012-01-26 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclPathObj.c: [Bug 3475569]: Add checks for unshared values
+ before calls demanding them. [Bug 3479689]: Stop memory corruption
+ when shimmering 0-refCount value to "path" type.
+
+2012-01-25 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclOO.c (Tcl_CopyObjectInstance): [Bug 3474460]: When
+ copying an object, make sure that the configuration of the variable
+ resolver is also duplicated.
+
+2012-01-22 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * tools/uniClass.tcl: [FRQ 3473670]: Various Unicode-related
+ * tools/uniParse.tcl: speedups/robustness. Enhanced tools to be
+ * generic/tclUniData.c: able to handle characters > 0xffff. Done in
+ * generic/tclUtf.c: all branches in order to simplify merges for
+ * generic/regc_locale.c: new Unicode versions (such as 6.1)
+
+2012-01-22 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclDictObj.c (DictExistsCmd): [Bug 3475264]: Ensure that
+ errors only ever happen when insufficient arguments are supplied, and
+ not when a path doesn't exist or a dictionary is poorly formatted (the
+ two cases can't be easily distinguished).
+
+2012-01-21 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tcl.h: [Bug 3474726]: Eliminate detection of struct
+ * generic/tclWinPort.h: _stat32i64, just use _stati64 in combination
+ * generic/tclFCmd.c: with _USE_32BIT_TIME_T, which is the same
+ * generic/tclTest.c: then. Only keep _stat32i64 usage for cygwin,
+ * win/configure.in: so it will not conflict with cygwin's own
+ * win/configure: struct stat.
+
+2012-01-21 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCmdMZ.c: [Bug 3475667]: Prevent buffer read overflow.
+ Thanks to "sebres" for the report and fix.
+
+2012-01-17 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/dict.n (dict with): [Bug 3474512]: Explain better what is going
+ on when a dictionary key and the dictionary variable collide.
+
+2012-01-13 Donal K. Fellows <dkf@users.sf.net>
+
+ * library/http/http.tcl (http::Connect): [Bug 3472316]: Ensure that we
+ only try to read the socket error exactly once.
+
+2012-01-12 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/tclvars.n: [Bug 3466506]: Document more environment variables.
+
+2012-01-09 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclUtf.c: [Bug 3464428]: [string is graph \u0120] was
+ * generic/regc_locale.c: wrong. Add table for Unicode [:cntrl:] class.
+ * tools/uniClass.tcl: Generate Unicode [:cntrl:] class table.
+ * tests/utf.test:
+
+2012-01-08 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/clock.tcl (ReadZoneinfoFile): [Bug 3470928]: Corrected a bug
+ * tests/clock.test (clock-56.4): where loading zoneinfo would
+ fail if one timezone abbreviation was a proper tail of another, and
+ zic used the same bytes of the file to represent both of them. Added a
+ test case for the bug, using the same data that caused the observed
+ failure "in the wild."
+
+2011-12-30 Venkat Iyer <venkat@comit.com>
+
+ * library/tzdata/America/Bahia: Update to Olson's tzdata2011n
+ * library/tzdata/America/Havana:
+ * library/tzdata/Europe/Kiev:
+ * library/tzdata/Europe/Simferopol:
+ * library/tzdata/Europe/Uzhgorod:
+ * library/tzdata/Europe/Zaporozhye:
+ * library/tzdata/Pacific/Fiji:
+
+2011-12-23 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclUtf.c: [Bug 3464428]: [string is graph \u0120] is wrong.
+ * generic/tclUniData.c:
+ * generic/regc_locale.c:
+ * tests/utf.test:
+ * tools/uniParse.tcl: Clean up some unused stuff, and be more robust
+ against changes in UnicodeData.txt syntax
+
+2011-12-13 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclCompile.c (TclInitAuxDataTypeTable): Extended to register
+ the DictUpdateInfo structure as an AuxData type. For use by tbcload,
+ tclcompiler.
+
+2011-12-11 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/regc_locale.c: [Bug 3457031]: Some Unicode 6.0 chars not
+ * tests/utf.test: in [:print:] class
+
+2011-12-07 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * tools/uniParse.tcl: [Bug 3444754]: string tolower \u01c5 is wrong
+ * generic/tclUniData.c:
+ * tests/utf.test:
+
+2011-11-30 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * library/tcltest/tcltest.tcl: [Bug 967195]: Make tcltest work
+ when tclsh is compiled without using the setargv() function on mingw.
+
+2011-11-29 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/Makefile.in: don't install tommath_(super)?class.h
+ * unix/Makefile.in: don't install directories like 8.2 and 8.3
+ * generic/tclTomMath.h: [Bug 2991415]: move include tclInt.h from
+ * generic/tclTomMathInt.h: tclTomMath.h to tclTomMathInt.h
+
+2011-11-25 Donal K. Fellows <dkf@users.sf.net>
+
+ * library/history.tcl (history): Simplify the dance of variable
+ management used when chaining to the implementation command.
+
+2011-11-22 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclExecute.c (TclCompileObj): Simplify and de-indent the
+ logic so that it is easier to comprehend.
+
+2011-11-22 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinPort.h: [Bug 3354324]: Windows: [file mtime] sets wrong
+ * win/tclWinFile.c: time (VS2005+ only).
+ * generic/tclTest.c:
+
+2011-11-20 Joe Mistachkin <joe@mistachkin.com>
+
+ * tests/thread.test: Remove unnecessary [after] calls from the thread
+ tests. Make error message matching more robust for tests that may
+ have built-in race conditions. Test thread-7.26 must first unset all
+ thread testing related variables. Revise results of the thread-7.28
+ through thread-7.31 tests to account for the fact they are canceled
+ via a script sent to the thread asynchronously, which then impacts the
+ error message handling. Attempt to manually drain the event queue for
+ the main thread after joining the test thread to make sure no stray
+ events are processed at the wrong time on the main thread. Revise all
+ the synchronization and comparison semantics related to the thread id
+ and error message.
+
+2011-11-18 Joe Mistachkin <joe@mistachkin.com>
+
+ * tests/thread.test: Remove all use of thread::release from the thread
+ 7.x tests, replacing it with a script that can easily cause "stuck"
+ threads to self-destruct for those test cases that require it. Also,
+ make the error message handling far more robust by keeping track of
+ every asynchronous error.
+
+2011-11-17 Joe Mistachkin <joe@mistachkin.com>
+
+ * tests/thread.test: Refactor all the remaining thread-7.x tests that
+ were using [testthread]. Note that this test file now requires the
+ very latest version of the Thread package to pass all tests. In
+ addition, the thread-7.18 and thread-7.19 tests have been flagged as
+ knownBug because they cannot pass without modifications to the [expr]
+ command, persuant to TIP #392.
+
+2011-11-17 Joe Mistachkin <joe@mistachkin.com>
+
+ * generic/tclThreadTest.c: For [testthread cancel], avoid creating a
+ new Tcl_Obj when the default script cancellation result is desired.
+
+2011-11-11 Donal K. Fellows <dkf@users.sf.net>
+
+ * win/tclWinConsole.c: Refactor common thread handling patterns.
+
+2011-11-11 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * tests/zlib.test: [Bug 3428756]: Use nonblocking writes in
+ single-threaded IO tests to avoid deadlocks when going beyond OS
+ buffers. Tidy up [chan configure] flags across zlib.test.
+
+2011-11-03 Donal K. Fellows <dkf@users.sf.net>
+
+ * unix/tclUnixCompat.c (TclpGetPwNam, TclpGetPwUid, TclpGetGrNam)
+ (TclpGetGrGid): Use the elaborate memory management scheme outlined on
+ http://www.opengroup.org/austin/docs/austin_328.txt to handle Tcl's
+ use of standard reentrant versions of the passwd/group access
+ functions so that everything can work on all BSDs. Problem identified
+ by Stuart Cassoff.
+
+2011-10-20 Don Porter <dgp@users.sourceforge.net>
+
+ * library/http/http.tcl: Bump to version 2.8.3
+ * library/http/pkgIndex.tcl:
+ * unix/Makefile.in:
+ * win/Makefile.in:
+
+ * changes: Updates toward 8.6b3 release.
+
+2011-10-20 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclLiteral.c (TclInvalidateCmdLiteral): [Bug 3418547]:
+ Additional code for handling the invalidation of literals.
+ * generic/tclBasic.c (Tcl_CreateObjCommand, Tcl_CreateCommand)
+ (TclRenameCommand, Tcl_ExposeCommand): The four additional places that
+ need extra care when dealing with literals.
+ * generic/tclTest.c (TestInterpResolverCmd): Additional test machinery
+ for interpreter resolvers.
+
+2011-10-18 Reinhard Max <max@suse.de>
+
+ * library/clock.tcl (::tcl::clock::GetSystemTimeZone): Cache the time
+ zone only if it was detected by one of the expensive methods.
+ Otherwise after unsetting TCL_TZ or TZ the previous value will still
+ be used.
+
+2011-10-15 Venkat Iyer <venkat@comit.com>
+
+ * library/tzdata/America/Sitka: Update to Olson's tzdata2011l
+ * library/tzdata/Pacific/Fiji:
+ * library/tzdata/Asia/Hebron: (New)
+
+2011-10-11 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinFile.c: [Bug 2935503]: Incorrect mode field returned by
+ [file stat] command.
+
+2011-10-09 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmds.c (TclCompileDictWithCmd): Corrected handling of
+ qualified names, and added spacial cases for empty bodies (used when
+ [dict with] is just used for extracting variables).
+
+2011-10-07 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tcl.h: Fix gcc warnings (discovered with latest
+ * generic/tclIORChan.c: mingw, based on gcc 4.6.1)
+ * tests/env.test: Fix env.test, when running under wine 1.3.
+
+2011-10-06 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclDictObj.c (TclDictWithInit, TclDictWithFinish):
+ * generic/tclCompCmds.c (TclCompileDictWithCmd): Experimental
+ compilation for the [dict with] subcommand, using parts factored out
+ from the interpreted version of the command.
+
+2011-10-05 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinInt.h: Remove tclWinProcs, as it is no longer
+ * win/tclWin32Dll.c: being used.
+
+2011-10-03 Venkat Iyer <venkat@comit.com>
+
+ * library/tzdata/Africa/Dar_es_Salaam: Update to Olson's tzdata2011k
+ * library/tzdata/Africa/Kampala:
+ * library/tzdata/Africa/Nairobi:
+ * library/tzdata/Asia/Gaza:
+ * library/tzdata/Europe/Kaliningrad:
+ * library/tzdata/Europe/Kiev:
+ * library/tzdata/Europe/Minsk:
+ * library/tzdata/Europe/Simferopol:
+ * library/tzdata/Europe/Uzhgorod:
+ * library/tzdata/Europe/Zaporozhye:
+ * library/tzdata/Pacific/Apia:
+
+2011-09-29 Donal K. Fellows <dkf@users.sf.net>
+
+ * tools/tcltk-man2html.tcl, tools/tcltk-man2html-utils.tcl: More
+ refactoring so that more of the utility code is decently out of the
+ way. Adjusted the header-material generator so that version numbers
+ are only included in locations where there is room.
+
+2011-09-28 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclOO.h: [RFE 3010352]: make all TclOO API functions
+ * generic/tclOODecls.h: MODULE_SCOPE
+ * generic/tclOOIntDecls.h:
+
+2011-09-27 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclIndexObj.c (Tcl_ParseArgsObjv): [Bug 3413857]: Corrected
+ the memory management for the code parsing arguments when returning
+ "large" numbers of arguments. Also unbroke the TCL_ARGV_AUTO_REST
+ macro in passing.
+
+2011-09-26 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCmdAH.c (TclMakeFileCommandSafe): [Bug 3211758]: Also
+ make the main [file] command hidden by default in safe interpreters,
+ because that's what existing code expects. This will reduce the amount
+ which the code breaks, but not necessarily eliminate it...
+
+2011-09-23 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclIORTrans.c: More revisions to get finalization of
+ ReflectedTransforms correct, including adopting a "dead" field as was
+ done in tclIORChan.c.
+
+ * tests/thread.test: Stop using the deprecated thread management
+ commands of the tcltest package. The test suite ought to provide
+ these tools for itself. They do not belong in a testing harness.
+
+2011-09-22 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCmdIL.c: Revise [info frame] so that it stops creating
+ cycles in the iPtr->cmdFramePtr stack.
+
+2011-09-22 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/re_syntax.n: [Bug 2903743]: Add more magic so that we can do at
+ least something sane on Solaris.
+ * tools/tcltk-man2html-utils.tcl (process-text): Teach the HTML
+ generator how to handle this magic.
+
+2011-09-21 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclThreadTest.c: Revise the thread exit handling of the
+ [testthread] command so that it properly maintains the per-process
+ data structures even when the thread exits for reasons other than the
+ [testthread exit] command.
+
+2011-09-21 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * unix/tclIO.c: [Bug 3412487]: Now short reads are allowed in
+ synchronous fcopy, avoid mistaking them as nonblocking ones.
+
+2011-09-21 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclIORTrans.c (ForwardOpToOwnerThread): Fixed the missing
+ initialization of the 'dsti' field. Reported by Don Porter, on chat.
+
+2011-09-20 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclIORChan.c: Re-using the "interp" field to signal a dead
+ channel (via NULL value) interfered with conditional cleanup tasks
+ testing for "the right interp". Added a new field "dead" to perform
+ the dead channel signalling task so the corrupted logic is avoided.
+
+ * generic/tclIORTrans.c: Revised ReflectClose() and
+ FreeReflectedTransform() so that we stop leaking ReflectedTransforms,
+ yet free all Tcl_Obj values in the same thread that alloced them.
+
+2011-09-19 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/ioTrans.test: Conversion from [testthread] to Thread package
+ stops most memory leaks.
+
+ * tests/thread.test: Plug most memory leaks in thread.test.
+ Constrain the rest to be skipped during `make valgrind'. Tests using
+ the [testthread cancel] testing command are leaky. Corrections wait
+ for either addition of [thread::cancel] to the Thread package, or
+ improvements to the [testthread] testing command to make leak-free
+ versions of these tests possible.
+
+ * generic/tclIORChan.c: Plug all memory leaks in ioCmd.test exposed
+ * tests/ioCmd.test: by `make valgrind'.
+ * unix/Makefile.in:
+
+2011-09-16 Jan Nijtmans <nijtmans@users.sf.net>
+
+ IMPLEMENTATION OF TIP #388
+
+ * doc/Tcl.n:
+ * doc/re_syntax.n:
+ * generic/regc_lex.c:
+ * generic/regcomp.c:
+ * generic/regcustom.h:
+ * generic/tcl.h:
+ * generic/tclParse.c:
+ * tests/reg.test:
+ * tests/utf.test:
+
+2011-09-16 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclProc.c (ProcWrongNumArgs): [Bugs 3400658,3408830]:
+ Corrected the handling of procedure error messages (found by TclOO).
+
+2011-09-16 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tcl.h: Don't change Tcl_UniChar type when
+ * generic/regcustom.h: TCL_UTF_MAX == 4 (not supported anyway)
+
+2011-09-16 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclProc.c (ProcWrongNumArgs): [Bugs 3400658,3408830]:
+ Ensemble-like rewriting of error messages is complex, and TclOO (in
+ combination with iTcl) hits the most tricky cases.
+
+ * library/http/http.tcl (http::geturl): [Bug 3391977]: Ensure that the
+ -headers option overrides the -type option (important because -type
+ has a default that is not always appropriate, and the header must not
+ be duplicated).
+
+2011-09-15 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompExpr.c: [Bug 3408408]: Partial improvement by sharing
+ as literals the computed values of constant subexpressions when we can
+ do so without incurring the cost of string rep generation.
+
+2011-09-13 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclUtil.c: [Bug 3390638]: Workaround broken Solaris
+ Studio cc optimizer. Thanks to Wolfgang S. Kechel.
+
+ * generic/tclDTrace.d: [Bug 3405652]: Portability workaround for
+ broken system DTrace support. Thanks to Dagobert Michelson.
+
+2011-09-12 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinPort.h: [Bug 3407070]: tclPosixStr.c won't build with
+ EOVERFLOW==E2BIG
+
+2011-09-11 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/thread.test: Convert [testthread] use to Thread package use
+ in thread-6.1. Eliminates a memory leak in `make valgrind`.
+
+ * tests/socket.test: [Bug 3390699]: Convert [testthread] use to
+ Thread package use in socket_*-13.1. Eliminates a memory leak in
+ `make valgrind`.
+
+2011-09-09 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/chanio.test: [Bug 3389733]: Convert [testthread] use to
+ * tests/io.test: Thread package use in *io-70.1. Eliminates a
+ memory leak in `make valgrind`.
+
+2011-09-07 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompExpr.c: [Bug 3401704]: Allow function names like
+ * tests/parseExpr.test: influence(), nanobot(), and 99bottles() that
+ have been parsed as missing operator syntax errors before with the
+ form NUMBER + FUNCTION.
+ ***POTENTIAL INCOMPATIBILITY***
+
+2011-09-06 Venkat Iyer <venkat@comit.com>
+
+ * library/tzdata/America/Goose_Bay: Update to Olson's tzdata2011i
+ * library/tzdata/America/Metlakatla:
+ * library/tzdata/America/Resolute:
+ * library/tzdata/America/St_Johns:
+ * library/tzdata/Europe/Kaliningrad:
+ * library/tzdata/Pacific/Apia:
+ * library/tzdata/Pacific/Honolulu:
+ * library/tzdata/Africa/Juba: (new)
+
+2011-09-06 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tcl.h: [RFE 1711975]: Tcl_MainEx() (like Tk_MainEx())
+ * generic/tclDecls.h:
+ * generic/tclMain.c:
+
+2011-09-02 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/http.test: Convert [testthread] use to Thread package use.
+ Eliminates memory leak seen in `make valgrind`.
+
+2011-09-01 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * unix/tclUnixSock.c: [Bug 3401422]: Cache script-level changes to the
+ nonblocking flag of an async client socket in progress, and commit
+ them on completion.
+
+2011-09-01 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclStrToD.c: [Bug 3402540]: Corrections to TclParseNumber()
+ * tests/binary.test: to make it reject invalid Nan(Hex) strings.
+
+ * tests/scan.test: [scan Inf %g] is portable; remove constraint.
+
+2011-08-30 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclInterp.c (SlaveCommandLimitCmd, SlaveTimeLimitCmd):
+ [Bug 3398794]: Ensure that low-level conditions in the limit API are
+ enforced at the script level through errors, not a Tcl_Panic. This
+ means that interpreters cannot read their own limits (writing already
+ did not work).
+
+2011-08-30 Reinhard Max <max@suse.de>
+
+ * unix/tclUnixSock.c (TcpWatchProc): [Bug 3394732]: Put back the check
+ for server sockets.
+
+2011-08-29 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclIORTrans.c: Leak of ReflectedTransformMap.
+
+2011-08-27 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclStringObj.c: [RFE 3396731]: Revise the [string reverse]
+ * tests/string.test: implementation to operate on the representation
+ that comes in, avoid conversion to other reps.
+
+2011-08-23 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclIORChan.c: [Bug 3396948]: Leak of ReflectedChannelMap.
+
+2011-08-19 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclIORTrans.c: [Bugs 3393279, 3393280]: ReflectClose(.) is
+ missing Tcl_EventuallyFree() calls at some of its exits.
+
+ * generic/tclIO.c: [Bugs 3394654, 3393276]: Revise FlushChannel() to
+ account for the possibility that the ChanWrite() call might recycle
+ the buffer out from under us.
+
+ * generic/tclIO.c: Preserve the chanPtr during FlushChannel so that
+ channel drivers don't yank it away before we're done with it.
+
+2011-08-19 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * generic/tclTest.c: [Bug 2981154]: async-4.3 segfault.
+ * tests/async.test: [Bug 1774689]: async-4.3 sometimes fails.
+
+2011-08-18 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * generic/tclIO.c: [Bug 3096275]: Sync fcopy buffers input.
+
+2011-08-18 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclUniData.c: [Bug 3393714]: Overflow in toupper delta
+ * tools/uniParse.tcl:
+ * tests/utf.test:
+
+2011-08-17 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * generic/tclIO.c: [Bug 2946474]: Consistently resume backgrounded
+ * tests/ioCmd.test: flushes+closes when exiting.
+
+2011-08-17 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
+ * doc/interp.n: Document TIP 378's one-way-ness.
+
+2011-08-17 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclGet.c: [Bug 3393150]: Overlooked free of intreps.
+ (It matters for bignums!)
+
+2011-08-16 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompile.c: [Bug 3392070]: More complete prevention of
+ Tcl_Obj reference cycles when producing an intrep of ByteCode.
+
2011-08-16 Donal K. Fellows <dkf@users.sf.net>
* generic/tclListObj.c (TclLindexList, TclLsetFlat): Silence warnings
@@ -14,8 +2382,8 @@
* generic/tclPosixStr.c: [Bug 3388350]: mingw64 compiler warnings
* win/tclWinPort.h:
- * win/configure.in
- * win/configure
+ * win/configure.in:
+ * win/configure:
2011-08-14 Jan Nijtmans <nijtmans@users.sf.net>
@@ -53,9 +2421,9 @@
2011-08-09 Jan Nijtmans <nijtmans@users.sf.net>
* win/tclWinConsole.c: [Bug 3388350]: mingw64 compiler warnings
- * win/tclWinDde.c
- * win/tclWinPipe.c
- * win/tclWinSerial.c
+ * win/tclWinDde.c:
+ * win/tclWinPipe.c:
+ * win/tclWinSerial.c:
2011-08-09 Jan Nijtmans <nijtmans@users.sf.net>
@@ -116,7 +2484,7 @@
* generic/tclIOSock.c (TclCreateSocketAddress): Don't bother using
AI_ADDRCONFIG for now, as it was causing problems in various
situations.
-
+
2011-08-04 Donal K. Fellows <dkf@users.sf.net>
* generic/tclAssembly.c (AssembleOneLine, GetBooleanOperand)
@@ -236,12 +2604,12 @@
2011-07-15 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCompile.c: Avoid segfaults when RecordByteCodeStats()
- is called in a deleted interp.
+ * generic/tclCompile.c: Avoid segfaults when RecordByteCodeStats() is
+ called in a deleted interp.
- * generic/tclCompile.c: [Bug 467523, 3357771]: Prevent circular
- references in values with ByteCode intreps. They can lead to
- memory leaks.
+ * generic/tclCompile.c: [Bug 467523, 3357771]: Prevent circular
+ references in values with ByteCode intreps. They can lead to memory
+ leaks.
2011-07-14 Donal K. Fellows <dkf@users.sf.net>
@@ -283,19 +2651,19 @@
* unix/Makefile.in:
* win/Makefile.in:
* win/Makefile.vc:
- Fix a bug where bignum->double conversion is "round up" and
- not "round to nearest" (causing expr double(1[string repeat 0 23])
- not to be 1e+23). [Bug 3349507]
+ [Bug 3349507]: Fix a bug where bignum->double conversion is "round up"
+ and not "round to nearest" (causing expr double(1[string repeat 0 23])
+ not to be 1e+23).
2011-06-28 Reinhard Max <max@suse.de>
- * unix/tclUnixSock.c (CreateClientSocket): Fix and simplify
- posting of the writable fileevent at the end of an asynchronous
- connection attempt. Improve comments for some of the trickery
- around [socket -async]. [Bug 3325339]
+ * unix/tclUnixSock.c (CreateClientSocket): [Bug 3325339]: Fix and
+ simplify posting of the writable fileevent at the end of an
+ asynchronous connection attempt. Improve comments for some of the
+ trickery around [socket -async].
- * tests/socket.test: Adjust tests to the async code changes. Add
- more tests for corner cases of async sockets.
+ * tests/socket.test: Adjust tests to the async code changes. Add more
+ tests for corner cases of async sockets.
2011-06-22 Andreas Kupries <andreask@activestate.com>
@@ -305,33 +2673,34 @@
* win/Makefile.in:
* generic/tclInt.h: Fixed the inadvertently committed disabling of
- stack checks, see my 2010-11-15 commit.
+ stack checks, see my 2010-11-15 commit.
2011-06-22 Reinhard Max <max@suse.de>
Merge from rmax-ipv6-branch:
* unix/tclUnixSock.c: Fix [socket -async], so that all addresses
returned by getaddrinfo() are tried, not just the first one. This
- requires the event loop to be running while the async connection
- is in progress. ***POTENTIAL INCOMPATIBILITY***
+ requires the event loop to be running while the async connection is in
+ progress. ***POTENTIAL INCOMPATIBILITY***
* tests/socket.test: Add a test for the above.
* doc/socket: Document the fact that -async needs the event loop
* generic/tclIOSock.c: AI_ADDRCONFIG is broken on HP-UX
2011-06-21 Don Porter <dgp@users.sourceforge.net>
- * generic/tclLink.c: Prevent multiple links to a single Tcl
- variable when calling Tcl_LinkVar(). [Bug 3317466]
+ * generic/tclLink.c: [Bug 3317466]: Prevent multiple links to a
+ single Tcl variable when calling Tcl_LinkVar().
2011-06-13 Don Porter <dgp@users.sourceforge.net>
- * generic/tclStrToD.c: [Bug 3315098] Mem leak fix from Gustaf Neumann.
+ * generic/tclStrToD.c: [Bug 3315098]: Mem leak fix from Gustaf
+ Neumann.
2011-06-08 Andreas Kupries <andreask@activestate.com>
- * generic/tclExecute.c: Reverted the fix for [Bug 3274728]
- committed on 2011-04-06 and replaced with one which is
- 64bit-safe. The existing fix crashed tclsh on Windows 64bit.
+ * generic/tclExecute.c: Reverted the fix for [Bug 3274728] committed
+ on 2011-04-06 and replaced with one which is 64bit-safe. The existing
+ fix crashed tclsh on Windows 64bit.
2011-06-08 Donal K. Fellows <dkf@users.sf.net>
@@ -348,8 +2717,8 @@
2011-06-02 Don Porter <dgp@users.sourceforge.net>
* generic/tclBasic.c: Removed TclCleanupLiteralTable(), and old
- * generic/tclInt.h: band-aid routine put in place while a fix
- * generic/tclLiteral.c: for [Bug 994838] took shape. No longer needed.
+ * generic/tclInt.h: band-aid routine put in place while a fix for
+ * generic/tclLiteral.c: [Bug 994838] took shape. No longer needed.
2011-06-02 Donal K. Fellows <dkf@users.sf.net>
@@ -365,23 +2734,23 @@
2011-06-01 Jan Nijtmans <nijtmans@users.sf.net>
- * generic/tclUtil.c: Fix for [Bug 3309871]: Valgrind finds:
- invalid read in TclMaxListLength()
+ * generic/tclUtil.c: Fix for [Bug 3309871]: Valgrind finds: invalid
+ read in TclMaxListLength().
2011-05-31 Don Porter <dgp@users.sourceforge.net>
- * generic/tclInt.h: Use a complete growth algorithm for lists
- * generic/tclListObj.c: so that length limits do not overconstrain
- * generic/tclStringObj.c: by a factor of 2. [Bug 3293874]:
- * generic/tclUtil.c: Fix includes rooting all growth routines
- by default on a commone tunable parameter TCL_MIN_GROWTH.
+ * generic/tclInt.h: Use a complete growth algorithm for lists so
+ * generic/tclListObj.c: that length limits do not overconstrain by a
+ * generic/tclStringObj.c: factor of 2. [Bug 3293874]: Fix includes
+ * generic/tclUtil.c: rooting all growth routines by default on a
+ common tunable parameter TCL_MIN_GROWTH.
2011-05-25 Don Porter <dgp@users.sourceforge.net>
* library/msgcat/msgcat.tcl: Bump to msgcat 1.4.4.
* library/msgcat/pkgIndex.tcl:
- * unix/Makefile.in
- * win/Makefile.in
+ * unix/Makefile.in:
+ * win/Makefile.in:
2011-05-25 Donal K. Fellows <dkf@users.sf.net>
@@ -407,27 +2776,26 @@
2011-05-17 Andreas Kupries <andreask@activestate.com>
* generic/tclCompile.c (TclFixupForwardJump): Tracked down and fixed
- * generic/tclBasic.c (TclArgumentBCEnter): the cause of a violation
- of my assertion that 'ePtr->nline == objc' in TclArgumentBCEnter.
- When a bytecode was grown during jump fixup the pc -> command line
- mapping was not updated. When things aligned just wrong the mapping
- would direct command A to the data for command B, with a different
- number of arguments.
+ * generic/tclBasic.c (TclArgumentBCEnter): the cause of a violation of
+ my assertion that 'ePtr->nline == objc' in TclArgumentBCEnter. When a
+ bytecode was grown during jump fixup the pc -> command line mapping
+ was not updated. When things aligned just wrong the mapping would
+ direct command A to the data for command B, with a different number of
+ arguments.
2011-05-11 Reinhard Max <max@suse.de>
* unix/tclUnixSock.c (TcpWatchProc): No need to check for server
- sockets here, as the generic server code already takes care of
- that.
- * tests/socket.test (accept): Add tests to make sure that this
- remains so.
+ sockets here, as the generic server code already takes care of that.
+ * tests/socket.test (accept): Add tests to make sure that this remains
+ so.
2011-05-10 Don Porter <dgp@users.sourceforge.net>
* generic/tclInt.h: New internal routines TclScanElement() and
* generic/tclUtil.c: TclConvertElement() are rewritten guts of
- machinery to produce string rep of lists. The new routines avoid
- and correct [Bug 3173086]. See comments for much more detail.
+ machinery to produce string rep of lists. The new routines avoid and
+ correct [Bug 3173086]. See comments for much more detail.
* generic/tclDictObj.c: Update all callers.
* generic/tclIndexObj.c:
@@ -454,8 +2822,8 @@
2011-05-07 Miguel Sofer <msofer@users.sf.net>
- * generic/tclInt.h: fix USE_TCLALLOC so that it can be enabled
- * unix/Makefile.in: without editing the Makefile
+ * generic/tclInt.h: Fix USE_TCLALLOC so that it can be enabled without
+ * unix/Makefile.in: editing the Makefile.
2011-05-05 Don Porter <dgp@users.sourceforge.net>
@@ -472,21 +2840,21 @@
2011-05-02 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCmdMZ.c: Revised TclFindElement() interface. The
- * generic/tclDictObj.c: final argument had been bracePtr, the address
- * generic/tclListObj.c: of a boolean var, where the caller can be told
+ * generic/tclCmdMZ.c: Revised TclFindElement() interface. The final
+ * generic/tclDictObj.c: argument had been bracePtr, the address of a
+ * generic/tclListObj.c: boolean var, where the caller can be told
* generic/tclParse.c: whether or not the parsed list element was
* generic/tclUtil.c: enclosed in braces. In practice, no callers
really care about that. What the callers really want to know is
whether the list element value exists as a literal substring of the
string being parsed, or whether a call to TclCopyAndCollpase() is
- needed to produce the list element value. Now the final argument
- is changed to do what callers actually need. This is a better fit
- for the calls in tclParse.c, where now a good deal of post-processing
- checking for "naked backslashes" is no longer necessary.
+ needed to produce the list element value. Now the final argument is
+ changed to do what callers actually need. This is a better fit for the
+ calls in tclParse.c, where now a good deal of post-processing checking
+ for "naked backslashes" is no longer necessary.
***POTENTIAL INCOMPATIBILITY***
- For any callers calling in via the internal stubs table who really
- do use the final argument explicitly to check for the enclosing brace
+ For any callers calling in via the internal stubs table who really do
+ use the final argument explicitly to check for the enclosing brace
scenario. Simply looking for the braces where they must be is the
revision available to those callers, and it will backport cleanly.
@@ -501,17 +2869,17 @@
* generic/tclCompCmdsSZ.c:
* generic/tclCompCmdsSZ.c: Rewrite of parts of the switch compiler to
- better use the powers of TclFindElement() and do less parsing on
- its own.
+ better use the powers of TclFindElement() and do less parsing on its
+ own.
2011-04-28 Don Porter <dgp@users.sourceforge.net>
* generic/tclInt.h: New utility routines:
- * generic/tclParse.c: TclIsSpaceProc() and
- * generic/tclUtil.c: TclCountSpaceRuns()
+ * generic/tclParse.c: TclIsSpaceProc() and TclCountSpaceRuns()
+ * generic/tclUtil.c:
- * generic/tclCmdMZ.c: Use new routines to replace calls to
- * generic/tclListObj.c: isspace() and their /* INTL */ risk.
+ * generic/tclCmdMZ.c: Use new routines to replace calls to isspace()
+ * generic/tclListObj.c: and their /* INTL */ risk.
* generic/tclStrToD.c:
* generic/tclUtf.c:
* unix/tclUnixFile.c:
@@ -570,8 +2938,8 @@
* generic/tclConfig.c:
* generic/tclListObj.c:
- * generic/tclInt.h: Define and use macros that test whether
- * generic/tclBasic.c: a Tcl list value is canonical.
+ * generic/tclInt.h: Define and use macros that test whether a Tcl
+ * generic/tclBasic.c: list value is canonical.
* generic/tclUtil.c:
2011-04-18 Donal K. Fellows <dkf@users.sf.net>
@@ -681,10 +3049,10 @@
2011-04-04 Don Porter <dgp@users.sourceforge.net>
- * README: Updated README files, repairing broken URLs and
- * macosx/README: removing other bits that were clearly wrong.
+ * README: [Bug 3202030]: Updated README files, repairing broken
+ * macosx/README:URLs and removing other bits that were clearly wrong.
* unix/README: Still could use more eyeballs on the detailed build
- * win/README: advice on various plaforms. [Bug 3202030]
+ * win/README: advice on various plaforms.
2011-04-04 Donal K. Fellows <dkf@users.sf.net>
@@ -741,8 +3109,7 @@
2011-03-28 Donal K. Fellows <dkf@users.sf.net>
* generic/tclCmdMZ.c, generic/tclConfig.c, generic/tclUtil.c: More
- generation of errorCode information, notably when lists are
- mis-parsed.
+ generation of errorCode information, notably when lists are mis-parsed
* generic/tclCmdMZ.c (Tcl_RegexpObjCmd, Tcl_RegsubObjCmd): Use the
error messages generated by the variable management code rather than
@@ -750,11 +3117,11 @@
2011-03-27 Miguel Sofer <msofer@users.sf.net>
- * generic/tclBasic.c (TclNREvalObjEx): fix performance issue,
- notably apparent in tclbench's "LIST lset foreach". Many thanks to
- twylite for patiently researching the issue and explaining it to
- me: a missing Tcl_ResetObjResult that causes unwanted sharing of
- the current result Tcl_Obj.
+ * generic/tclBasic.c (TclNREvalObjEx): fix performance issue, notably
+ apparent in tclbench's "LIST lset foreach". Many thanks to Twylite for
+ patiently researching the issue and explaining it to me: a missing
+ Tcl_ResetObjResult that causes unwanted sharing of the current result
+ Tcl_Obj.
2011-03-26 Donal K. Fellows <dkf@users.sf.net>
@@ -789,8 +3156,12 @@
2011-03-21 Jan Nijtmans <nijtmans@users.sf.net>
- * unix/tclLoadDl.c: [Bug #3216070]: Loading extension libraries
+ * unix/tclLoadDl.c: [Bug 3216070]: Loading extension libraries
* unix/tclLoadDyld.c: from embedded Tcl applications.
+ ***POTENTIAL INCOMPATIBILITY***
+ For extensions which rely on symbols from other extensions being
+ present in the global symbol table. For an example and some discussion
+ of workarounds, see http://stackoverflow.com/q/8330614/301832
2011-03-21 Miguel Sofer <msofer@users.sf.net>
@@ -822,8 +3193,8 @@
2011-03-16 Don Porter <dgp@users.sourceforge.net>
- * generic/tclBasic.c: Some rewrites to eliminate calls to
- * generic/tclParse.c: isspace() and their /* INTL */ risk.
+ * generic/tclBasic.c: Some rewrites to eliminate calls to isspace()
+ * generic/tclParse.c: and their /* INTL */ risk.
* generic/tclProc.c:
2011-03-16 Jan Nijtmans <nijtmans@users.sf.net>
@@ -908,10 +3279,10 @@
2011-03-09 Don Porter <dgp@users.sourceforge.net>
- * generic/tclNamesp.c: Tighten the detector of nested [namespace code]
- * tests/namespace.test: quoting that the quoted scripts function
- properly even in a namespace that contains a custom "namespace"
- command. [Bug 3202171]
+ * generic/tclNamesp.c: [Bug 3202171]: Tighten the detector of nested
+ * tests/namespace.test: [namespace code] quoting that the quoted
+ scripts function properly even in a namespace that contains a custom
+ "namespace" command.
* doc/tclvars.n: Formatting fix. Thanks to Pat Thotys.
@@ -934,8 +3305,8 @@
* generic/tclInt.h: Remove TclMarkList() routine, an experimental
* generic/tclUtil.c: dead-end from the 8.5 alpha days.
- * generic/tclResult.c (ResetObjResult): Correct failure to clear
- invalid intrep. Thanks to Colin McDonald. [Bug 3202905]
+ * generic/tclResult.c (ResetObjResult): [Bug 3202905]: Correct failure
+ to clear invalid intrep. Thanks to Colin McDonald.
2011-03-08 Donal K. Fellows <dkf@users.sf.net>
@@ -950,13 +3321,13 @@
* generic/tclParse.c:
* generic/tclUtil.c:
- * generic/tclUtil.c (TclFindElement): Guard escape sequence scans
- to not overrun the string end. [Bug 3192636]
+ * generic/tclUtil.c (TclFindElement): [Bug 3192636]: Guard escape
+ sequence scans to not overrun the string end.
2011-03-05 Don Porter <dgp@users.sourceforge.net>
- * generic/tclParse.c (TclParseBackslash): Correct trunction checks in
- * tests/parse.test: \x and \u substitutions. [Bug 3200987]
+ * generic/tclParse.c (TclParseBackslash): [Bug 3200987]: Correct
+ * tests/parse.test: trunction checks in \x and \u substitutions.
2011-03-05 Miguel Sofer <msofer@users.sf.net>
@@ -972,20 +3343,20 @@
* tests/assemble.test (new file):
* unix/Makefile.in:
* win/Makefile.in:
- * win/makefile.vc: Merged dogeen-assembler-branch into HEAD.
- Since all functional changes are in the tcl::unsupported namespace,
- there's no reason to sequester this code on a separate branch.
+ * win/makefile.vc: Merged dogeen-assembler-branch into HEAD. Since
+ all functional changes are in the tcl::unsupported namespace, there's
+ no reason to sequester this code on a separate branch.
2011-03-05 Miguel Sofer <msofer@users.sf.net>
- * generic/tclExecute.c: cleaner mem management for TEBCdata
+ * generic/tclExecute.c: Cleaner mem management for TEBCdata
* generic/tclExecute.c:
* tests/nre.test: Renamed BottomData to TEBCdata, so that the name
refers to what it is rather than to its storage location.
- * generic/tclBasic.c: Renamed struct TEOV_callback to
- * generic/tclCompExpr.c: the more descriptive NRE_callback.
+ * generic/tclBasic.c: Renamed struct TEOV_callback to the more
+ * generic/tclCompExpr.c: descriptive NRE_callback.
* generic/tclCompile.c:
* generic/tclExecute.c:
* generic/tclInt.decls:
@@ -1002,9 +3373,9 @@
2011-03-01 Miguel Sofer <msofer@users.sf.net>
- * generic/tclBasic.c (TclNREvalObjv): missing a variable
- declaration in commented out non-optimised code, left for ref in
- checkin [b97b771b6d]
+ * generic/tclBasic.c (TclNREvalObjv): Missing a variable declaration
+ in commented out non-optimised code, left for ref in checkin
+ [b97b771b6d]
2011-03-03 Don Porter <dgp@users.sourceforge.net>
@@ -1029,17 +3400,17 @@
* generic/tclStubInit.c:
* win/makefile.vc:
- * generic/tclExecute.c (ExprObjCallback): fix object leak
+ * generic/tclExecute.c (ExprObjCallback): Fix object leak
- * generic/tclExecute.c (TEBCresume): store local var array and
+ * generic/tclExecute.c (TEBCresume): Store local var array and
constants in automatic vars to reduce indirection, slight perf
increase
- * generic/tclOOCall.c (TclOODeleteContext): added missing '*' so
- that trunk compiles.
+ * generic/tclOOCall.c (TclOODeleteContext): Added missing '*' so that
+ trunk compiles.
- * generic/tclBasic.c (TclNRRunCallbacks): don't do the trampoline
- dance for commands that do not have an nreProc, [Patch 3168229]
+ * generic/tclBasic.c (TclNRRunCallbacks): [Patch 3168229]: Don't do
+ the trampoline dance for commands that do not have an nreProc.
2011-03-01 Donal K. Fellows <dkf@users.sf.net>
@@ -1059,23 +3430,23 @@
* generic/tclPreserve.c: Don't miss 64-bit address bits in panic
message.
- * win/tclWinChan.c: Fix various gcc-4.5.2 64-bit warning messages
- * win/tclWinConsole.c e.g. by using full 64-bits for socket fd's
- * win/tclWinDde.c
- * win/tclWinPipe.c
- * win/tclWinReg.c
- * win/tclWinSerial.c
- * win/tclWinSock.c
- * win/tclWinThrd.c
+ * win/tclWinChan.c: Fix various gcc-4.5.2 64-bit warning
+ * win/tclWinConsole.c: messages, e.g. by using full 64-bits for
+ * win/tclWinDde.c: socket fd's
+ * win/tclWinPipe.c:
+ * win/tclWinReg.c:
+ * win/tclWinSerial.c:
+ * win/tclWinSock.c:
+ * win/tclWinThrd.c:
2011-01-19 Jan Nijtmans <nijtmans@users.sf.net>
- * tools/genStubs.tcl: [Enh #3159920]: Tcl_ObjPrintf() crashes with
+ * tools/genStubs.tcl: [FRQ 3159920]: Tcl_ObjPrintf() crashes with
* generic/tcl.decls bad format specifier.
- * generic/tcl.h
- * generic/tclDecls.h
+ * generic/tcl.h:
+ * generic/tclDecls.h:
-2011-01-18 Donal K. Fellows <dkf@users.sf.net>3159920
+2011-01-18 Donal K. Fellows <dkf@users.sf.net>
* generic/tclOOMethod.c (PushMethodCallFrame): [Bug 3001438]: Make
sure that the cmdPtr field of the procPtr is correct and relevant at
@@ -1088,10 +3459,10 @@
* generic/tclBasic.c: Various mismatches between Tcl_Panic
* generic/tclCompCmds.c: format string and its arguments,
* generic/tclCompCmdsSZ.c: discovered thanks to [Bug 3159920]
- * generic/tclCompExpr.c
- * generic/tclEnsemble.c
- * generic/tclPreserve.c
- * generic/tclTest.c
+ * generic/tclCompExpr.c:
+ * generic/tclEnsemble.c:
+ * generic/tclPreserve.c:
+ * generic/tclTest.c:
2011-01-17 Jan Nijtmans <nijtmans@users.sf.net>
@@ -1124,10 +3495,9 @@
2011-01-07 Kevin B. Kenny <kennykb@acm.org>
* tests/util.test (util-15.*): Added test cases for floating point
- conversion of the largest denormal and the smallest normal number,
- to avoid any possibility of the failure suffered by PHP in the
- last couple of days. (They didn't fail, so no actual functional
- change.)
+ conversion of the largest denormal and the smallest normal number, to
+ avoid any possibility of the failure suffered by PHP in the last
+ couple of days. (They didn't fail, so no actual functional change.)
2011-01-05 Donal K. Fellows <dkf@users.sf.net>
@@ -1234,8 +3604,7 @@
2010-12-14 Jan Nijtmans <nijtmans@users.sf.net>
- * generic/tcl.h: [Bug 3137454]: Tcl CVS HEAD does not build
- on GCC 3.
+ * generic/tcl.h: [Bug 3137454]: Tcl CVS HEAD does not build on GCC 3.
2010-12-14 Reinhard Max <max@suse.de>
@@ -1250,8 +3619,8 @@
* generic/tcl.h: [Bug 3135271]: Link error due to hidden
* unix/tcl.m4: symbols (CentOS 4.2)
* unix/configure: (autoconf-2.59)
- * win/tclWinFile.c: Undocumented feature, only meant to be
- used by Tk_Main. See [Patch 3124554]: Move WishPanic from Tk to Tcl
+ * win/tclWinFile.c: Undocumented feature, only meant to be used by
+ Tk_Main. See [Patch 3124554]: Move WishPanic from Tk to Tcl
2010-12-12 Stuart Cassoff <stwo@users.sourceforge.net>
@@ -1336,7 +3705,7 @@
* generic/tclBinary.c: [Bug 3129448]: Possible over-allocation on
* generic/tclCkalloc.c: 64-bit platforms.
- * generic/tclTrace.c
+ * generic/tclTrace.c:
2010-12-05 Jan Nijtmans <nijtmans@users.sf.net>
@@ -1472,8 +3841,8 @@
* win/cat.c: to reality. See for what's missing:
* win/tcl.m4: <https://sourceforge.net/apps/trac/mingw-w64/wiki/Unicode%20apps>
* win/configure: (re-generated)
- * win/tclWinPort.h:[Bug #3110161]: Extensions using TCHAR don't compile
- on VS2005 SP1
+ * win/tclWinPort.h: [Bug 3110161]: Extensions using TCHAR don't
+ compile on VS2005 SP1
2010-11-15 Andreas Kupries <andreask@activestate.com>
@@ -1624,9 +3993,9 @@
[dogeen-assembler-branch]
* generic/tclAssembly.c:
- * tests/assembly.test (assemble-17.15): Reworked branch handling so that
- forward branches can use jump1 (jumpTrue1, jumpFalse1). Added test
- cases that the forward branches will expand to jump4, jumpTrue4,
+ * tests/assembly.test (assemble-17.15): Reworked branch handling so
+ that forward branches can use jump1 (jumpTrue1, jumpFalse1). Added
+ test cases that the forward branches will expand to jump4, jumpTrue4,
jumpFalse4 when needed.
2010-10-23 Kevin B. Kenny <kennykb@acm.org>
@@ -1731,7 +4100,8 @@
* win/tclWinReg.c:
* win/tclWinTest.c: More cleanups
* win/tclWinFile.c: Add netapi32 to the link line, so we no longer
- * win/tcl.m4: have to use LoadLibrary to access those functions.
+ * win/tcl.m4: have to use LoadLibrary to access those
+ functions.
* win/makefile.vc:
* win/configure: (Re-generate with autoconf-2.59)
* win/rules.vc Update for VS10
@@ -1995,7 +4365,7 @@
[BRANCH: dogeen-assembler-branch]
- * generic/tclAssembly.c (new file):
+ * generic/tclAssembly.c (new file):
* generic/tclAssembly.h:
* generic/tclBasic.c (builtInCmds, Tcl_CreateInterp):
* generic/tclInt.h:
@@ -2281,6 +4651,7 @@
* generic/*Decls.h: (regenerated)
2010-08-18 Miguel Sofer <msofer@users.sf.net>
+
* generic/tclBasic.c: New redesign of [tailcall]: find
* generic/tclExecute.c: errors early on, so that errorInfo
* generic/tclInt.h: contains the proper info [Bug 3047235]
@@ -2452,8 +4823,8 @@
2010-07-02 Jan Nijtmans <nijtmans@users.sf.net>
- * generic/tclInt.decls: [Bug 803489]: Tcl_FindNamespace problem in the
- * generic/tclIntDecls.h: Stubs table
+ * generic/tclInt.decls: [Bug 803489]: Tcl_FindNamespace problem in
+ * generic/tclIntDecls.h: the Stubs table
* generic/tclStubInit.c:
2010-07-02 Donal K. Fellows <dkf@users.sf.net>
@@ -2651,8 +5022,7 @@
2010-05-19 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
* tests/dict.test: Add missing tests for [Bug 3004007], fixed under
- the radar on 2010-02-24 (dkf): EIAS violation in
- list-dict conversions.
+ the radar on 2010-02-24 (dkf): EIAS violation in list-dict conversions
2010-05-19 Jan Nijtmans <nijtmans@users.sf.net>
@@ -3840,8 +6210,8 @@
2010-01-21 Miguel Sofer <msofer@users.sf.net>
- * generic/tclCompile.h: NRE-enable direct eval on BC spoilage
- * generic/tclExecute.c: [Bug 2910748]
+ * generic/tclCompile.h: [Bug 2910748]: NRE-enable direct eval on BC
+ * generic/tclExecute.c: spoilage.
* tests/nre.test:
2010-01-19 Donal K. Fellows <dkf@users.sf.net>
@@ -4506,10 +6876,9 @@
2009-11-11 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
- * generic/tclIO.c: Fix [Bug 2888099] (close discards ENOSPC error)
- by saving the errno from the first of two
- FlushChannel()s. Uneasy to test; might need
- specific channel drivers. Four-hands with aku.
+ * generic/tclIO.c: Fix [Bug 2888099] (close discards ENOSPC error) by
+ saving the errno from the first of two FlushChannel()s. Uneasy to
+ test; might need specific channel drivers. Four-hands with aku.
2009-11-10 Pat Thoyts <patthoyts@users.sourceforge.net>
@@ -4654,10 +7023,11 @@
For 32-bit builds where "long" and "int" are two names for the same
thing, this is no change at all. For 64-bit builds, though, this
causes the dp[] array of an mp_int to be made up of 32-bit elements
- instead of 64-bit elements. This is a huge improvement because details
- elsewhere in the mp_int implementation cause only 28 bits of each
- element to be actually used storing number data. Without this change
- bignums are over 50% wasted space on 64-bit systems. [Bug 2800740].
+ instead of 64-bit elements. This is a huge improvement because
+ details elsewhere in the mp_int implementation cause only 28 bits of
+ each element to be actually used storing number data. Without this
+ change bignums are over 50% wasted space on 64-bit systems. [Bug
+ 2800740].
***POTENTIAL INCOMPATIBILITY***
For 64-bit builds, callers of routines with (mp_digit) or (mp_digit *)
@@ -4783,10 +7153,10 @@
2009-10-18 Joe Mistachkin <joe@mistachkin.com>
* tests/thread.test (thread-4.[345]): [Bug 1565466]: Correct tests to
- save their error state before the final call to threadReap just in case
- it triggers an "invalid thread id" error. This error can occur if one
- or more of the target threads has exited prior to the attempt to send
- it an asynchronous exit command.
+ save their error state before the final call to threadReap just in
+ case it triggers an "invalid thread id" error. This error can occur
+ if one or more of the target threads has exited prior to the attempt
+ to send it an asynchronous exit command.
2009-10-17 Donal K. Fellows <dkf@users.sf.net>
@@ -4829,14 +7199,15 @@
2009-10-05 Andreas Kupries <andreask@activestate.com>
* library/safe.tcl (AliasGlob): Fixed conversion of catch to
- try/finally, it had an 'on ok msg' branch missing, causing a
- silent error immediately, and bogus glob results, breaking
- search for Tcl modules.
+ try/finally, it had an 'on ok msg' branch missing, causing a silent
+ error immediately, and bogus glob results, breaking search for Tcl
+ modules.
2009-10-04 Daniel Steffen <das@users.sourceforge.net>
- * macosx/tclMacOSXBundle.c: Workaround CF memory managment bug in
- * unix/tclUnixInit.c: Mac OS X 10.4 & earlier. [Bug 2569449]
+ * macosx/tclMacOSXBundle.c: [Bug 2569449]: Workaround CF memory
+ * unix/tclUnixInit.c: managment bug in Mac OS X 10.4 &
+ earlier.
2009-10-02 Kevin B. Kenny <kennykb@acm.org>
@@ -5623,9 +7994,9 @@
* unix/tclUnixChan.c: TclUnixWaitForFile(): use FD_* macros
* macosx/tclMacOSXNotify.c: to manipulate select masks (Cassoff).
- [Bug 1960647]
+ [FRQ 1960647] [Bug 3486554]
- * unix/tclLoadDyld.c: use RTLD_GLOBAL instead of RTLD_LOCAL.
+ * unix/tclLoadDyld.c: Use RTLD_GLOBAL instead of RTLD_LOCAL.
[Bug 1961211]
* macosx/tclMacOSXNotify.c: revise CoreFoundation notifier to allow
@@ -5821,9 +8192,8 @@
2009-03-15 Joe Mistachkin <joe@mistachkin.com>
- * generic/tclThread.c: Modify fix for TSD leak to match Tcl 8.5
- * generic/tclThreadStorage.c: (and prior) allocation semantics. [Bug
- 2687952]
+ * generic/tclThread.c: [Bug 2687952]: Modify fix for TSD leak to match
+ * generic/tclThreadStorage.c: Tcl 8.5 (and prior) allocation semantics
2009-03-15 Donal K. Fellows <dkf@users.sf.net>
@@ -5911,10 +8281,10 @@
2009-02-20 Don Porter <dgp@users.sourceforge.net>
- * generic/tclPathObj.c: Fixed mistaken logic in TclFSGetPathType()
- * tests/fileName.test: that assumed (not "absolute" => "relative").
- This is a false assumption on Windows, where "volumerelative" is
- another possibility. [Bug 2571597]
+ * generic/tclPathObj.c: [Bug 2571597]: Fixed mistaken logic in
+ * tests/fileName.test: TclFSGetPathType() that assumed (not
+ "absolute") => "relative". This is a false assumption on Windows,
+ where "volumerelative" is another possibility.
2009-02-18 Don Porter <dgp@users.sourceforge.net>
@@ -5968,23 +8338,23 @@
2009-02-16 Jan Nijtmans <nijtmans@users.sf.net>
- * generic/tclZlib.c: hack needed for official zlib1.dll build.
+ * generic/tclZlib.c: Hack needed for official zlib1.dll build.
* win/configure.in: fix [Feature Request 2605263] use official
* win/Makefile.in: zlib build.
* win/configure: (regenerated)
* compat/zlib/zdll.lib: new files
* compat/zlib/zlib1.dll:
- * win/Makefile.in: fix [Bug 2605232] tdbc doesn't build when
- Tcl is compiled with --disable-shared.
+ * win/Makefile.in: [Bug 2605232]: tdbc doesn't build when Tcl is
+ compiled with --disable-shared.
2009-02-15 Don Porter <dgp@users.sourceforge.net>
- * generic/tclStringObj.c: Added protections from invalid memory
- * generic/tclTestObj.c: accesses when we append (some part of)
- * tests/stringObj.test: a Tcl_Obj to itself. Added the
- appendself and appendself2 subcommands to the [teststringobj] testing
- command and added tests to the test suite. [Bug 2603158]
+ * generic/tclStringObj.c: [Bug 2603158]: Added protections from
+ * generic/tclTestObj.c: invalid memory accesses when we append
+ * tests/stringObj.test: (some part of) a Tcl_Obj to itself.
+ Added the appendself and appendself2 subcommands to the
+ [teststringobj] testing command and added tests to the test suite.
* generic/tclStringObj.c: Factor out duplicate code from
Tcl_AppendObjToObj.
@@ -6120,7 +8490,7 @@
2009-02-09 Jan Nijtmans <nijtmans@users.sf.net>
- * generic/tclCompile.c: fix [Bug 2555129] const compiler warning (as
+ * generic/tclCompile.c: [Bug 2555129]: const compiler warning (as
error) in tclCompile.c
2009-02-07 Donal K. Fellows <dkf@users.sf.net>
@@ -6132,8 +8502,8 @@
2009-02-05 Joe Mistachkin <joe@mistachkin.com>
- * generic/tclInterp.c: Fix argument checking for [interp cancel]. [Bug
- 2544618]
+ * generic/tclInterp.c: [Bug 2544618]: Fix argument checking for
+ [interp cancel].
* unix/Makefile.in: Fix build issue with zlib on FreeBSD (and possibly
other platforms).
@@ -6155,12 +8525,12 @@
2009-02-04 Don Porter <dgp@users.sourceforge.net>
- * generic/tclStringObj.c: Added overflow protections to the
- AppendUtfToUtfRep routine to either avoid invalid arguments and
- crashes, or to replace them with controlled panics. [Bug 2561794]
+ * generic/tclStringObj.c: [Bug 2561794]: Added overflow protections to
+ the AppendUtfToUtfRep routine to either avoid invalid arguments and
+ crashes, or to replace them with controlled panics.
- * generic/tclCmdMZ.c: Prevent crashes due to int overflow of the
- length of the result of [string repeat]. [Bug 2561746]
+ * generic/tclCmdMZ.c: [Bug 2561746]: Prevent crashes due to int
+ overflow of the length of the result of [string repeat].
2009-02-03 Jan Nijtmans <nijtmans@users.sf.net>
@@ -6192,9 +8562,9 @@
2009-02-03 Don Porter <dgp@users.sourceforge.net>
- * generic/tclStringObj.c (SetUnicodeObj): Corrected failure of
- Tcl_SetUnicodeObj() to panic on a shared object. [Bug 2561488]. Also
- factored out common code to reduce duplication.
+ * generic/tclStringObj.c (SetUnicodeObj): [Bug 2561488]:
+ Corrected failure of Tcl_SetUnicodeObj() to panic on a shared object.
+ Also factored out common code to reduce duplication.
* generic/tclObj.c (Tcl_GetStringFromObj): Reduce code duplication.
@@ -6269,19 +8639,19 @@
2009-01-26 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
- * generic/tclInt.h: Fix [Bug 1028264]: WSACleanup() too early.
- * generic/tclEvent.c: The fix introduces "late exit handlers"
- * win/tclWinSock.c: for similar late process-wide cleanups.
+ * generic/tclInt.h: [Bug 1028264]: WSACleanup() too early.
+ * generic/tclEvent.c: The fix introduces "late exit handlers" for
+ * win/tclWinSock.c: similar late process-wide cleanups.
2009-01-26 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
- * win/tclWinSock.c: Fix [Bug 2446662]: resync Win behavior on RST
- with that of unix (EOF).
+ * win/tclWinSock.c: [Bug 2446662]: Resync Win behavior on RST with
+ that of unix (EOF).
2009-01-26 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclZlib.c (ChanClose): Only generate error messages in the
- interpreter when the thread is not being closed down. [Bug 2536400]
+ * generic/tclZlib.c (ChanClose): [Bug 2536400]: Only generate error
+ messages in the interpreter when the thread is not being closed down.
2009-01-23 Donal K. Fellows <dkf@users.sf.net>
@@ -6308,7 +8678,7 @@
2009-01-21 Andreas Kupries <andreask@activestate.com>
- * generic/tclIORChan.c (ReflectClose): Fix for [Bug 2458202].
+ * generic/tclIORChan.c (ReflectClose): [Bug 2458202]:
* generic/tclIORTrans.c (ReflectClose): Closing a channel may supply
NULL for the 'interp'. Test for finalization needs to be different,
and one place has to pull the interp out of the channel instead.
@@ -6320,12 +8690,12 @@
2009-01-19 Kevin B. Kenny <kennykb@acm.org>
- * unix/Makefile.in: Added a CONFIG_INSTALL_DIR parameter so that
- * unix/tcl.m4: distributors can control where tclConfig.sh goes.
- Made the installation of 'ldAix' conditional upon actually being on an
- AIX system. Allowed for downstream packagers to customize
- SHLIB_VERSION on BSD-derived systems. Thanks to Stuart Cassoff for
- [Patch 907924].
+ * unix/Makefile.in: [Patch 907924]:Added a CONFIG_INSTALL_DIR
+ * unix/tcl.m4: parameter so that distributors can control where
+ tclConfig.sh goes. Made the installation of 'ldAix' conditional upon
+ actually being on an AIX system. Allowed for downstream packagers to
+ customize SHLIB_VERSION on BSD-derived systems. Thanks to Stuart
+ Cassoff for his help.
* unix/configure: Autoconf 2.59
2009-01-19 David Gravereaux <davygrvy@pobox.com>
@@ -6362,8 +8732,8 @@
2009-01-13 Jan Nijtmans <nijtmans@users.sf.net>
- * unix/tcl.m4: fix [tcl-Bug 2502365] Building of head on HPUX is
- broken when using the native CC.
+ * unix/tcl.m4: [Bug 2502365]: Building of head on HPUX is broken when
+ using the native CC.
* unix/configure (autoconf-2.59)
2009-01-13 Donal K. Fellows <dkf@users.sf.net>
@@ -6386,20 +8756,20 @@
2009-01-09 Don Porter <dgp@users.sourceforge.net>
- * generic/tclStringObj.c (STRING_SIZE): Corrected failure to limit
- memory allocation requests to the sizes that can be supported by Tcl's
- memory allocation routines. [Bug 2494093]
+ * generic/tclStringObj.c (STRING_SIZE): [Bug 2494093]: Corrected
+ failure to limit memory allocation requests to the sizes that can be
+ supported by Tcl's memory allocation routines.
2009-01-09 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclNamesp.c (NamespaceEnsembleCmd): Error out when someone
- gives wrong # of args to [namespace ensemble create]. [Bug 1558654]
+ * generic/tclNamesp.c (NamespaceEnsembleCmd): [Bug 1558654]: Error out
+ when someone gives wrong # of args to [namespace ensemble create].
2009-01-08 Don Porter <dgp@users.sourceforge.net>
- * generic/tclStringObj.c (STRING_UALLOC): Added missing parens
- required to get correct results out of things like
- STRING_UALLOC(num + append). [Bug 2494093]
+ * generic/tclStringObj.c (STRING_UALLOC): [Bug 2494093]: Added missing
+ parens required to get correct results out of things like
+ STRING_UALLOC(num + append).
2009-01-08 Donal K. Fellows <dkf@users.sf.net>
@@ -6411,7 +8781,7 @@
2009-01-07 Donal K. Fellows <dkf@users.sf.net>
- * doc/dict.n: Added more examples. [Tk Bug 2491235]
+ * doc/dict.n: [Tk Bug 2491235]: Added more examples.
* tests/oo.test (oo-22.1): Adjusted test to be less dependent on the
specifics of how [info frame] reports general frame information, and
@@ -6430,20 +8800,20 @@
* generic/tclDictObj.c (DictIncrCmd): Corrected twiddling in internals
of dictionaries so that literals can't get destroyed.
- * tests/expr.test: Eliminate non-ASCII char. [Bug 2006879]
+ * tests/expr.test: [Bug 2006879]: Eliminate non-ASCII char.
- * generic/tclOOInfo.c (InfoObjectMethodsCmd,InfoClassMethodsCmd): Only
- delete pointers that were actually allocated! [Bug 2489836]
+ * generic/tclOOInfo.c (InfoObjectMethodsCmd,InfoClassMethodsCmd):
+ [Bug 2489836]: Only delete pointers that were actually allocated!
* generic/tclOO.c (TclNRNewObjectInstance, Tcl_NewObjectInstance):
- Perform search for existing commands in right context. [Bug 2481109]
+ [Bug 2481109]: Perform search for existing commands in right context.
2009-01-05 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclCmdMZ.c (TclNRSourceObjCmd): Make implementation of the
- * generic/tclIOUtil.c (TclNREvalFile): [source] command be NRE
- enabled so that [yield] inside a script sourced in a coroutine can
- work. [Bug 2412068]
+ * generic/tclCmdMZ.c (TclNRSourceObjCmd): [Bug 2412068]: Make
+ * generic/tclIOUtil.c (TclNREvalFile): implementation of the
+ [source] command be NRE enabled so that [yield] inside a script
+ sourced in a coroutine can work.
2009-01-04 Donal K. Fellows <dkf@users.sf.net>
@@ -6458,22 +8828,21 @@
2009-01-02 Donal K. Fellows <dkf@users.sf.net>
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): Force the use of the compatibility
- version of mkstemp() on IRIX. [Bug 878333]
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): [Bug 878333]: Force the use of the
+ compatibility version of mkstemp() on IRIX.
* unix/configure.in, unix/Makefile.in (mkstemp.o):
- * compat/mkstemp.c (new file): Added a compatibility implementation of
- the mkstemp() function, which is apparently needed on some platforms.
- [Bug 741967]
-
- ******************************************************************
- *** CHANGELOG ENTRIES FOR 2008 IN "ChangeLog.2008" ***
- *** CHANGELOG ENTRIES FOR 2006-2007 IN "ChangeLog.2007" ***
- *** CHANGELOG ENTRIES FOR 2005 IN "ChangeLog.2005" ***
- *** CHANGELOG ENTRIES FOR 2004 IN "ChangeLog.2004" ***
- *** CHANGELOG ENTRIES FOR 2003 IN "ChangeLog.2003" ***
- *** CHANGELOG ENTRIES FOR 2002 IN "ChangeLog.2002" ***
- *** CHANGELOG ENTRIES FOR 2001 IN "ChangeLog.2001" ***
- *** CHANGELOG ENTRIES FOR 2000 IN "ChangeLog.2000" ***
- *** CHANGELOG ENTRIES FOR 1999 AND EARLIER IN "ChangeLog.1999" ***
- ******************************************************************
-
+ * compat/mkstemp.c (new file): [Bug 741967]: Added a compatibility
+ implementation of the mkstemp() function, which is apparently needed
+ on some platforms.
+
+ ******************************************************************
+ *** CHANGELOG ENTRIES FOR 2008 IN "ChangeLog.2008" ***
+ *** CHANGELOG ENTRIES FOR 2006-2007 IN "ChangeLog.2007" ***
+ *** CHANGELOG ENTRIES FOR 2005 IN "ChangeLog.2005" ***
+ *** CHANGELOG ENTRIES FOR 2004 IN "ChangeLog.2004" ***
+ *** CHANGELOG ENTRIES FOR 2003 IN "ChangeLog.2003" ***
+ *** CHANGELOG ENTRIES FOR 2002 IN "ChangeLog.2002" ***
+ *** CHANGELOG ENTRIES FOR 2001 IN "ChangeLog.2001" ***
+ *** CHANGELOG ENTRIES FOR 2000 IN "ChangeLog.2000" ***
+ *** CHANGELOG ENTRIES FOR 1999 AND EARLIER IN "ChangeLog.1999" ***
+ ******************************************************************
diff --git a/ChangeLog.2000 b/ChangeLog.2000
index 2ebdd23..0d20eaf 100644
--- a/ChangeLog.2000
+++ b/ChangeLog.2000
@@ -746,7 +746,7 @@
* doc/trace.n: minor doc cleanup
-2000-09-06 André Pönitz <poenitz@htwm.de>
+2000-09-06 André Pönitz <poenitz@htwm.de>
* doc/*.n: added or changed "SEE ALSO:" section
@@ -1086,7 +1086,7 @@
* unix/tcl.m4 (SC_ENABLE_GCC): Don't set CC=gcc before running
AC_PROG_CC if CC is already set.
-2000-07-13 André Pönitz <poenitz@mathematik.tu-chemnitz.de>
+2000-07-13 André Pönitz <poenitz@mathematik.tu-chemnitz.de>
* doc/lappend.n:
* doc/lindex.n:
diff --git a/ChangeLog.2001 b/ChangeLog.2001
index 6579651..06e7c36 100644
--- a/ChangeLog.2001
+++ b/ChangeLog.2001
@@ -939,7 +939,7 @@
version of Tcl with Cygwin gcc. Users should compile with Mingw gcc
instead.
-2001-11-06 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+2001-11-06 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* generic/tclIO.c (ReadChars): Fixed [Bug 478856] reported by Stuart
Cassoff <stwo@users.sourceforge.net>. The bug caused loss of
diff --git a/ChangeLog.2003 b/ChangeLog.2003
index b12cd2c..c586ba9 100644
--- a/ChangeLog.2003
+++ b/ChangeLog.2003
@@ -3284,7 +3284,7 @@
2003-01-10 Vince Darley <vincentdarley@users.sourceforge.net>
- * generic/tclIOUtil.c:
+ * generic/tclIOUtil.c:
* win/tclWinInt.h:
* win/tclWinInit.c: fix to new WinTcl crash on exit with vfs,
introduced on 2002-12-06. Encodings must be cleaned up after the
diff --git a/README b/README
index 0442a0e..7004bc5 100644
--- a/README
+++ b/README
@@ -1,8 +1,7 @@
README: Tcl
- This is the Tcl 8.6b2 source distribution.
- http://tcl.sourceforge.net/
- You can get any source release of Tcl from the file distributions
- link at the above URL.
+ This is the Tcl 8.6.1 source distribution.
+ http://sourceforge.net/projects/tcl/files/Tcl/
+ You can get any source release of Tcl from the URL above.
Contents
--------
@@ -27,9 +26,14 @@ Tcl can also be used for a variety of web-related tasks and for creating
powerful command languages for applications.
Tcl is maintained, enhanced, and distributed freely by the Tcl community.
-The home for Tcl/Tk releases and bug/patch database is on SourceForge:
+Source code development and tracking of bug reports and feature requests
+takes place at:
- http://tcl.sourceforge.net/
+ http://core.tcl.tk/
+
+Tcl/Tk release and mailing list services are hosted by SourceForge:
+
+ http://sourceforge.net/projects/tcl/
with the Tcl Developer Xchange hosted at:
@@ -49,7 +53,7 @@ The home page for this release, including new features, is
Detailed release notes can be found at the file distributions page
by clicking on the relevant version.
- http://sourceforge.net/projects/tcl/files/
+ http://sourceforge.net/projects/tcl/files/Tcl/
Information about Tcl itself can be found at
http://www.tcl.tk/about/
@@ -146,18 +150,13 @@ and go to the Mailing Lists page.
------------------------
We are very interested in receiving bug reports, patches, and suggestions
-for improvements. We prefer that you send this information to us via the
-bug form at SourceForge, rather than emailing us directly. The bug
-database is at:
-
- http://tcl.sourceforge.net/
+for improvements. We prefer that you send this information to us as
+tickets entered into our tracker at:
-The bug form was designed to give uniform structure to bug reports as
-well as to solicit enough information to minimize followup questions.
+ http://core.tcl.tk/tcl/reportlist
We will log and follow-up on each bug, although we cannot promise a
-specific turn-around time. Enhancements, reported via the Feature
-Requests form at the same web site, may take longer and may not happen
+specific turn-around time. Enhancements may take longer and may not happen
at all unless there is widespread support for them (we're trying to
slow the rate at which Tcl/Tk turns into a kitchen sink). It's very
difficult to make incompatible changes to Tcl/Tk at this point, due to
diff --git a/changes b/changes
index 88ea3e6..659319c 100644
--- a/changes
+++ b/changes
@@ -126,7 +126,7 @@ Tcl_Eval.
that came after version 3.3 was released.
40. 5/17/91 Changed tests to conform to Mary Ann May-Pumphrey's approach.
-
+
41. 5/23/91 Massive revision to Tcl parser to simplify the implementation
of string and floating-point support in expressions. Newlines inside
[] are now treated as command separators rather than word separators
@@ -260,7 +260,7 @@ argument (before file name), for consistency with other Tcl commands.
*** POTENTIAL INCOMPATIBILITY ***
72. 8/20/91 Changed format of information in $errorInfo variable:
-comments such as
+comments such as
("while" body line 1)
are now on separate lines from commands being executed.
*** POTENTIAL INCOMPATIBILITY ***
@@ -1192,7 +1192,7 @@ under some dynamic loading systems (e.g. SunOS 4.1 and Windows).
6/8/95 (feature change) Modified interface to Tcl_Main to pass in the
address of the application-specific initialization procedure.
Tcl_AppInit is no longer hardwired into Tcl_Main. This is needed
-in order to make Tcl a shared library.
+in order to make Tcl a shared library.
6/8/95 (feature change) Modified Makefile so that the installed versions
of tclsh and libtcl.a have version number in them (e.g. tclsh7.4 and
@@ -1616,7 +1616,7 @@ file name. Under Windows '95, this is incorrectly interpreted as a UNC
path. They delays came from the network timeouts needed to determine that
the file name was invalid. Tcl_TranslateFileName now suppresses duplicate
slashes that aren't at the beginning of the file name. (SS)
-
+
1/25/96 (bug fix) Changed exec and open to create children so they are
attached to the application's console if it exists. (SS)
@@ -2254,21 +2254,21 @@ version of Tcl. It's quite a bit faster than MetroWerk's version. (RJ)
8/26/96 (documentation update) Removed old change bars (for all changes
in Tcl 7.5 and earlier releases) from manual entries. (JO)
-8/27/96 (enhancement) The exec and open commands behave better and work in
-more situations under Windows NT and Windows 95. Documentation describes
+8/27/96 (enhancement) The exec and open commands behave better and work in
+more situations under Windows NT and Windows 95. Documentation describes
what is still lacking. (CS)
8/27/96 (enhancement) The Windows makefiles will now compile even if the
compiler is not in the path and/or the compiler's environment variables
-have not been set up. (CS)
+have not been set up. (CS)
-8/27/96 (configuration improvement) The Windows resource files are
+8/27/96 (configuration improvement) The Windows resource files are
automatically updated when the version/patch level changes. The header file
now has a comment that reminds the user which other files must be manually
updated when the version/patch level changes. (CS)
8/28/96 (new feature) Added file manipulation features (copy, rename, delete,
-mkdir) that are supported on all platforms. They are implemented as
+mkdir) that are supported on all platforms. They are implemented as
subcommands to the "file" command. See the documentation for the "file"
command for more information. (JH)
@@ -2371,7 +2371,7 @@ the Tcl script in the fileevent wasn't closing the socket immediately. (JL)
package goes in a separate subdirectory of a directory in
$tcl_pkgPath). These directories are included in auto_path by
default.
- - Changed the package auto-loader to look for pkgIndex.tcl files
+ - Changed the package auto-loader to look for pkgIndex.tcl files
not only in the auto_path directories but also in their immediate
children. This should make it easier to install and uninstall
packages (don't have to change auto_path or merge pkgIndex.tcl
@@ -2621,7 +2621,7 @@ lookups of keyword arguments. (JO)
1/12/97 (new feature) Serial IO channel drivers for Windows and Unix,
available by using Tcl open command to open pseudo-files like "com1:" or
-"/dev/ttya". New option to Tcl fconfigure command for serial files:
+"/dev/ttya". New option to Tcl fconfigure command for serial files:
"-mode baud,parity,data,stop" to specify baud rate, parity, data bits, and
stop bits. Serial IO is not yet available on Mac.
@@ -2701,7 +2701,7 @@ to Feb 31.) The code now will return the last valid day of the
month in these situations. Thanks to Hume Smith for sending in
this bug fix. (RJ)
-2/10/97 (feature change) Eliminated Tcl_StringObjAppend and
+2/10/97 (feature change) Eliminated Tcl_StringObjAppend and
Tcl_StringObjAppendObj procedures, replaced them with Tcl_AppendToObj
and Tcl_AppendStringsToObj procedures. Added new procedure
Tcl_SetObjLength. (JO)
@@ -3068,7 +3068,7 @@ compilation errors from "invoked from within" to "while compiling". (BL)
modified the interpreter result even if there was no error.
- The argument parsing procedure used by several compile procedures
always treated "]" as end of a command: e.g., "set a ]" would fail.
- - Changed errorInfo traceback message for compilation errors from
+ - Changed errorInfo traceback message for compilation errors from
"invoked from within" to "while compiling".
- Problem initializing Tcl object managers during interpreter creation.
- Added check and error message if formal parameter to a procedure is
@@ -3143,7 +3143,7 @@ is leaked to safe interps. Error message fixes for interp sub commands.
Likewise changes in safealias.tcl; tcl_safeCreateInterp can now be called
without argument to generate the slave name (like in interp create). (DL)
-7/10/97 (bug fixes) Bytecode compiler now generates more detailed
+7/10/97 (bug fixes) Bytecode compiler now generates more detailed
command location information: subcommands as well as commands now have
location information. This means command trace procedures now get the
correct source string for each command in their command parameter. (BL)
@@ -3181,7 +3181,7 @@ malloc and free. (SS)
sourcing/loading (see safe.n) to hide pathnames, use virtual
paths tokens instead, improved security in several respects and made it
more tunable. Multi level interp loading can work too now. Package auto
-loading now works in safe interps as long as the package directory is in
+loading now works in safe interps as long as the package directory is in
the auto_path (no deep crawling allowed in safe interps). (DL)
*** POTENTIAL INCOMPATIBILITY with previous alpha and beta releases ***
@@ -3209,7 +3209,7 @@ exists" command returns 0 for them. (BL)
7/29/97 (feature change) Changed the http package to use the ::http
namespace. http_get renamed to http::geturl, http_config renamed to
http::config, http_formatQuery renamed to http::formatQuery.
-It now provides the 2.0 version of the package.
+It now provides the 2.0 version of the package.
The 1.0 version is still available with the old names.
*** POTENTIAL INCOMPATIBILITY with Tcl 8.0b2 but not with Tcl 7.6 ***
@@ -3273,7 +3273,7 @@ except that the default precision is 12 instead of 6. (JO)
----------------- Released 8.0, 8/18/97 -----------------------
8/19/97 (bug fix) Minimal fix for glob -nocomplain bugs:
-"glob -nocomplain unreadableDir/*" was generating an anonymous
+"glob -nocomplain unreadableDir/*" was generating an anonymous
error. More in depth fixes will come with 8.1. (DL).
8/20/97 (bug fix) Removed check for FLT_MIN in binary command so
@@ -3318,7 +3318,7 @@ does not prevent stack overflow by multi-interps recursion or aliasing} (DL)
9/11/97 (bug fix) An uninitialized variable in Tcl_WaitPid caused
pipes to fail to report eof properly under Windows. (SS)
-9/12/97 (bug fix) "exec" was misidentifying some DOS executables as not
+9/12/97 (bug fix) "exec" was misidentifying some DOS executables as not
executable. (CCS)
9/14/97 (bug fix) Was using the wrong structure in sizeof operation in
@@ -3342,7 +3342,7 @@ Roseman for the pointer on the fix.) (RJ)
cause the compare function to run off the end of an array if the
number only contained 0's. (Thanks to Greg Couch for the report.) (RJ)
-9/18/97 (bug fix) TclFinalizeEnvironment was not cleaning up
+9/18/97 (bug fix) TclFinalizeEnvironment was not cleaning up
properly. (DL, JI)
9/18/97 (bug fix) Fixed long-standing bug where an "array get" command
@@ -3378,9 +3378,9 @@ Now you can "join $list \0" for instance. (DL)
non-existent directory, exec would fail when trying to create its temporary
files. (CCS)
-10/9/97 (bug fix) Under mac and windows, "info hostname" would crash if
+10/9/97 (bug fix) Under mac and windows, "info hostname" would crash if
sockets were installed but the hostname could not be determined anyhow.
-Tcl_GetHostName() was returning NULL when it should have been returning
+Tcl_GetHostName() was returning NULL when it should have been returning
an empty string. (CCS)
10/10/97 (bug fix) "file attribute /" returned error on windows. (CCS)
@@ -3468,7 +3468,7 @@ around to be really closed in this case. (JL)
12/8/97 (bug fix) Need to protect the channel in a fileevent so that it
is not deleted before the fileevent handler returns. (CS, JL)
-12/18/97 (bug fix) In the opt argument parsing package: if the description
+12/18/97 (bug fix) In the opt argument parsing package: if the description
had only flags, the "too many arguments" case was not detected. The default
value was not used for the special "args" ending argument. (DL)
@@ -3511,7 +3511,7 @@ that could lead to a crash. (SS)
non-local variable references. (SS)
6/25/98 (new features) Added name resolution hooks to support [incr Tcl].
-There are new internal Tcl_*Resolver* APIs to add, query and remove the hooks.
+There are new internal Tcl_*Resolver* APIs to add, query and remove the hooks.
With this changes it should be possible to dynamically load [incr Tcl]
as an extension. (MM)
@@ -3539,7 +3539,7 @@ TclAccessInsertProc, TclStatInsertProc, & TclOpenFileChannelInsertProc
insert pointers to such routines; TclAccessDeleteProc, TclStatDeleteProc,
& TclOpenFileChannelDeleteProc delete pointers to such routines. See
the file generic/tclIOUtils.c for more details. (SKS)
-
+
7/1/98 (enhancement) Added a new internal C variable
tclPreInitScript. This is a pointer to a string that may hold an
initialization script; If this pointer is non-NULL it is evaluated in
@@ -3623,7 +3623,7 @@ internal representation holds a pointer to a Proc structure. Extended
TclCreateProc to take both strings and "procbody". (EMS)
10/13/98 (bug fix) The "info complete" command can now handle strings
-with NULLs embedded. Thanks to colin@field.medicine.adelaide.edu.au
+with NULLs embedded. Thanks to colin@field.medicine.adelaide.edu.au
for providing this fix. (RJ)
10/13/98 (bug fix) The "lsort -dictionary" command did not properly
@@ -3691,7 +3691,7 @@ by default. Fixed socket code so it turns off this bit right after
creation so sockets aren't kept open by exec'ed processes. [Bug: 892]
Thanks to Kevin Kenny for this fix. (SS)
-1/11/98 (bug fix) On HP, "info sharedlibextension" was returning
+1/11/98 (bug fix) On HP, "info sharedlibextension" was returning
empty string on static apps. It now always returns ".sl". (RJ)
1/28/99 (configure change) Now support -pipe option on gcc. (RJ)
@@ -3736,7 +3736,7 @@ panic. (stanton)
2/2/99 (feature change/bug fix) Changed the behavior of "file
extension" so that it splits at the last period. Now the extension of
-a file like "foo..o" is ".o" instead of "..o" as in previous versions.
+a file like "foo..o" is ".o" instead of "..o" as in previous versions.
*** POTENTIAL INCOMPATIBILITY ***
----------------- Released 8.0.5, 3/9/99 -------------------------
@@ -3757,15 +3757,15 @@ a file like "foo..o" is ".o" instead of "..o" as in previous versions.
of a UTF-8 string remains \0. Thus Tcl strings once again do not
contain null bytes, except for termination bytes.
- For Java compatibility, "\uXXXX" is used in Tcl to enter a Unicode
- character. "\u0000" through "\uffff" are acceptable Unicode
- characters.
+ character. "\u0000" through "\uffff" are acceptable Unicode
+ characters.
- "\xXX" is used to enter a small Unicode character (between 0 and 255)
in Tcl.
- Tcl automatically translates between UTF-8 and the normal encoding for
the platform during interactions with the system.
- The fconfigure command now supports a -encoding option for specifying
the encoding of an open file or socket. Tcl will automatically
- translate between the specified encoding and UTF-8 during I/O.
+ translate between the specified encoding and UTF-8 during I/O.
See the directory library/encoding to find out what encodings are
supported (eventually there will be an "encoding" command that
makes this information more accessible).
@@ -3839,7 +3839,7 @@ imported procedures as well as procedures defined in a namespace. (BL)
in place of Tcl_GetStringFromObj() if the string representation's length
isn't needed. (BL)
-12/18/97 (bug fix) In the opt argument parsing package: if the description
+12/18/97 (bug fix) In the opt argument parsing package: if the description
had only flags, the "too many arguments" case was not detected. The default
value was not used for the special "args" ending argument. (DL)
@@ -3849,11 +3849,11 @@ procs now in auto.tcl and package.tcl can be autoloaded if needed. (DL)
1/7/98 (enhancement) tcltest made at install time will search for it's
init.tcl where it is, even when using virtual path compilation. (DL)
-1/8/98 (os bug workaround) when needed, using a replacement for memcmp so
+1/8/98 (os bug workaround) when needed, using a replacement for memcmp so
string compare "char with high bit set" "char w/o high bit set" returns
the expected value on all platforms. (DL)
-1/8/98 (unix portability/configure) building from .../unix/targetName/
+1/8/98 (unix portability/configure) building from .../unix/targetName/
subdirectories and simply using "../configure" should now work fine. (DL)
1/14/98 (enhancement) Added new regular expression package that
@@ -3885,7 +3885,7 @@ to generate direct loading package indexes (such those you need
if you use namespaces and plan on using namespace import just after
package require). pkg_mkIndex still has limitations regarding
package dependencies but errors are now ignored and with -direct, correct
-package indexes can be generated even if there are dependencies as long
+package indexes can be generated even if there are dependencies as long
as the "package provide" are done early enough in the files. (DL)
1/28/98 (enhancement) Performance tuning of regexp and regsub. (CCS)
@@ -3909,7 +3909,7 @@ continue to use the argv array after calling Tcl_OpenCommandChannel(). (CCS)
2/1/98 (bug fix) More bugs with %Z in format string argument to strftime():
1. Borland always returned empty string.
2. MSVC always returned the timezone string for the current time, not the
- timezone string for the specified time.
+ timezone string for the specified time.
3. With MSVC, "clock format 0 -format %Z -gmt 1" would return "GMT" the first
time it was called, but would return the current timezone string on all
subsequent calls. (CCS)
@@ -3931,7 +3931,7 @@ root directory was returning error. (CCS)
determine the attributes for a file. Previously it would return different
error messages on Unix vs. Windows vs. Mac. (CCS)
-2/4/98 (bug fixes) Fixed several instances of bugs where the parser/compiler
+2/4/98 (bug fixes) Fixed several instances of bugs where the parser/compiler
would reach outside the range of allocated memory. Improved the array
lookup algorithm in set compilation. (DL)
@@ -3939,13 +3939,13 @@ lookup algorithm in set compilation. (DL)
deprecated and ignored. The part1 is always parsed when the part2 argument
is NULL. This is to avoid a pattern of errors for extension writers converting
from string based Tcl_SetVar() to new Tcl_SetObjVar2() and who could easily
-forget to provide the flag and thus get code working for normal variables
+forget to provide the flag and thus get code working for normal variables
but not for array elements. The performance hit is minimal. A side effect
of that change is that is is no longer possible to create scalar variables
-that can't be accessed by tcl scripts because of their invalid name
-(ending with parenthesis). Likewise it is also parsed and checked to
-ensure that you don't create array elements of array whose name is a valid
-array element because they would not be accessible from scripts anyway.
+that can't be accessed by tcl scripts because of their invalid name
+(ending with parenthesis). Likewise it is also parsed and checked to
+ensure that you don't create array elements of array whose name is a valid
+array element because they would not be accessible from scripts anyway.
Note: There is still duplicate array elements parsing code. (DL)
*** POTENTIAL INCOMPATIBILITY ***
@@ -3991,7 +3991,7 @@ registry call. (CCS)
2/11/98 (enhancement) Eliminate the TCL_USE_TIMEZONE_VAR definition from
configure.in, because it was the same information as the already existing
HAVE_TM_ZONE definition. The lack of HAVE_TM_ZONE is used to work around a
-Solaris and Windows bug where "clock format [clock sec] -format %Z -gmt 1"
+Solaris and Windows bug where "clock format [clock sec] -format %Z -gmt 1"
produces the local timezone string instead of "GMT". (CCS)
2/11/98 (bug fix) Memleaks and dereferencing of uninitialized memory in
@@ -4349,7 +4349,7 @@ strings that are already null terminated. [Bug: 1793] (stanton)
5/3/99 (new feature) Applied Jeff Hobbs's string patch which includes
the following changes:
- - added new subcommands: equal, repeat, map, is, replace
+ - added new subcommands: equal, repeat, map, is, replace
- added -length option to "string compare|equal"
- added -nocase option to "string compare|equal|match"
- string and list indices can be an integer or end?-integer?.
@@ -4378,7 +4378,7 @@ improvements for many Tcl scripts. [Bug: 1063] (stanton)
encoding subfield from the LANG/LC_ALL environment variables in cases
where the locale is not found in the built-in locale table. It also
attempts to initialize the locale subsystem so X11 is happy. [Bug: 1989]
-(stanton)
+(stanton)
5/14/99 (bug fix) Applied the patch to fix 100-year and 400-year
boundaries in leap year code, from Isaac Hollander. [Bug: 2066] (redman)
@@ -4466,7 +4466,7 @@ harness package. Modified test files to use new tcltest package.
6/26/99 (new feature) Applied patch from Peter Hardie to add poke
command to dde and changed the dde package version number to
-1.1. (redman)
+1.1. (redman)
6/28/99 (bug fix) Applied patch from Peter Hardie to fix problem in
Tcl_GetIndexFromObj() when the key being passed is the empty string.
@@ -4529,7 +4529,7 @@ notation for opening serial ports on Windows. (redman)
instead of the platform-specific "size_t", primarily after SunOS 4
users could no longer compile. (redman)
-7/22/99 (bug fix) Fixed crashing during "array set a(b) {}".
+7/22/99 (bug fix) Fixed crashing during "array set a(b) {}".
[Bug: 2427] (redman)
7/22/99 (bug fix) The install-sh script must be given execute
@@ -4564,7 +4564,7 @@ pack-old.n [Bug: 2469]. Patches from Don Porter. (redman)
7/29/99 (bug fix) Allow tcl to open CON and NUL, even for redirection
of std channels. [Bug: 2393 2392 2209 2458] (redman)
-7/30/99 (bug fix) Applied fixed Trf patch from Andreas Kupries.
+7/30/99 (bug fix) Applied fixed Trf patch from Andreas Kupries.
[Bug: 2386] (hobbs)
7/30/99 (bug fix) Fixed bug in info complete. [Bug: 2383 2466] (hobbs)
@@ -4574,7 +4574,7 @@ provided by James Dennett. [Bug: 2450] (redman)
7/30/99 (bug fix) Fixed launching of 16bit applications on Win9x from
wish. The command line was being primed with tclpip82.dll, but it was
-ignored later.
+ignored later.
7/30/99 (bug fix) Added functions to stub table, patch provided by Jan
Nijtmans. [Bug: 2445] (hobbs)
@@ -4587,7 +4587,7 @@ thread's stack space. (redman)
--------------- Released 8.2b2, August 5, 1999 ----------------------
8/4/99 (bug fix) Applied patches supplied by Henry Spencer to greatly
-enhance performance of certain classes of regular expressions.
+enhance performance of certain classes of regular expressions.
[Bug: 2440 2447] (stanton)
8/5/99 (doc change) Made it clear that tcl_pkgPath was not set for
@@ -4601,7 +4601,7 @@ terminated in tclLiteral.c. [Bug: 2496] (hobbs)
8/9/99 (bug fix) Fixed test suite to handle larger integers
(64bit). Patch from Don Porter. (hobbs)
-8/9/99 (documentation fix) Clarified Tcl_DecrRefCount docs
+8/9/99 (documentation fix) Clarified Tcl_DecrRefCount docs
[Bug: 1952]. Clarified array pattern docs [Bug: 1330]. Fixed clock docs
[Bug: 693]. Fixed formatting errors [Bug: 2188 2189]. Fixed doc error
in tclvars.n [Bug: 2042]. (hobbs)
@@ -4661,7 +4661,7 @@ and in testthread code. No more known (reported) mem leaks for Tcl
built using gcc on Solaris 2.5.1. Also none reported for Tcl on NT
(using Purify 6.0). (hobbs)
-10/30/99 (bug fix) fixed improper bytecode handling of
+10/30/99 (bug fix) fixed improper bytecode handling of
'eval {set array($unknownvar) 5}' (also for incr) (hobbs)
10/30/99 (bug fix) fixed event/io threading problems by making
@@ -5115,7 +5115,7 @@ bits for Tcl_UniChar though) (hobbs)
2001-05-30 (new feature)[TIP 15] Tcl_GetMathFuncInfo, Tcl_ListMathFuncs,
Tcl_InfoObjCmd, InfoFunctionsCmd APIs (fellows)
-2001-06-08 (bug fix,feature enhancement)[219170,414936] all Tcl_Panic
+2001-06-08 (bug fix,feature enhancement)[219170,414936] all Tcl_Panic
definitions brought into agreement (porter)
2001-06-12 (bug fix)[219232] regexp returned non-matching sub-pairs to have
@@ -5284,7 +5284,7 @@ compiles to 0 bytecodes (sofer)
2001-09-13 (new feature) Old ChangeLog entries => ChangeLog.1999 (hobbs)
-2001-09-17 (new feature) compiling with TCL_COMPILE_DEBUG now required to
+2001-09-17 (new feature) compiling with TCL_COMPILE_DEBUG now required to
enable all compile and execution tracing (sofer)
*** POTENTIAL INCOMPATIBILITY ***
@@ -5566,7 +5566,7 @@ options to configure (max)
2002-07-30 (bug fix)[584603] WriteChars infinite loop non-UTF-8 string (kupries)
-2002-08-04 (new feature)[584051,580433,585105,582429][TIP 27] Tcl interfaces
+2002-08-04 (new feature)[584051,580433,585105,582429][TIP 27] Tcl interfaces
are now fully CONST-ified. Use the symbols USE_NON_CONST or
USE_COMPAT_CONST to select interfaces with fewer changes.
*** POTENTIAL INCOMPATIBILITY ***
@@ -5576,7 +5576,7 @@ options to configure (max)
=> tcltest 2.2
2002-08-07 (bug fix)[587488] mem leak with USE_THREAD_ALLOC (sofer,sass)
-
+
2002-08-07 (feature enhancement)[584794,584650,472576] boolean values
are no longer always re-parsed from string. (sofer)
@@ -5710,7 +5710,7 @@ packages in multiple interps.
2003-02-01 (bug fix)[675356] [clock clicks {}]; [clock clicks -] - syntax errs
-2003-02-01 (bug fix)[656660] MT-safety for [clock format]
+2003-02-01 (bug fix)[656660] MT-safety for [clock format]
2003-02-03 (bug fix)[651271] command rename traces get fully-qualified names
*** POTENTIAL INCOMPATIBILITY ***
@@ -5929,7 +5929,7 @@ various odd regexp "can't happen" bugs.
2003-12-09 (platform support)[852369] update errno usage for recent glibc
-2003-12-12 (bug fix)[858937] fix for [file normalize ~nobody]
+2003-12-12 (bug fix)[858937] fix for [file normalize ~nobody]
2003-12-17 (bug fix)[839519] fixed two memory leaks (vasiljevic)
@@ -5944,7 +5944,7 @@ various odd regexp "can't happen" bugs.
2004-02-12 (feature enhancement) update HP-11 build libs setup
-2004-02-17 (bug fix)[849514,859251] corrected [file normailze] of $link/..
+2004-02-17 (bug fix)[849514,859251] corrected [file normailze] of $link/..
2004-02-17 (bug fix)[772288] Unix std channels forced to exist at startup.
@@ -6037,7 +6037,7 @@ in this changeset (new minor version) rather than bug fixes:
* [TIP #139] documented portions of Tcl's namespace C APIs
* [TIP #148] correct [list]-quoting of the '#' character
- *** POTENTIAL INCOMPATIBILITY ***
+ *** POTENTIAL INCOMPATIBILITY ***
For scripts that assume a particular (buggy) string rep for lists.
* [TIP #156] add "root locale" to msgcat
@@ -6532,7 +6532,7 @@ Reduces the ***POTENTIAL INCOMPATIBILITY*** from 2005-05-17.
2005-07-22 (enhancement)[1237755] 8.4 features in script library (fradin,porter)
-2005-07-24 (new feature) configure macros SC_PROG_TCLSH, SC_BUILD_TCLSH (dejong)
+2005-07-24 (new feature) configure macros SC_PROG_TCLSH, SC_BUILD_TCLSH (dejong)
2005-07-26 (bug fix)[1047286] cmd delete traces during namespace delete (porter)
2005-07-26 (new unix feature)[1231015] ${prefix}/share on ::tcl_pkgPath (dejong)
@@ -6627,7 +6627,7 @@ registered by [package ifneeded] provides the version it claims (lavana,porter)
2005-11-09 (bug fix)[1350293,1350291] [after $negative $script] fixed (kenny)
-2005-11-12 (bug fix)[1352734,1354540,1355942,1355342] [namespace delete]
+2005-11-12 (bug fix)[1352734,1354540,1355942,1355342] [namespace delete]
issues with [namespace path] and command delete traces (sofer,fellows)
2005-11-18 (bug fix)[1358369] URL parsing standards compliance (wu,fellows)
@@ -6756,7 +6756,7 @@ naked-fork safe on Tiger (steffen)
2006-06-20 (internal change) Dropped the internal routines used to hook into
filesystem operations back in the pre-Tcl_Filesystem days. (porter)
***POTENTIAL INCOMPATIBILITY***
-For extensions and programs that have never migrated to the supported Tcl 8.4
+For extensions and programs that have never migrated to the supported Tcl 8.4
interface for virtual filesystems
2006-07-05 (enhancement) Expression parser rewrite avoids stack overflow,
@@ -7603,7 +7603,7 @@ avoid otherwise very tricky multi-thread finalization bugs. (staplin,ferrieux)
2009-10-04 (bug fix)[2569449] Core Foundation memory bug in Tiger (steffen)
-2009-10-06 (bug fix) repair intrep loss in slave interp evaluations
+2009-10-06 (bug fix) repair intrep loss in slave interp evaluations
introduced by first versions of the NRE conversion (nadkarni,porter)
2009-10-06 (bug fix)[1941434] broken tclTomMath.h includes (porter)
@@ -7915,6 +7915,7 @@ memory with buffer backup (ferrieux)
2011-03-14 (bug fix) Fixes from libtommath 0.42.0 release (fellows)
2011-03-21 (bug fix)[3216070] [load] extension from embed Tcl apps (nijtmans)
+ ***POTENTIAL INCOMPATIBILITY***
2011-03-27 (performance) NRE: LIST lset foreach benchmark (twylite)
@@ -7954,3 +7955,352 @@ memory with buffer backup (ferrieux)
Many more Tcl built-in command errors now set an -errorcode.
--- Released 8.6b2, August 8, 2011 --- See ChangeLog for details ---
+
+2011-07-02 (bug fix)[3349507] correct double(1[string repeat 0 23]) (kenny)
+
+2011-07-19 (bug fix)[3371644] Tcl_ConvertElement() segfault (sader, ferrieux)
+
+2011-07-21 (bug fix)[3372130] hypot(.) segfault (nijtmans)
+
+2011-08-12 (bug fix)[3389764] memleaks due to reference cycles in dup'd paths
+
+2011-08-15 (bug fix)[3390272] leak of [info script] value (porter)
+
+2011-08-17 (bug fix)[3393150] bignum leaks in Tcl_Get*() routines (porter)
+
+2011-08-18 (bug fix)[3393714] [string toupper] overflow (nijtmans)
+
+2011-08-30 (bug fix)[3398794] panic in interp limit setting (gavlian,fellows)
+
+2011-09-08 (bug fix)[3401704] revised expr parser to permit function names
+like "nano()" instead of parsing as "nan o()" with missing op (duquette,porter)
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2011-09-10 (bug fix)[3400658] wrong num args msg with TclOO (rsooltan,fellows)
+
+2011-09-13 (bug fix)[3390638] solaris studio cc workaround (kechel,porter)
+
+2011-09-13 (bug fix)[3405652] DTrace workaround (michelson,porter)
+
+2011-09-16 (bug fix)[3391977] -headers overrides -type (ziegenhagen,fellows)
+=> http 2.8.3
+
+2011-09-16 (TIP 388) New \Uhhhhhhhh syntax (nijtmans)
+
+2011-10-06 (enhancement) bytecode compile [dict with] (fellows)
+
+2011-10-11 (bug fix)[2935503] [file stat] returns bad mode (nadkarni,nijtmans)
+
+2011-10-20 (bug fix)[3418547] cmd lits and custom resolvers (soberning,fellows)
+
+2011-10-31 (bug fix)[3414754] EIAS violation in fs paths (porter)
+
+2011-11-22 (bug fix)[3354324] Win: [file mtime] sets wrong time (nijtmans)
+
+2011-11-30 (bug fix)[967195] Simply args passed to child processes (nijtmans)
+=> tcltest 2.3.4
+
+2011-12-07 (bug fix)[3444754] fix [string tolower \u01C5] (nijtmans)
+
+2011-12-11 (update)[3457031] Update [[:print:]] to Unicode 6.0 (nijtmans)
+
+2011-12-24 (bug fix)[3464428] fix [string is graph \u0120] (nijtmans)
+
+2012-01-08 (bug fix)[3470928] zoneinfo trouble with Windhoek data file (kenny)
+
+2012-01-13 (bug fix)[3472316] fix retrieval of socket error (fellows)
+
+2012-01-21 (bug fix)[3475667] [regexp] buffer read overflow (sebres)
+
+2012-01-22 (bug fix)[3475264] [dict exists] return 0, not error (fellows)
+
+2012-01-25 (bug fix)[3474460] [oo::copy] var resolution list (fellows)
+
+2012-01-26 (bug fix)[3475569,3479689] mem corrupt in fs path (sebres,porter)
+
+2012-01-30 (enhancement) improve bytecode compile of [catch] (fellows)
+
+2012-02-02 (bug fix)[2974459,2879351,1951574,1852572,1661378,1613456] Fix
+problems where [file *able] would return false results on Win/Samba (porter)
+
+2012-02-06 (bug fix)[3484621] bump bytecode epoch on exec traces (kuhn,sofer)
+
+2012-02-15 (bug fix)[3487626] crash compiling [dict for] (fellows)
+
+2012-02-15 (enhancement) bytecode compile [lrange],[lreplace] (fellows)
+
+2012-02-17 (bug fix)[2233954] compile problem on AIX & Android (nijtmans)
+
+2012-02-29 (bug fix)[3466099] BOM in Unicode (nijtmans)
+
+2012-03-07 (bug fix)[3498327] RFC 3986 compliance (kupries)
+
+2012-03-26 (TIP 380) New builtin class [oo::Slot] (fellows)
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2012-03-27 (TIP 397) <cloned> method to extend [oo::copy] (fellows)
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2012-03-27 (TIP 395) New subcommand [string is entier] (fellows)
+
+2012-04-02 (TIP 396) New command [yieldto] (fellows)
+
+2012-04-04 (bug fix)[3514761] crash combining objects and ensembles (fellows)
+
+2012-04-09 (bug fix)[2712377] [info vars] and oo variables (fellows)
+
+2012-04-09 (bug fix)[3396896] no dups in oo var lists (fellows)
+
+2012-04-11 (bug fix)[3448512] [clock scan 1958-01-01] fail on Win (nijtmans)
+
+2012-04-15 (bug fix)[3517696] fix flush of zlib chan xform (fellows)
+
+2012-04-18 tzdata updated to Olson's tzdata2012c (kenny)
+
+2012-04-28 (TIP 398) exit non-blocking chan without flush (ferrieux)
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2012-05-02 (enhancement) Better use of Intel cpuid instruction (nijtmans)
+
+2012-05-03 (bug fix)[3428753] Unbreak synchronous [socket -async] (porter)
+
+2012-05-10 (bug fix)[2812981] force consistent config of Tcl+pkgs (ferrieux)
+
+2012-05-10 (bug fix)[473946] correct send of special characters (nijtmans)
+
+2012-05-17 (bug fix)[3445787] fix [file] ensemble in Safe Base (fellows)
+
+2012-05-17 (bug fix)[2964715] fix [glob] in Safe Base (fellows)
+
+2012-05-17 (bug fix)[3106532] proper [switch -indexvar] values (fellows)
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2012-05-21 (TIP 106) New -binary option to [dde execute|poke] (oehlmann)
+=> dde 1.4.0
+
+2012-05-23 (bug fix)[3525907] [zlib push decompress] & [chan event]
+(fellows,ferrieux,kupries)
+
+2012-05-28 (bug fix)[3529949] Protect ~ paths in Safe Base (fellows)
+
+2012-06-21 (bug fix)[3362446] [registry keys] failure (nijtmans)
+=> registry 1.3.0
+
+2012-06-25 (bug fix)[3537605] [encoding dirs a b] error message (fellows)
+
+2012-06-25 (bug fix)[3024359] crash when multi-thread concurrent [file system]
+and Tcl_FSMountsChanged(). (porter)
+
+2012-06-29 (bug fix)[3536888] fix locale guessing (oehlmann,nijtmans)
+
+2012-07-05 (bug fix)[1189293] make "<<" redirect binary safe (porter)
+
+2012-07-08 (bug fix)[3531209] accept IPv6 URLs (max)
+=> http 2.8.4
+
+2012-07-24 (bug fix) stop mem corruption in stacked channel events (max,porter)
+
+2012-07-25 (bug fix)[3546275] [auto_execok] search match [exec] (danckaert)
+
+2012-07-27 (update)[3464401] Support Unicode 6.2 (nijtmans)
+
+2012-08-20 (bug fix)[3559678] [file normalize] EIAS failure (phao,dgp)
+
+2012-08-25 (bug fix)[3561330] Ukranian translation of "March" (teterin)
+
+2012-09-07 (TIP 404) New msgcat commands [mcflset], [mcflmset] (oehlmann)
+=> msgcat 1.5.0
+
+Many revisions to better support a Cygwin environment (nijtmans)
+
+Dropped support for OS X versions less than 10.4 (Tiger) (fellows)
+
+--- Released 8.6b3, September 18, 2012 --- See ChangeLog for details ---
+
+2012-09-20 (enhancement) full Unicode support (nijtmans)
+=> dde 1.4.0
+
+2012-09-20 (enhancement) update bundled zlib to 1.2.7 (nijtmans)
+
+2012-10-03 (bug fix) exit panic on stacked std channel (griffin,porter)
+
+2012-10-14 (bug fix) [tcl::Bgerror] crash on non-dict options (nijtmans)
+
+2012-10-16 (TIP 400) New [zlib] options to set compression dict (fellows)
+
+2012-10-16 (TIP 405) New commands [lmap] and [dict map] (fellows)
+
+2012-10-24 (enhancement) [dict unset] now bytecompiled (fellows)
+
+2012-11-05 (TIP 413) Revisions to default [string trim*] trimset (nijtmans)
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2012-11-05 (enhancement) Now bytecompiled: [array exists], [array set],
+[array unset], [dict create], [dict exists], [dict merge], [format],
+[info commands], [info coroutine], [info level], [info object],
+[namespace current], [namespace code], [namespace qualifiers], [namespace tail],
+[namespace which], [regsub], [self], [string first], [string last],
+[string map], [string range], [tailcall], [yield]. (fellows)
+
+2012-11-06 (bug fix)[3581754] avoid multiple callback on keep-alive (fellows)
+=> http 2.8.5
+
+2012-11-07 tzdata updated to Olson's tzdata2012i (kenny)
+
+2012-11-13 (bug fix)[3567063] thread fp settings from master (mistachkin)
+
+2012-11-14 (bug fix)[2933003] tempfile creation in $TMPDIR (fellows)
+
+2012-11-15 (TIP 416) New [load] options -global and -lazy (nijtmans)
+
+2012-11-20 (bug fix)[3033307] base64 trail whitespace (kovalenko,goth)
+
+2012-12-03 (bug fix) [configure] query broke init from argv (porter)
+=> tcltest 2.3.5
+
+2012-12-13 (bug fix)[3595576] crash: [catch {} -> noSuchNs::var] (sofer,porter)
+
+2012-12-13 (bug fix) crash: [zlib gunzip $data -header noSuchNs::var] (porter)
+
+--- Released 8.6.0, December 20, 2012 --- See ChangeLog for details ---
+
+2012-12-22 (bug fix)[3598150] DString to Tcl_Obj memleak (afredd)
+
+2012-12-27 (bug fix)[3598580] Tcl_ListObjReplace() refcount fix (nijtmans)
+
+2013-01-04 (bug fix) memleak in [format] compiler (fellows)
+
+2013-01-08 (bug fix)[3092089,3587096] [file normalize] on junction points
+
+2013-01-09 (bug fix)[3599395] status line processing (nijtmans)
+2013-01-23 (bug fix)[2911139] repair async connection management (fellows)
+=> http 2.8.6
+
+2013-01-26 (bug fix)[3601804] Darwin segfault platformCPUID (nijtmans)
+
+2013-01-28 (enhancement) improve ensemble bytecode (fellows)
+
+2013-01-30 (enhancement) selected script code improvements (fradin)
+=> tcltest 2.3.6
+
+2013-01-30 (bug fix)[3599098] update to handle glibc banner changes (kupries)
+=> platform 1.0.11
+
+2013-01-31 (bug fix)[3598282] make install DESTDIR support (cassoff)
+
+2013-02-05 (bug fix)[3603434] [file normalize a:/] flaw in VFS (porter,griffin)
+
+2013-02-09 (bug fix)[3603695] $obj varname resolution rules (venable,fellows)
+
+2013-02-11 (bug fix)[3603553] zlib flushing errors (vampiera,fellows)
+
+2013-02-14 (bug fix)[3604576] msgcat use of Windows registry (oehlmann,nijtmans)
+=> msgcat 1.5.1
+
+2013-02-19 (bug fix)[2438181] report errors in trace handlers (yorick)
+
+2013-02-21 (bug fix)[3605447] unbreak [namespace export -clear] (porter)
+
+2013-02-23 (bug fix)[3599194] fallback IPv6 routines (afredd,max)
+
+2013-02-27 (bug fix)[3606139] stop crash in [regexp] (lane)
+
+2013-03-03 (bug fix)[3606258] major serial port update (english)
+
+2013-03-06 (bug fix)[3606683] [regexp (((((a)*)*)*)*)* {}] hangs
+(grathwohl,lane,porter)
+
+2013-03-12 (enhancement) better build support for Debian arch (shadura)
+
+2013-03-19 (bug fix)[2893771] [file stat] on locked files (thoyts,nijtmans)
+
+2013-03-21 (bug fix)[2102614] [auto_mkindex] ensemble support (griffin)
+
+2013-03-27 Tcl_Zlib*() routines tolerate NULL interps (porter
+
+2013-04-04 (bug fix) Support URLs with query but no path (max)
+=> http 2.8.7
+
+2013-04-08 (bug fix)[3610026] regexp crash on color overflow (linnakangas)
+
+2013-04-29 (enhancement) [array set] compile improvement (fellows)
+
+2013-04-30 (enhancement) broaden glibc version detection (kupries)
+=> platform 1.0.12
+
+2013-05-06 (platform support) Cygwin64 (nijtmans)
+
+2013-05-15 (enhancement) Improved [list {*}...] compile (fellows)
+
+2013-05-16 (platform support) mingw-4.0 (nijtmans)
+
+2013-05-19 (platform support) FreeBSD updates (cerutti)
+
+2013-05-20 (bug fix)[3613567] access error temp file creation (keene)
+
+2013-05-20 (bug fix)[3613569] temp file open fail can crash [load] (keene)
+
+2013-05-22 (bug fix)[3613609] [lsort -nocase] failed on non-ASCII (fellows)
+
+2013-05-28 (bug fix)[3036566] Use language packs (Vista+) locale (oehlmann)
+=> msgcat 1.5.2
+
+2013-05-29 (bug fix)[3614102] [apply {{} {list [if 1]}}] stack woes (porter)
+
+2013-06-03 Restored lost performance appending to long strings (elby,porter)
+
+2013-06-05 (bug fix)[2835313] [while 1 {foo [continue]}] crash (fellows)
+
+2013-06-17 (bug fix)[a876646] [:cntrl:] includes \x00 to \x1f (nijtmans)
+
+2013-06-27 (bug fix)[983509] missing encodings for config values (nijtmans)
+
+2013-06-27 (bug fix)[34538b] apply DST in 2099 (lang)
+
+2013-07-02 (bug fix)[32afa6] corrected dirent64 check (griffin)
+
+2013-07-06 tzdata updated to Olson's tzdata2013d (kenny)
+
+2013-07-10 (bug fix)[86fb5e] [info frame] in compiled ensembles (porter)
+
+2013-07-18 (bug fix)[1c17fb] revisd syntax errorinfo that shows error (porter)
+
+2013-07-26 (bug fix)[6585b2] regexp {(\w).*?\1} abb (lane)
+
+2013-07-29 [string is space \u202f] => 1 (nijtmans)
+
+2013-08-01 [a0bc85] Limited support for fork with threads (for Rivet) (nijtmans)
+
+2013-08-01 (bug fix)[1905562] RE recursion limit increased to support
+reported usage of large expressions (porter)
+
+2013-08-02 (bug fix)[9d6162] superclass slot empty crash (vdgoot,fellows)2013-08-02 (bug fix)[9d6162] superclass slot empty crash (vdgoot,fellows)
+
+2013-08-03 (enhancement)[3611643] [auto_mkindex] support TclOO (fellows)
+
+2013-08-14 (bug fix)[a16752] Missing command delete callbacks (porter)
+
+2013-08-15 (bug fix)[3610404] reresolve traced forwards (porter)
+
+2013-08-15 Errors from execution traces become errors of the command (porter)
+
+2013-08-23 (bug fix)[8ff0cb9] Tcl_NR*Eval*() schedule only, as doc'd (porter)
+
+2013-08-29 (bug fix)[2486550] enable [interp invokehidden {} yield] (porter)
+
+2013-09-01 (bug fix)[b98fa55] [binary decode] fail on whitespace (reche,fellows)
+
+2013-09-07 (bug fix)[86ceb4] have tm path favor first provider (neumann,porter)
+
+2013-09-09 (bug fix)[3609693] copied object member variable confusion (fellows)
+=> TclOO 1.0.1
+
+2013-09-17 (bug fix)[2152292] [binary encode uuencode] corrected (fellows)
+
+2013-09-19 (bug fix)[3487626] segfaults in [dict] compilers (porter)
+
+2013-09-19 (bug fix)[31661d2] mem leak in [lreplace] (ade,porter)
+
+Many optmizations, improvements, and tightened stack management in bytecode.
+
+--- Released 8.6.1, Septemer 20, 2013 --- http://core.tcl.tk/tcl/ for details
diff --git a/compat/dirent2.h b/compat/dirent2.h
index 878457f..5be08ba 100644
--- a/compat/dirent2.h
+++ b/compat/dirent2.h
@@ -14,8 +14,6 @@
#ifndef _DIRENT
#define _DIRENT
-#include "tcl.h"
-
/*
* Dirent structure, which holds information about a single
* directory entry.
diff --git a/compat/dlfcn.h b/compat/dlfcn.h
index 6940c2a..fb27ea0 100644
--- a/compat/dlfcn.h
+++ b/compat/dlfcn.h
@@ -26,8 +26,6 @@
#ifndef __dlfcn_h__
#define __dlfcn_h__
-#include "tcl.h"
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/compat/fake-rfc2553.c b/compat/fake-rfc2553.c
index 666144f..3b91041 100644
--- a/compat/fake-rfc2553.c
+++ b/compat/fake-rfc2553.c
@@ -84,7 +84,7 @@ int fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
if (host != NULL) {
if (flags & NI_NUMERICHOST) {
- int len;
+ size_t len;
Tcl_MutexLock(&netdbMutex);
len = strlcpy(host, inet_ntoa(sin->sin_addr), hostlen);
Tcl_MutexUnlock(&netdbMutex);
@@ -135,7 +135,7 @@ fake_gai_strerror(int err)
#ifndef HAVE_FREEADDRINFO
void
-freeaddrinfo(struct addrinfo *ai)
+fake_freeaddrinfo(struct addrinfo *ai)
{
struct addrinfo *next;
@@ -199,7 +199,7 @@ fake_getaddrinfo(const char *hostname, const char *servname,
port = strtol(servname, &cp, 10);
if (port > 0 && port <= 65535 && *cp == '\0')
- port = htons(port);
+ port = htons((unsigned short)port);
else if ((sp = getservbyname(servname, NULL)) != NULL)
port = sp->s_port;
else
diff --git a/compat/string.h b/compat/string.h
index 84ee094..42be10c 100644
--- a/compat/string.h
+++ b/compat/string.h
@@ -13,8 +13,6 @@
#ifndef _STRING
#define _STRING
-#include "tcl.h"
-
/*
* The following #include is needed to define size_t. (This used to include
* sys/stdtypes.h but that doesn't exist on older versions of SunOS, e.g.
diff --git a/compat/unistd.h b/compat/unistd.h
index 6779e74..2de5bd0 100644
--- a/compat/unistd.h
+++ b/compat/unistd.h
@@ -14,7 +14,6 @@
#ifndef _UNISTD
#define _UNISTD
-#include "tcl.h"
#include <sys/types.h>
#ifndef NULL
diff --git a/compat/zlib/CMakeLists.txt b/compat/zlib/CMakeLists.txt
index a64fe0b..0c0247c 100644
--- a/compat/zlib/CMakeLists.txt
+++ b/compat/zlib/CMakeLists.txt
@@ -3,9 +3,16 @@ set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
project(zlib C)
-if(NOT DEFINED BUILD_SHARED_LIBS)
- option(BUILD_SHARED_LIBS "Build a shared library form of zlib" ON)
-endif()
+set(VERSION "1.2.8")
+
+option(ASM686 "Enable building i686 assembly implementation")
+option(AMD64 "Enable building amd64 assembly implementation")
+
+set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables")
+set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries")
+set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers")
+set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages")
+set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")
include(CheckTypeSize)
include(CheckFunctionExists)
@@ -56,23 +63,27 @@ if(MSVC)
set(CMAKE_DEBUG_POSTFIX "d")
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
+ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
endif()
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
# If we're doing an out of source build and the user has a zconf.h
# in their source tree...
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h)
- message(FATAL_ERROR
- "You must remove ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h "
- "from the source tree. This file is included with zlib "
- "but CMake generates this file for you automatically "
- "in the build directory.")
+ message(STATUS "Renaming")
+ message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h")
+ message(STATUS "to 'zconf.h.included' because this file is included with zlib")
+ message(STATUS "but CMake generates it automatically in the build directory.")
+ file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included)
endif()
endif()
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein
- ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY)
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
+set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc)
+configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein
+ ${ZLIB_PC} @ONLY)
+configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein
+ ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY)
+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})
#============================================================================
@@ -110,29 +121,71 @@ set(ZLIB_SRCS
trees.c
uncompr.c
zutil.c
- win32/zlib1.rc
)
+if(NOT MINGW)
+ set(ZLIB_DLL_SRCS
+ win32/zlib1.rc # If present will override custom build rule below.
+ )
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCC)
+ if(ASM686)
+ set(ZLIB_ASMS contrib/asm686/match.S)
+ elseif (AMD64)
+ set(ZLIB_ASMS contrib/amd64/amd64-match.S)
+ endif ()
+
+ if(ZLIB_ASMS)
+ add_definitions(-DASMV)
+ set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE)
+ endif()
+endif()
+
+if(MSVC)
+ if(ASM686)
+ ENABLE_LANGUAGE(ASM_MASM)
+ set(ZLIB_ASMS
+ contrib/masmx86/inffas32.asm
+ contrib/masmx86/match686.asm
+ )
+ elseif (AMD64)
+ ENABLE_LANGUAGE(ASM_MASM)
+ set(ZLIB_ASMS
+ contrib/masmx64/gvmat64.asm
+ contrib/masmx64/inffasx64.asm
+ )
+ endif()
+
+ if(ZLIB_ASMS)
+ add_definitions(-DASMV -DASMINF)
+ endif()
+endif()
+
# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents)
-string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([0-9A-Za-z.]+)\".*"
+string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*"
"\\1" ZLIB_FULL_VERSION ${_zlib_h_contents})
if(MINGW)
# This gets us DLL resource information when compiling on MinGW.
+ if(NOT CMAKE_RC_COMPILER)
+ set(CMAKE_RC_COMPILER windres.exe)
+ endif()
+
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
- COMMAND windres.exe
+ COMMAND ${CMAKE_RC_COMPILER}
-D GCC_WINDRES
-I ${CMAKE_CURRENT_SOURCE_DIR}
-I ${CMAKE_CURRENT_BINARY_DIR}
-o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
-i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc)
- set(ZLIB_SRCS ${ZLIB_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)
+ set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)
endif(MINGW)
-add_library(zlib ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
+add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
+add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL)
-
set_target_properties(zlib PROPERTIES SOVERSION 1)
if(NOT CYGWIN)
@@ -148,43 +201,49 @@ endif()
if(UNIX)
# On unix-like platforms the library is almost always called libz
- set_target_properties(zlib PROPERTIES OUTPUT_NAME z)
+ set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z)
+ if(NOT APPLE)
+ set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"")
+ endif()
elseif(BUILD_SHARED_LIBS AND WIN32)
# Creates zlib1.dll when building shared library version
set_target_properties(zlib PROPERTIES SUFFIX "1.dll")
endif()
if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
- install(TARGETS zlib
- RUNTIME DESTINATION bin
- ARCHIVE DESTINATION lib
- LIBRARY DESTINATION lib )
+ install(TARGETS zlib zlibstatic
+ RUNTIME DESTINATION "${INSTALL_BIN_DIR}"
+ ARCHIVE DESTINATION "${INSTALL_LIB_DIR}"
+ LIBRARY DESTINATION "${INSTALL_LIB_DIR}" )
endif()
if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )
- install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION include)
+ install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}")
+endif()
+if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
+ install(FILES zlib.3 DESTINATION "${INSTALL_MAN_DIR}/man3")
endif()
if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
- install(FILES zlib.3 DESTINATION share/man/man3)
+ install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}")
endif()
#============================================================================
# Example binaries
#============================================================================
-add_executable(example example.c)
+add_executable(example test/example.c)
target_link_libraries(example zlib)
add_test(example example)
-add_executable(minigzip minigzip.c)
+add_executable(minigzip test/minigzip.c)
target_link_libraries(minigzip zlib)
if(HAVE_OFF64_T)
- add_executable(example64 example.c)
+ add_executable(example64 test/example.c)
target_link_libraries(example64 zlib)
set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
add_test(example64 example64)
- add_executable(minigzip64 minigzip.c)
+ add_executable(minigzip64 test/minigzip.c)
target_link_libraries(minigzip64 zlib)
set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
endif()
diff --git a/compat/zlib/ChangeLog b/compat/zlib/ChangeLog
index fc61964..f22aaba 100644
--- a/compat/zlib/ChangeLog
+++ b/compat/zlib/ChangeLog
@@ -1,12 +1,276 @@
ChangeLog file for zlib
+Changes in 1.2.8 (28 Apr 2013)
+- Update contrib/minizip/iowin32.c for Windows RT [Vollant]
+- Do not force Z_CONST for C++
+- Clean up contrib/vstudio [Ro§]
+- Correct spelling error in zlib.h
+- Fix mixed line endings in contrib/vstudio
+
+Changes in 1.2.7.3 (13 Apr 2013)
+- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc
+
+Changes in 1.2.7.2 (13 Apr 2013)
+- Change check for a four-byte type back to hexadecimal
+- Fix typo in win32/Makefile.msc
+- Add casts in gzwrite.c for pointer differences
+
+Changes in 1.2.7.1 (24 Mar 2013)
+- Replace use of unsafe string functions with snprintf if available
+- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink]
+- Fix gzgetc undefine when Z_PREFIX set [Turk]
+- Eliminate use of mktemp in Makefile (not always available)
+- Fix bug in 'F' mode for gzopen()
+- Add inflateGetDictionary() function
+- Correct comment in deflate.h
+- Use _snprintf for snprintf in Microsoft C
+- On Darwin, only use /usr/bin/libtool if libtool is not Apple
+- Delete "--version" file if created by "ar --version" [Richard G.]
+- Fix configure check for veracity of compiler error return codes
+- Fix CMake compilation of static lib for MSVC2010 x64
+- Remove unused variable in infback9.c
+- Fix argument checks in gzlog_compress() and gzlog_write()
+- Clean up the usage of z_const and respect const usage within zlib
+- Clean up examples/gzlog.[ch] comparisons of different types
+- Avoid shift equal to bits in type (caused endless loop)
+- Fix unintialized value bug in gzputc() introduced by const patches
+- Fix memory allocation error in examples/zran.c [Nor]
+- Fix bug where gzopen(), gzclose() would write an empty file
+- Fix bug in gzclose() when gzwrite() runs out of memory
+- Check for input buffer malloc failure in examples/gzappend.c
+- Add note to contrib/blast to use binary mode in stdio
+- Fix comparisons of differently signed integers in contrib/blast
+- Check for invalid code length codes in contrib/puff
+- Fix serious but very rare decompression bug in inftrees.c
+- Update inflateBack() comments, since inflate() can be faster
+- Use underscored I/O function names for WINAPI_FAMILY
+- Add _tr_flush_bits to the external symbols prefixed by --zprefix
+- Add contrib/vstudio/vc10 pre-build step for static only
+- Quote --version-script argument in CMakeLists.txt
+- Don't specify --version-script on Apple platforms in CMakeLists.txt
+- Fix casting error in contrib/testzlib/testzlib.c
+- Fix types in contrib/minizip to match result of get_crc_table()
+- Simplify contrib/vstudio/vc10 with 'd' suffix
+- Add TOP support to win32/Makefile.msc
+- Suport i686 and amd64 assembler builds in CMakeLists.txt
+- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h
+- Add vc11 and vc12 build files to contrib/vstudio
+- Add gzvprintf() as an undocumented function in zlib
+- Fix configure for Sun shell
+- Remove runtime check in configure for four-byte integer type
+- Add casts and consts to ease user conversion to C++
+- Add man pages for minizip and miniunzip
+- In Makefile uninstall, don't rm if preceding cd fails
+- Do not return Z_BUF_ERROR if deflateParam() has nothing to write
+
+Changes in 1.2.7 (2 May 2012)
+- Replace use of memmove() with a simple copy for portability
+- Test for existence of strerror
+- Restore gzgetc_ for backward compatibility with 1.2.6
+- Fix build with non-GNU make on Solaris
+- Require gcc 4.0 or later on Mac OS X to use the hidden attribute
+- Include unistd.h for Watcom C
+- Use __WATCOMC__ instead of __WATCOM__
+- Do not use the visibility attribute if NO_VIZ defined
+- Improve the detection of no hidden visibility attribute
+- Avoid using __int64 for gcc or solo compilation
+- Cast to char * in gzprintf to avoid warnings [Zinser]
+- Fix make_vms.com for VAX [Zinser]
+- Don't use library or built-in byte swaps
+- Simplify test and use of gcc hidden attribute
+- Fix bug in gzclose_w() when gzwrite() fails to allocate memory
+- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen()
+- Fix bug in test/minigzip.c for configure --solo
+- Fix contrib/vstudio project link errors [Mohanathas]
+- Add ability to choose the builder in make_vms.com [Schweda]
+- Add DESTDIR support to mingw32 win32/Makefile.gcc
+- Fix comments in win32/Makefile.gcc for proper usage
+- Allow overriding the default install locations for cmake
+- Generate and install the pkg-config file with cmake
+- Build both a static and a shared version of zlib with cmake
+- Include version symbols for cmake builds
+- If using cmake with MSVC, add the source directory to the includes
+- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta]
+- Move obsolete emx makefile to old [Truta]
+- Allow the use of -Wundef when compiling or using zlib
+- Avoid the use of the -u option with mktemp
+- Improve inflate() documentation on the use of Z_FINISH
+- Recognize clang as gcc
+- Add gzopen_w() in Windows for wide character path names
+- Rename zconf.h in CMakeLists.txt to move it out of the way
+- Add source directory in CMakeLists.txt for building examples
+- Look in build directory for zlib.pc in CMakeLists.txt
+- Remove gzflags from zlibvc.def in vc9 and vc10
+- Fix contrib/minizip compilation in the MinGW environment
+- Update ./configure for Solaris, support --64 [Mooney]
+- Remove -R. from Solaris shared build (possible security issue)
+- Avoid race condition for parallel make (-j) running example
+- Fix type mismatch between get_crc_table() and crc_table
+- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler]
+- Fix the path to zlib.map in CMakeLists.txt
+- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe]
+- Add instructions to win32/Makefile.gcc for shared install [Torri]
+
+Changes in 1.2.6.1 (12 Feb 2012)
+- Avoid the use of the Objective-C reserved name "id"
+- Include io.h in gzguts.h for Microsoft compilers
+- Fix problem with ./configure --prefix and gzgetc macro
+- Include gz_header definition when compiling zlib solo
+- Put gzflags() functionality back in zutil.c
+- Avoid library header include in crc32.c for Z_SOLO
+- Use name in GCC_CLASSIC as C compiler for coverage testing, if set
+- Minor cleanup in contrib/minizip/zip.c [Vollant]
+- Update make_vms.com [Zinser]
+- Remove unnecessary gzgetc_ function
+- Use optimized byte swap operations for Microsoft and GNU [Snyder]
+- Fix minor typo in zlib.h comments [Rzesniowiecki]
+
+Changes in 1.2.6 (29 Jan 2012)
+- Update the Pascal interface in contrib/pascal
+- Fix function numbers for gzgetc_ in zlibvc.def files
+- Fix configure.ac for contrib/minizip [Schiffer]
+- Fix large-entry detection in minizip on 64-bit systems [Schiffer]
+- Have ./configure use the compiler return code for error indication
+- Fix CMakeLists.txt for cross compilation [McClure]
+- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes]
+- Fix compilation of contrib/minizip on FreeBSD [Marquez]
+- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath]
+- Include io.h for Turbo C / Borland C on all platforms [Truta]
+- Make version explicit in contrib/minizip/configure.ac [Bosmans]
+- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant]
+- Minor cleanup up contrib/minizip/unzip.c [Vollant]
+- Fix bug when compiling minizip with C++ [Vollant]
+- Protect for long name and extra fields in contrib/minizip [Vollant]
+- Avoid some warnings in contrib/minizip [Vollant]
+- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip
+- Add missing libs to minizip linker command
+- Add support for VPATH builds in contrib/minizip
+- Add an --enable-demos option to contrib/minizip/configure
+- Add the generation of configure.log by ./configure
+- Exit when required parameters not provided to win32/Makefile.gcc
+- Have gzputc return the character written instead of the argument
+- Use the -m option on ldconfig for BSD systems [Tobias]
+- Correct in zlib.map when deflateResetKeep was added
+
+Changes in 1.2.5.3 (15 Jan 2012)
+- Restore gzgetc function for binary compatibility
+- Do not use _lseeki64 under Borland C++ [Truta]
+- Update win32/Makefile.msc to build test/*.c [Truta]
+- Remove old/visualc6 given CMakefile and other alternatives
+- Update AS400 build files and documentation [Monnerat]
+- Update win32/Makefile.gcc to build test/*.c [Truta]
+- Permit stronger flushes after Z_BLOCK flushes
+- Avoid extraneous empty blocks when doing empty flushes
+- Permit Z_NULL arguments to deflatePending
+- Allow deflatePrime() to insert bits in the middle of a stream
+- Remove second empty static block for Z_PARTIAL_FLUSH
+- Write out all of the available bits when using Z_BLOCK
+- Insert the first two strings in the hash table after a flush
+
+Changes in 1.2.5.2 (17 Dec 2011)
+- fix ld error: unable to find version dependency 'ZLIB_1.2.5'
+- use relative symlinks for shared libs
+- Avoid searching past window for Z_RLE strategy
+- Assure that high-water mark initialization is always applied in deflate
+- Add assertions to fill_window() in deflate.c to match comments
+- Update python link in README
+- Correct spelling error in gzread.c
+- Fix bug in gzgets() for a concatenated empty gzip stream
+- Correct error in comment for gz_make()
+- Change gzread() and related to ignore junk after gzip streams
+- Allow gzread() and related to continue after gzclearerr()
+- Allow gzrewind() and gzseek() after a premature end-of-file
+- Simplify gzseek() now that raw after gzip is ignored
+- Change gzgetc() to a macro for speed (~40% speedup in testing)
+- Fix gzclose() to return the actual error last encountered
+- Always add large file support for windows
+- Include zconf.h for windows large file support
+- Include zconf.h.cmakein for windows large file support
+- Update zconf.h.cmakein on make distclean
+- Merge vestigial vsnprintf determination from zutil.h to gzguts.h
+- Clarify how gzopen() appends in zlib.h comments
+- Correct documentation of gzdirect() since junk at end now ignored
+- Add a transparent write mode to gzopen() when 'T' is in the mode
+- Update python link in zlib man page
+- Get inffixed.h and MAKEFIXED result to match
+- Add a ./config --solo option to make zlib subset with no libary use
+- Add undocumented inflateResetKeep() function for CAB file decoding
+- Add --cover option to ./configure for gcc coverage testing
+- Add #define ZLIB_CONST option to use const in the z_stream interface
+- Add comment to gzdopen() in zlib.h to use dup() when using fileno()
+- Note behavior of uncompress() to provide as much data as it can
+- Add files in contrib/minizip to aid in building libminizip
+- Split off AR options in Makefile.in and configure
+- Change ON macro to Z_ARG to avoid application conflicts
+- Facilitate compilation with Borland C++ for pragmas and vsnprintf
+- Include io.h for Turbo C / Borland C++
+- Move example.c and minigzip.c to test/
+- Simplify incomplete code table filling in inflate_table()
+- Remove code from inflate.c and infback.c that is impossible to execute
+- Test the inflate code with full coverage
+- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw)
+- Add deflateResetKeep and fix inflateResetKeep to retain dictionary
+- Fix gzwrite.c to accommodate reduced memory zlib compilation
+- Have inflate() with Z_FINISH avoid the allocation of a window
+- Do not set strm->adler when doing raw inflate
+- Fix gzeof() to behave just like feof() when read is not past end of file
+- Fix bug in gzread.c when end-of-file is reached
+- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF
+- Document gzread() capability to read concurrently written files
+- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo]
+
+Changes in 1.2.5.1 (10 Sep 2011)
+- Update FAQ entry on shared builds (#13)
+- Avoid symbolic argument to chmod in Makefile.in
+- Fix bug and add consts in contrib/puff [Oberhumer]
+- Update contrib/puff/zeros.raw test file to have all block types
+- Add full coverage test for puff in contrib/puff/Makefile
+- Fix static-only-build install in Makefile.in
+- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno]
+- Add libz.a dependency to shared in Makefile.in for parallel builds
+- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out
+- Replace $(...) with `...` in configure for non-bash sh [Bowler]
+- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen]
+- Add solaris* to Linux* in configure to allow gcc use [Groffen]
+- Add *bsd* to Linux* case in configure [Bar-Lev]
+- Add inffast.obj to dependencies in win32/Makefile.msc
+- Correct spelling error in deflate.h [Kohler]
+- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc
+- Add test to configure for GNU C looking for gcc in output of $cc -v
+- Add zlib.pc generation to win32/Makefile.gcc [Weigelt]
+- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not
+- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense
+- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser)
+- Make stronger test in zconf.h to include unistd.h for LFS
+- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack]
+- Fix zlib.h LFS support when Z_PREFIX used
+- Add updated as400 support (removed from old) [Monnerat]
+- Avoid deflate sensitivity to volatile input data
+- Avoid division in adler32_combine for NO_DIVIDE
+- Clarify the use of Z_FINISH with deflateBound() amount of space
+- Set binary for output file in puff.c
+- Use u4 type for crc_table to avoid conversion warnings
+- Apply casts in zlib.h to avoid conversion warnings
+- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller]
+- Improve inflateSync() documentation to note indeterminancy
+- Add deflatePending() function to return the amount of pending output
+- Correct the spelling of "specification" in FAQ [Randers-Pehrson]
+- Add a check in configure for stdarg.h, use for gzprintf()
+- Check that pointers fit in ints when gzprint() compiled old style
+- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler]
+- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt]
+- Add debug records in assmebler code [Londer]
+- Update RFC references to use http://tools.ietf.org/html/... [Li]
+- Add --archs option, use of libtool to configure for Mac OS X [Borstel]
+
Changes in 1.2.5 (19 Apr 2010)
- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev]
- Default to libdir as sharedlibdir in configure [Nieder]
- Update copyright dates on modified source files
- Update trees.c to be able to generate modified trees.h
- Exit configure for MinGW, suggesting win32/Makefile.gcc
+- Check for NULL path in gz_open [Homurlu]
Changes in 1.2.4.5 (18 Apr 2010)
- Set sharedlibdir in configure [Torok]
@@ -261,7 +525,7 @@ Changes in 1.2.3.4 (21 Dec 2009)
- Clear bytes after deflate lookahead to avoid use of uninitialized data
- Change a limit in inftrees.c to be more transparent to Coverity Prevent
- Update win32/zlib.def with exported symbols from zlib.h
-- Correct spelling error in zlib.h [Willem]
+- Correct spelling errors in zlib.h [Willem, Sobrado]
- Allow Z_BLOCK for deflate() to force a new block
- Allow negative bits in inflatePrime() to delete existing bit buffer
- Add Z_TREES flush option to inflate() to return at end of trees
@@ -952,7 +1216,7 @@ Changes in 1.0.6 (19 Jan 1998)
- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
- added makelcc.bat for lcc-win32 (Tom St Denis)
- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
-- Avoid expanded $Id: ChangeLog,v 1.4 2010/04/20 14:50:10 nijtmans Exp $. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
- check for unistd.h in configure (for off_t)
- remove useless check parameter in inflate_blocks_free
- avoid useless assignment of s->check to itself in inflate_blocks_new
diff --git a/compat/zlib/FAQ b/compat/zlib/FAQ
index 1a22750..99b7cf9 100644
--- a/compat/zlib/FAQ
+++ b/compat/zlib/FAQ
@@ -44,8 +44,8 @@ The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
6. Where's the zlib documentation (man pages, etc.)?
- It's in zlib.h . Examples of zlib usage are in the files example.c and
- minigzip.c, with more in examples/ .
+ It's in zlib.h . Examples of zlib usage are in the files test/example.c
+ and test/minigzip.c, with more in examples/ .
7. Why don't you use GNU autoconf or libtool or ...?
@@ -84,8 +84,10 @@ The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
13. How can I make a Unix shared library?
- make clean
- ./configure -s
+ By default a shared (and a static) library is built for Unix. So:
+
+ make distclean
+ ./configure
make
14. How do I install a shared zlib library on Unix?
@@ -325,7 +327,7 @@ The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
correctly points to the zlib specification in RFC 1950 for the "deflate"
transfer encoding, there have been reports of servers and browsers that
incorrectly produce or expect raw deflate data per the deflate
- specficiation in RFC 1951, most notably Microsoft. So even though the
+ specification in RFC 1951, most notably Microsoft. So even though the
"deflate" transfer encoding using the zlib format would be the more
efficient approach (and in fact exactly what the zlib format was designed
for), using the "gzip" transfer encoding is probably more reliable due to
diff --git a/compat/zlib/INDEX b/compat/zlib/INDEX
index f6c51ca..2ba0641 100644
--- a/compat/zlib/INDEX
+++ b/compat/zlib/INDEX
@@ -7,6 +7,9 @@ Makefile.in template for Unix Makefile
README guess what
configure configure script for Unix
make_vms.com makefile for VMS
+test/example.c zlib usages examples for build testing
+test/minigzip.c minimal gzip-like functionality for build testing
+test/infcover.c inf*.c code coverage for build coverage testing
treebuild.xml XML description of source file dependencies
zconf.h.cmakein zconf.h template for cmake
zconf.h.in zconf.h template for configure
@@ -14,9 +17,11 @@ zlib.3 Man page for zlib
zlib.3.pdf Man page in PDF format
zlib.map Linux symbol information
zlib.pc.in Template for pkg-config descriptor
+zlib.pc.cmakein zlib.pc template for cmake
zlib2ansi perl script to convert source files for C++ compilation
amiga/ makefiles for Amiga SAS C
+as400/ makefiles for AS/400
doc/ documentation for formats and algorithms
msdos/ makefiles for MSDOS
nintendods/ makefile for Nintendo DS
@@ -56,10 +61,8 @@ uncompr.c
zutil.c
zutil.h
- source files for sample programs:
-example.c
-minigzip.c
-See examples/README.examples for more
+ source files for sample programs
+See examples/README.examples
- unsupported contribution by third parties
+ unsupported contributions by third parties
See contrib/README.contrib
diff --git a/compat/zlib/Makefile.in b/compat/zlib/Makefile.in
index 5b15bd0..c61aa30 100644
--- a/compat/zlib/Makefile.in
+++ b/compat/zlib/Makefile.in
@@ -1,5 +1,5 @@
# Makefile for zlib
-# Copyright (C) 1995-2010 Jean-loup Gailly.
+# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler
# For conditions of distribution and use, see copyright notice in zlib.h
# To compile and test, type:
@@ -32,11 +32,12 @@ CPP=$(CC) -E
STATICLIB=libz.a
SHAREDLIB=libz.so
-SHAREDLIBV=libz.so.1.2.5
+SHAREDLIBV=libz.so.1.2.8
SHAREDLIBM=libz.so.1
LIBS=$(STATICLIB) $(SHAREDLIBV)
-AR=ar rc
+AR=ar
+ARFLAGS=rc
RANLIB=ranlib
LDCONFIG=ldconfig
LDSHAREDLIBC=-lc
@@ -53,11 +54,13 @@ mandir = ${prefix}/share/man
man3dir = ${mandir}/man3
pkgconfigdir = ${libdir}/pkgconfig
-OBJC = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \
- gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
+OBJZ = adler32.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o
+OBJG = compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o
+OBJC = $(OBJZ) $(OBJG)
-PIC_OBJC = adler32.lo compress.lo crc32.lo deflate.lo gzclose.lo gzlib.lo gzread.lo \
- gzwrite.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo uncompr.lo zutil.lo
+PIC_OBJZ = adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo
+PIC_OBJG = compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo
+PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG)
# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo
OBJA =
@@ -80,35 +83,49 @@ check: test
test: all teststatic testshared
teststatic: static
- @if echo hello world | ./minigzip | ./minigzip -d && ./example; then \
+ @TMPST=tmpst_$$; \
+ if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \
echo ' *** zlib test OK ***'; \
else \
echo ' *** zlib test FAILED ***'; false; \
- fi
- -@rm -f foo.gz
+ fi; \
+ rm -f $$TMPST
testshared: shared
@LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \
DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \
SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \
- if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh; then \
+ TMPSH=tmpsh_$$; \
+ if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \
echo ' *** zlib shared test OK ***'; \
else \
echo ' *** zlib shared test FAILED ***'; false; \
- fi
- -@rm -f foo.gz
+ fi; \
+ rm -f $$TMPSH
test64: all64
- @if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64; then \
+ @TMP64=tmp64_$$; \
+ if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \
echo ' *** zlib 64-bit test OK ***'; \
else \
echo ' *** zlib 64-bit test FAILED ***'; false; \
- fi
- -@rm -f foo.gz
+ fi; \
+ rm -f $$TMP64
+
+infcover.o: test/infcover.c zlib.h zconf.h
+ $(CC) $(CFLAGS) -I. -c -o $@ test/infcover.c
+
+infcover: infcover.o libz.a
+ $(CC) $(CFLAGS) -o $@ infcover.o libz.a
+
+cover: infcover
+ rm -f *.gcda
+ ./infcover
+ gcov inf*.c
libz.a: $(OBJS)
- $(AR) $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
-@ ($(RANLIB) $@ || true) >/dev/null 2>&1
match.o: match.S
@@ -123,11 +140,17 @@ match.lo: match.S
mv _match.o match.lo
rm -f _match.s
-example64.o: example.c zlib.h zconf.h
- $(CC) $(CFLAGS) -D_FILE_OFFSET_BITS=64 -c -o $@ example.c
+example.o: test/example.c zlib.h zconf.h
+ $(CC) $(CFLAGS) -I. -c -o $@ test/example.c
+
+minigzip.o: test/minigzip.c zlib.h zconf.h
+ $(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c
+
+example64.o: test/example.c zlib.h zconf.h
+ $(CC) $(CFLAGS) -I. -D_FILE_OFFSET_BITS=64 -c -o $@ test/example.c
-minigzip64.o: minigzip.c zlib.h zconf.h
- $(CC) $(CFLAGS) -D_FILE_OFFSET_BITS=64 -c -o $@ minigzip.c
+minigzip64.o: test/minigzip.c zlib.h zconf.h
+ $(CC) $(CFLAGS) -I. -D_FILE_OFFSET_BITS=64 -c -o $@ test/minigzip.c
.SUFFIXES: .lo
@@ -136,7 +159,7 @@ minigzip64.o: minigzip.c zlib.h zconf.h
$(CC) $(SFLAGS) -DPIC -c -o objs/$*.o $<
-@mv objs/$*.o $@
-$(SHAREDLIBV): $(PIC_OBJS)
+placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a
$(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS)
rm -f $(SHAREDLIB) $(SHAREDLIBM)
ln -s $@ $(SHAREDLIB)
@@ -168,14 +191,16 @@ install-libs: $(LIBS)
-@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi
-@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi
cp $(STATICLIB) $(DESTDIR)$(libdir)
- cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)
- cd $(DESTDIR)$(libdir); chmod u=rw,go=r $(STATICLIB)
- -@(cd $(DESTDIR)$(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1
- -@cd $(DESTDIR)$(sharedlibdir); if test "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \
- chmod 755 $(SHAREDLIBV); \
- rm -f $(SHAREDLIB) $(SHAREDLIBM); \
- ln -s $(SHAREDLIBV) $(SHAREDLIB); \
- ln -s $(SHAREDLIBV) $(SHAREDLIBM); \
+ chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB)
+ -@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1
+ -@if test -n "$(SHAREDLIBV)"; then \
+ cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \
+ echo "cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)"; \
+ chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \
+ echo "chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV)"; \
+ rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \
+ ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB); \
+ ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \
($(LDCONFIG) || true) >/dev/null 2>&1; \
fi
cp zlib.3 $(DESTDIR)$(man3dir)
@@ -191,22 +216,25 @@ install: install-libs
chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h
uninstall:
- cd $(DESTDIR)$(includedir); rm -f zlib.h zconf.h
- cd $(DESTDIR)$(libdir); rm -f libz.a; \
- if test "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \
+ cd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h
+ cd $(DESTDIR)$(libdir) && rm -f libz.a; \
+ if test -n "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \
rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
fi
- cd $(DESTDIR)$(man3dir); rm -f zlib.3
- cd $(DESTDIR)$(pkgconfigdir); rm -f zlib.pc
+ cd $(DESTDIR)$(man3dir) && rm -f zlib.3
+ cd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc
docs: zlib.3.pdf
zlib.3.pdf: zlib.3
groff -mandoc -f H -T ps zlib.3 | ps2pdf - zlib.3.pdf
-zconf.h.in: zconf.h.cmakein
- sed "/^#cmakedefine/D" < zconf.h.cmakein > zconf.h.in
- touch -r zconf.h.cmakein zconf.h.in
+zconf.h.cmakein: zconf.h.in
+ -@ TEMPFILE=zconfh_$$; \
+ echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\
+ sed -f $$TEMPFILE zconf.h.in > zconf.h.cmakein &&\
+ touch -r zconf.h.in zconf.h.cmakein &&\
+ rm $$TEMPFILE
zconf: zconf.h.in
cp -p zconf.h.in zconf.h
@@ -216,13 +244,16 @@ clean:
rm -f *.o *.lo *~ \
example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \
example64$(EXE) minigzip64$(EXE) \
+ infcover \
libz.* foo.gz so_locations \
_match.s maketree contrib/infback9/*.o
rm -rf objs
+ rm -f *.gcda *.gcno *.gcov
+ rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov
maintainer-clean: distclean
-distclean: clean zconf docs
- rm -f Makefile zlib.pc
+distclean: clean zconf zconf.h.cmakein docs
+ rm -f Makefile zlib.pc configure.log
-@rm -f .DS_Store
-@printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile
-@printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile
diff --git a/compat/zlib/README b/compat/zlib/README
index d4219bf..5ca9d12 100644
--- a/compat/zlib/README
+++ b/compat/zlib/README
@@ -1,22 +1,22 @@
ZLIB DATA COMPRESSION LIBRARY
-zlib 1.2.5 is a general purpose data compression library. All the code is
+zlib 1.2.8 is a general purpose data compression library. All the code is
thread safe. The data format used by the zlib library is described by RFCs
(Request for Comments) 1950 to 1952 in the files
-http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
-and rfc1952.txt (gzip format).
+http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
+rfc1952 (gzip format).
All functions of the compression library are documented in the file zlib.h
(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
-of the library is given in the file example.c which also tests that the library
-is working correctly. Another example is given in the file minigzip.c. The
-compression library itself is composed of all source files except example.c and
-minigzip.c.
+of the library is given in the file test/example.c which also tests that
+the library is working correctly. Another example is given in the file
+test/minigzip.c. The compression library itself is composed of all source
+files in the root directory.
To compile all files and run the test program, follow the instructions given at
the top of Makefile.in. In short "./configure; make test", and if that goes
-well, "make install" should work for most flavors of Unix. For Windows, use one
-of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
+well, "make install" should work for most flavors of Unix. For Windows, use
+one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
make_vms.com.
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
@@ -31,7 +31,7 @@ Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
issue of Dr. Dobb's Journal; a copy of the article is available at
http://marknelson.us/1997/01/01/zlib-engine/ .
-The changes made in version 1.2.5 are documented in the file ChangeLog.
+The changes made in version 1.2.8 are documented in the file ChangeLog.
Unsupported third party contributions are provided in directory contrib/ .
@@ -44,7 +44,7 @@ http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
available in Python 1.5 and later versions, see
-http://www.python.org/doc/lib/module-zlib.html .
+http://docs.python.org/library/zlib.html .
zlib is built into tcl: http://wiki.tcl.tk/4610 .
@@ -84,7 +84,7 @@ Acknowledgments:
Copyright notice:
- (C) 1995-2010 Jean-loup Gailly and Mark Adler
+ (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
diff --git a/compat/zlib/adler32.c b/compat/zlib/adler32.c
index 997020d..a868f07 100644
--- a/compat/zlib/adler32.c
+++ b/compat/zlib/adler32.c
@@ -1,17 +1,17 @@
/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2007 Mark Adler
+ * Copyright (C) 1995-2011 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-/* @(#) $Id: adler32.c,v 1.3 2010/04/20 14:50:10 nijtmans Exp $ */
+/* @(#) $Id$ */
#include "zutil.h"
#define local static
-local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
+local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
-#define BASE 65521UL /* largest prime smaller than 65536 */
+#define BASE 65521 /* largest prime smaller than 65536 */
#define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
@@ -21,39 +21,44 @@ local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8);
-/* use NO_DIVIDE if your processor does not do division in hardware */
+/* use NO_DIVIDE if your processor does not do division in hardware --
+ try it both ways to see which is faster */
#ifdef NO_DIVIDE
-# define MOD(a) \
+/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
+ (thank you to John Reiser for pointing this out) */
+# define CHOP(a) \
+ do { \
+ unsigned long tmp = a >> 16; \
+ a &= 0xffffUL; \
+ a += (tmp << 4) - tmp; \
+ } while (0)
+# define MOD28(a) \
do { \
- if (a >= (BASE << 16)) a -= (BASE << 16); \
- if (a >= (BASE << 15)) a -= (BASE << 15); \
- if (a >= (BASE << 14)) a -= (BASE << 14); \
- if (a >= (BASE << 13)) a -= (BASE << 13); \
- if (a >= (BASE << 12)) a -= (BASE << 12); \
- if (a >= (BASE << 11)) a -= (BASE << 11); \
- if (a >= (BASE << 10)) a -= (BASE << 10); \
- if (a >= (BASE << 9)) a -= (BASE << 9); \
- if (a >= (BASE << 8)) a -= (BASE << 8); \
- if (a >= (BASE << 7)) a -= (BASE << 7); \
- if (a >= (BASE << 6)) a -= (BASE << 6); \
- if (a >= (BASE << 5)) a -= (BASE << 5); \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
+ CHOP(a); \
if (a >= BASE) a -= BASE; \
} while (0)
-# define MOD4(a) \
+# define MOD(a) \
do { \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
+ CHOP(a); \
+ MOD28(a); \
+ } while (0)
+# define MOD63(a) \
+ do { /* this assumes a is not negative */ \
+ z_off64_t tmp = a >> 32; \
+ a &= 0xffffffffL; \
+ a += (tmp << 8) - (tmp << 5) + tmp; \
+ tmp = a >> 16; \
+ a &= 0xffffL; \
+ a += (tmp << 4) - tmp; \
+ tmp = a >> 16; \
+ a &= 0xffffL; \
+ a += (tmp << 4) - tmp; \
if (a >= BASE) a -= BASE; \
} while (0)
#else
# define MOD(a) a %= BASE
-# define MOD4(a) a %= BASE
+# define MOD28(a) a %= BASE
+# define MOD63(a) a %= BASE
#endif
/* ========================================================================= */
@@ -92,7 +97,7 @@ uLong ZEXPORT adler32(adler, buf, len)
}
if (adler >= BASE)
adler -= BASE;
- MOD4(sum2); /* only added so many BASE's */
+ MOD28(sum2); /* only added so many BASE's */
return adler | (sum2 << 16);
}
@@ -137,8 +142,13 @@ local uLong adler32_combine_(adler1, adler2, len2)
unsigned long sum2;
unsigned rem;
+ /* for negative len, return invalid adler32 as a clue for debugging */
+ if (len2 < 0)
+ return 0xffffffffUL;
+
/* the derivation of this formula is left as an exercise for the reader */
- rem = (unsigned)(len2 % BASE);
+ MOD63(len2); /* assumes len2 >= 0 */
+ rem = (unsigned)len2;
sum1 = adler1 & 0xffff;
sum2 = rem * sum1;
MOD(sum2);
diff --git a/compat/zlib/old/as400/bndsrc b/compat/zlib/as400/bndsrc
index 9cf94bb..98814fd 100644
--- a/compat/zlib/old/as400/bndsrc
+++ b/compat/zlib/as400/bndsrc
@@ -129,4 +129,87 @@ STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB')
EXPORT SYMBOL("zlibCompileFlags")
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.2.5 additional entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+/********************************************************************/
+/* *MODULE ADLER32 ZLIB 01/02/01 00:15:09 */
+/********************************************************************/
+
+ EXPORT SYMBOL("adler32_combine")
+ EXPORT SYMBOL("adler32_combine64")
+
+/********************************************************************/
+/* *MODULE CRC32 ZLIB 01/02/01 00:15:09 */
+/********************************************************************/
+
+ EXPORT SYMBOL("crc32_combine")
+ EXPORT SYMBOL("crc32_combine64")
+
+/********************************************************************/
+/* *MODULE GZLIB ZLIB 01/02/01 00:15:09 */
+/********************************************************************/
+
+ EXPORT SYMBOL("gzbuffer")
+ EXPORT SYMBOL("gzoffset")
+ EXPORT SYMBOL("gzoffset64")
+ EXPORT SYMBOL("gzopen64")
+ EXPORT SYMBOL("gzseek64")
+ EXPORT SYMBOL("gztell64")
+
+/********************************************************************/
+/* *MODULE GZREAD ZLIB 01/02/01 00:15:09 */
+/********************************************************************/
+
+ EXPORT SYMBOL("gzclose_r")
+
+/********************************************************************/
+/* *MODULE GZWRITE ZLIB 01/02/01 00:15:09 */
+/********************************************************************/
+
+ EXPORT SYMBOL("gzclose_w")
+
+/********************************************************************/
+/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */
+/********************************************************************/
+
+ EXPORT SYMBOL("inflateMark")
+ EXPORT SYMBOL("inflatePrime")
+ EXPORT SYMBOL("inflateReset2")
+ EXPORT SYMBOL("inflateUndermine")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.2.6 additional entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+/********************************************************************/
+/* *MODULE DEFLATE ZLIB 01/02/01 00:15:09 */
+/********************************************************************/
+
+ EXPORT SYMBOL("deflateResetKeep")
+ EXPORT SYMBOL("deflatePending")
+
+/********************************************************************/
+/* *MODULE GZWRITE ZLIB 01/02/01 00:15:09 */
+/********************************************************************/
+
+ EXPORT SYMBOL("gzgetc_")
+
+/********************************************************************/
+/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */
+/********************************************************************/
+
+ EXPORT SYMBOL("inflateResetKeep")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.2.8 additional entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+/********************************************************************/
+/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */
+/********************************************************************/
+
+ EXPORT SYMBOL("inflateGetDictionary")
+
ENDPGMEXP
diff --git a/compat/zlib/as400/compile.clp b/compat/zlib/as400/compile.clp
new file mode 100644
index 0000000..e3f47c6
--- /dev/null
+++ b/compat/zlib/as400/compile.clp
@@ -0,0 +1,110 @@
+/******************************************************************************/
+/* */
+/* ZLIB */
+/* */
+/* Compile sources into modules and link them into a service program. */
+/* */
+/******************************************************************************/
+
+ PGM
+
+/* Configuration adjustable parameters. */
+
+ DCL VAR(&SRCLIB) TYPE(*CHAR) LEN(10) +
+ VALUE('ZLIB') /* Source library. */
+ DCL VAR(&SRCFILE) TYPE(*CHAR) LEN(10) +
+ VALUE('SOURCES') /* Source member file. */
+ DCL VAR(&CTLFILE) TYPE(*CHAR) LEN(10) +
+ VALUE('TOOLS') /* Control member file. */
+
+ DCL VAR(&MODLIB) TYPE(*CHAR) LEN(10) +
+ VALUE('ZLIB') /* Module library. */
+
+ DCL VAR(&SRVLIB) TYPE(*CHAR) LEN(10) +
+ VALUE('LGPL') /* Service program library. */
+
+ DCL VAR(&CFLAGS) TYPE(*CHAR) +
+ VALUE('OPTIMIZE(40)') /* Compile options. */
+
+ DCL VAR(&TGTRLS) TYPE(*CHAR) +
+ VALUE('V5R3M0') /* Target release. */
+
+
+/* Working storage. */
+
+ DCL VAR(&CMDLEN) TYPE(*DEC) LEN(15 5) VALUE(300) /* Command length. */
+ DCL VAR(&CMD) TYPE(*CHAR) LEN(512)
+ DCL VAR(&FIXDCMD) TYPE(*CHAR) LEN(512)
+
+
+/* Compile sources into modules. */
+
+ CHGVAR VAR(&FIXDCMD) VALUE('CRTCMOD' *BCAT &CFLAGS *BCAT +
+ 'SYSIFCOPT(*IFS64IO)' *BCAT +
+ 'DEFINE(''_LARGEFILE64_SOURCE''' *BCAT +
+ '''_LFS64_LARGEFILE=1'') TGTRLS(' *TCAT &TGTRLS *TCAT +
+ ') SRCFILE(' *TCAT &SRCLIB *TCAT '/' *TCAT +
+ &SRCFILE *TCAT ') MODULE(' *TCAT &MODLIB *TCAT '/')
+
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'ADLER32)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'COMPRESS)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'CRC32)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'DEFLATE)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZCLOSE)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZLIB)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZREAD)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZWRITE)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFBACK)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFFAST)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFLATE)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFTREES)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'TREES)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'UNCOMPR)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+ CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'ZUTIL)')
+ CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+
+/* Link modules into a service program. */
+
+ CRTSRVPGM SRVPGM(&SRVLIB/ZLIB) +
+ MODULE(&MODLIB/ADLER32 &MODLIB/COMPRESS +
+ &MODLIB/CRC32 &MODLIB/DEFLATE +
+ &MODLIB/GZCLOSE &MODLIB/GZLIB +
+ &MODLIB/GZREAD &MODLIB/GZWRITE +
+ &MODLIB/INFBACK &MODLIB/INFFAST +
+ &MODLIB/INFLATE &MODLIB/INFTREES +
+ &MODLIB/TREES &MODLIB/UNCOMPR +
+ &MODLIB/ZUTIL) +
+ SRCFILE(&SRCLIB/&CTLFILE) SRCMBR(BNDSRC) +
+ TEXT('ZLIB 1.2.8') TGTRLS(&TGTRLS)
+
+ ENDPGM
diff --git a/compat/zlib/old/as400/readme.txt b/compat/zlib/as400/readme.txt
index beae13f..7b5d93b 100644
--- a/compat/zlib/old/as400/readme.txt
+++ b/compat/zlib/as400/readme.txt
@@ -1,4 +1,4 @@
- ZLIB version 1.2.3 for AS400 installation instructions
+ ZLIB version 1.2.8 for AS400 installation instructions
I) From an AS400 *SAVF file:
@@ -8,7 +8,7 @@ On the AS400:
_ Create the ZLIB AS400 library:
- CRTLIB LIB(ZLIB) TYPE(PROD) TEXT('ZLIB compression API library')
+ CRTLIB LIB(ZLIB) TYPE(*PROD) TEXT('ZLIB compression API library')
_ Create a work save file, for example:
@@ -52,7 +52,7 @@ II) From the original source distribution:
1) On the AS400, create the source library:
- CRTLIB LIB(ZLIB) TYPE(PROD) TEXT('ZLIB compression API library')
+ CRTLIB LIB(ZLIB) TYPE(*PROD) TEXT('ZLIB compression API library')
2) Create the source files:
@@ -70,7 +70,10 @@ II) From the original source distribution:
compress.c COMPRESS C ZLIB - Compress a memory buffer
crc32.c CRC32 C ZLIB - Compute the CRC-32 of a data stream
deflate.c DEFLATE C ZLIB - Compress data using the deflation algorithm
- gzio.c GZIO C ZLIB - IO on .gz files
+ gzclose.c GZCLOSE C ZLIB - Close .gz files
+ gzlib.c GZLIB C ZLIB - Miscellaneous .gz files IO support
+ gzread.c GZREAD C ZLIB - Read .gz files
+ gzwrite.c GZWRITE C ZLIB - Write .gz files
infback.c INFBACK C ZLIB - Inflate using a callback interface
inffast.c INFFAST C ZLIB - Fast proc. literals & length/distance pairs
inflate.c INFLATE C ZLIB - Interface to inflate modules
@@ -81,6 +84,7 @@ II) From the original source distribution:
H Original ZLIB C and ILE/RPG include files
crc32.h CRC32 C ZLIB - CRC32 tables
deflate.h DEFLATE C ZLIB - Internal compression state
+ gzguts.h GZGUTS C ZLIB - Definitions for the gzclose module
inffast.h INFFAST C ZLIB - Header to use inffast.c
inffixed.h INFFIXED C ZLIB - Table for decoding fixed codes
inflate.h INFLATE C ZLIB - Internal inflate state definitions
@@ -108,4 +112,4 @@ Notes: For AS400 ILE RPG programmers, a /copy member defining the ZLIB
implementation does not handle conversion from/to ASCII, so
text data code conversions must be done explicitely.
- Always open zipped files in binary mode.
+ Mainly for the reason above, always open zipped files in binary mode.
diff --git a/compat/zlib/old/as400/zlib.inc b/compat/zlib/as400/zlib.inc
index a9a4f5c..7341a6d 100644
--- a/compat/zlib/old/as400/zlib.inc
+++ b/compat/zlib/as400/zlib.inc
@@ -1,7 +1,7 @@
* ZLIB.INC - Interface to the general purpose compression library
*
* ILE RPG400 version by Patrick Monnerat, DATASPHERE.
- * Version 1.2.3.9
+ * Version 1.2.8
*
*
* WARNING:
@@ -22,16 +22,25 @@
*
* Versioning information.
*
- D ZLIB_VERSION C '1.2.3.9'
- D ZLIB_VERNUM C X'1239'
+ D ZLIB_VERSION C '1.2.8'
+ D ZLIB_VERNUM C X'1280'
+ D ZLIB_VER_MAJOR C 1
+ D ZLIB_VER_MINOR C 2
+ D ZLIB_VER_REVISION...
+ D C 8
+ D ZLIB_VER_SUBREVISION...
+ D C 0
*
* Other equates.
*
D Z_NO_FLUSH C 0
+ D Z_PARTIAL_FLUSH...
+ D C 1
D Z_SYNC_FLUSH C 2
D Z_FULL_FLUSH C 3
D Z_FINISH C 4
D Z_BLOCK C 5
+ D Z_TREES C 6
*
D Z_OK C 0
D Z_STREAM_END C 1
@@ -72,6 +81,7 @@
D z_streamp S * Stream struct ptr
D gzFile S * File pointer
D z_off_t S 10i 0 Stream offsets
+ D z_off64_t S 20i 0 Stream offsets
*
**************************************************************************
* Structures
@@ -101,15 +111,15 @@
**************************************************************************
*
D compress PR 10I 0 extproc('compress')
- D dest 32767 options(*varsize) Destination buffer
+ D dest 65535 options(*varsize) Destination buffer
D destLen 10U 0 Destination length
- D source 32767 const options(*varsize) Source buffer
+ D source 65535 const options(*varsize) Source buffer
D sourceLen 10u 0 value Source length
*
D compress2 PR 10I 0 extproc('compress2')
- D dest 32767 options(*varsize) Destination buffer
+ D dest 65535 options(*varsize) Destination buffer
D destLen 10U 0 Destination length
- D source 32767 const options(*varsize) Source buffer
+ D source 65535 const options(*varsize) Source buffer
D sourceLen 10U 0 value Source length
D level 10I 0 value Compression level
*
@@ -117,34 +127,50 @@
D sourceLen 10U 0 value
*
D uncompress PR 10I 0 extproc('uncompress')
- D dest 32767 options(*varsize) Destination buffer
+ D dest 65535 options(*varsize) Destination buffer
D destLen 10U 0 Destination length
- D source 32767 const options(*varsize) Source buffer
+ D source 65535 const options(*varsize) Source buffer
D sourceLen 10U 0 value Source length
*
+ /if not defined(LARGE_FILES)
D gzopen PR extproc('gzopen')
D like(gzFile)
D path * value options(*string) File pathname
D mode * value options(*string) Open mode
+ /else
+ D gzopen PR extproc('gzopen64')
+ D like(gzFile)
+ D path * value options(*string) File pathname
+ D mode * value options(*string) Open mode
+ *
+ D gzopen64 PR extproc('gzopen64')
+ D like(gzFile)
+ D path * value options(*string) File pathname
+ D mode * value options(*string) Open mode
+ /endif
*
D gzdopen PR extproc('gzdopen')
D like(gzFile)
- D fd 10i 0 value File descriptor
+ D fd 10I 0 value File descriptor
D mode * value options(*string) Open mode
*
+ D gzbuffer PR 10I 0 extproc('gzbuffer')
+ D file value like(gzFile) File pointer
+ D size 10U 0 value
+ *
D gzsetparams PR 10I 0 extproc('gzsetparams')
D file value like(gzFile) File pointer
D level 10I 0 value
- D strategy 10i 0 value
+ D strategy 10I 0 value
*
D gzread PR 10I 0 extproc('gzread')
D file value like(gzFile) File pointer
- D buf 32767 options(*varsize) Buffer
+ D buf 65535 options(*varsize) Buffer
D len 10u 0 value Buffer length
*
D gzwrite PR 10I 0 extproc('gzwrite')
D file value like(gzFile) File pointer
- D buf 32767 const options(*varsize) Buffer
+ D buf 65535 const options(*varsize) Buffer
D len 10u 0 value Buffer length
*
D gzputs PR 10I 0 extproc('gzputs')
@@ -153,29 +179,87 @@
*
D gzgets PR * extproc('gzgets')
D file value like(gzFile) File pointer
- D buf 32767 options(*varsize) Read buffer
+ D buf 65535 options(*varsize) Read buffer
D len 10i 0 value Buffer length
*
+ D gzputc PR 10i 0 extproc('gzputc')
+ D file value like(gzFile) File pointer
+ D c 10I 0 value Character to write
+ *
+ D gzgetc PR 10i 0 extproc('gzgetc')
+ D file value like(gzFile) File pointer
+ *
+ D gzgetc_ PR 10i 0 extproc('gzgetc_')
+ D file value like(gzFile) File pointer
+ *
+ D gzungetc PR 10i 0 extproc('gzungetc')
+ D c 10I 0 value Character to push
+ D file value like(gzFile) File pointer
+ *
D gzflush PR 10i 0 extproc('gzflush')
D file value like(gzFile) File pointer
D flush 10I 0 value Type of flush
*
+ /if not defined(LARGE_FILES)
D gzseek PR extproc('gzseek')
D like(z_off_t)
D file value like(gzFile) File pointer
D offset value like(z_off_t) Offset
D whence 10i 0 value Origin
+ /else
+ D gzseek PR extproc('gzseek64')
+ D like(z_off_t)
+ D file value like(gzFile) File pointer
+ D offset value like(z_off_t) Offset
+ D whence 10i 0 value Origin
+ *
+ D gzseek64 PR extproc('gzseek64')
+ D like(z_off64_t)
+ D file value like(gzFile) File pointer
+ D offset value like(z_off64_t) Offset
+ D whence 10i 0 value Origin
+ /endif
*
D gzrewind PR 10i 0 extproc('gzrewind')
D file value like(gzFile) File pointer
*
+ /if not defined(LARGE_FILES)
D gztell PR extproc('gztell')
D like(z_off_t)
D file value like(gzFile) File pointer
+ /else
+ D gztell PR extproc('gztell64')
+ D like(z_off_t)
+ D file value like(gzFile) File pointer
+ *
+ D gztell64 PR extproc('gztell64')
+ D like(z_off64_t)
+ D file value like(gzFile) File pointer
+ /endif
+ *
+ /if not defined(LARGE_FILES)
+ D gzoffset PR extproc('gzoffset')
+ D like(z_off_t)
+ D file value like(gzFile) File pointer
+ /else
+ D gzoffset PR extproc('gzoffset64')
+ D like(z_off_t)
+ D file value like(gzFile) File pointer
+ *
+ D gzoffset64 PR extproc('gzoffset64')
+ D like(z_off64_t)
+ D file value like(gzFile) File pointer
+ /endif
*
D gzeof PR 10i 0 extproc('gzeof')
D file value like(gzFile) File pointer
*
+ D gzclose_r PR 10i 0 extproc('gzclose_r')
+ D file value like(gzFile) File pointer
+ *
+ D gzclose_w PR 10i 0 extproc('gzclose_w')
+ D file value like(gzFile) File pointer
+ *
D gzclose PR 10i 0 extproc('gzclose')
D file value like(gzFile) File pointer
*
@@ -234,7 +318,7 @@
D deflateSetDictionary...
D PR 10I 0 extproc('deflateSetDictionary') Init. dictionary
D strm like(z_stream) Compression stream
- D dictionary 32767 const options(*varsize) Dictionary bytes
+ D dictionary 65535 const options(*varsize) Dictionary bytes
D dictLength 10U 0 value Dictionary length
*
D deflateCopy PR 10I 0 extproc('deflateCopy') Compress strm 2 strm
@@ -253,9 +337,14 @@
D strm like(z_stream) Compression stream
D sourcelen 10U 0 value Compression level
*
+ D deflatePending PR 10I 0 extproc('deflatePending') Change level & strat
+ D strm like(z_stream) Compression stream
+ D pending 10U 0 Pending bytes
+ D bits 10I 0 Pending bits
+ *
D deflatePrime PR 10I 0 extproc('deflatePrime') Change level & strat
D strm like(z_stream) Compression stream
- D bits 10I 0 value Number of bits to insert
+ D bits 10I 0 value # of bits to insert
D value 10I 0 value Bits to insert
*
D inflateInit2 PR 10I 0 extproc('inflateInit2_') Init. expansion
@@ -267,9 +356,15 @@
D inflateSetDictionary...
D PR 10I 0 extproc('inflateSetDictionary') Init. dictionary
D strm like(z_stream) Expansion stream
- D dictionary 32767 const options(*varsize) Dictionary bytes
+ D dictionary 65535 const options(*varsize) Dictionary bytes
D dictLength 10U 0 value Dictionary length
*
+ D inflateGetDictionary...
+ D PR 10I 0 extproc('inflateGetDictionary') Get dictionary
+ D strm like(z_stream) Expansion stream
+ D dictionary 65535 options(*varsize) Dictionary bytes
+ D dictLength 10U 0 Dictionary length
+ *
D inflateSync PR 10I 0 extproc('inflateSync') Sync. expansion
D strm like(z_stream) Expansion stream
*
@@ -280,11 +375,23 @@
D inflateReset PR 10I 0 extproc('inflateReset') End and init. stream
D strm like(z_stream) Expansion stream
*
+ D inflateReset2 PR 10I 0 extproc('inflateReset2') End and init. stream
+ D strm like(z_stream) Expansion stream
+ D windowBits 10I 0 value Log2(buffer size)
+ *
+ D inflatePrime PR 10I 0 extproc('inflatePrime') Insert bits
+ D strm like(z_stream) Expansion stream
+ D bits 10I 0 value Bit count
+ D value 10I 0 value Bits to insert
+ *
+ D inflateMark PR 10I 0 extproc('inflateMark') Get inflate info
+ D strm like(z_stream) Expansion stream
+ *
D inflateBackInit...
D PR 10I 0 extproc('inflateBackInit_')
D strm like(z_stream) Expansion stream
D windowBits 10I 0 value Log2(buffer size)
- D window 32767 options(*varsize) Buffer
+ D window 65535 options(*varsize) Buffer
D version * value options(*string) Version string
D stream_size 10i 0 value Stream struct. size
*
@@ -307,12 +414,12 @@
*
D adler32 PR 10U 0 extproc('adler32') New checksum
D adler 10U 0 value Old checksum
- D buf 32767 const options(*varsize) Bytes to accumulate
+ D buf 65535 const options(*varsize) Bytes to accumulate
D len 10U 0 value Buffer length
*
D crc32 PR 10U 0 extproc('crc32') New checksum
D crc 10U 0 value Old checksum
- D buf 32767 const options(*varsize) Bytes to accumulate
+ D buf 65535 const options(*varsize) Bytes to accumulate
D len 10U 0 value Buffer length
*
**************************************************************************
@@ -328,4 +435,17 @@
*
D get_crc_table PR * extproc('get_crc_table') Ptr to ulongs
*
+ D inflateUndermine...
+ D PR 10I 0 extproc('inflateUndermine')
+ D strm like(z_stream) Expansion stream
+ D arg 10I 0 value Error code
+ *
+ D inflateResetKeep...
+ D PR 10I 0 extproc('inflateResetKeep') End and init. stream
+ D strm like(z_stream) Expansion stream
+ *
+ D deflateResetKeep...
+ D PR 10I 0 extproc('deflateResetKeep') End and init. stream
+ D strm like(z_stream) Expansion stream
+ *
/endif
diff --git a/compat/zlib/compress.c b/compat/zlib/compress.c
index 21fa4c1..6e97626 100644
--- a/compat/zlib/compress.c
+++ b/compat/zlib/compress.c
@@ -3,7 +3,7 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-/* @(#) $Id: compress.c,v 1.3 2010/04/20 14:50:10 nijtmans Exp $ */
+/* @(#) $Id$ */
#define ZLIB_INTERNAL
#include "zlib.h"
@@ -29,7 +29,7 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
z_stream stream;
int err;
- stream.next_in = (Bytef*)source;
+ stream.next_in = (z_const Bytef *)source;
stream.avail_in = (uInt)sourceLen;
#ifdef MAXSEG_64K
/* Check for source > 64K on 16-bit machine: */
diff --git a/compat/zlib/configure b/compat/zlib/configure
index bd9edd2..b77a8a8 100755
--- a/compat/zlib/configure
+++ b/compat/zlib/configure
@@ -13,39 +13,52 @@
# If you have problems, try without defining CC and CFLAGS before reporting
# an error.
+# start off configure.log
+echo -------------------- >> configure.log
+echo $0 $* >> configure.log
+date >> configure.log
+
+# set command prefix for cross-compilation
if [ -n "${CHOST}" ]; then
- uname="$(echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/')"
+ uname="`echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/'`"
CROSS_PREFIX="${CHOST}-"
fi
+# destination name for static library
STATICLIB=libz.a
-LDFLAGS="${LDFLAGS} -L. ${STATICLIB}"
+
+# extract zlib version numbers from zlib.h
VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < zlib.h`
VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h`
VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h`
+
+# establish commands for library building
if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then
AR=${AR-"${CROSS_PREFIX}ar"}
- test -n "${CROSS_PREFIX}" && echo Using ${AR}
+ test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log
else
AR=${AR-"ar"}
- test -n "${CROSS_PREFIX}" && echo Using ${AR}
+ test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log
fi
-AR_RC="${AR} rc"
+ARFLAGS=${ARFLAGS-"rc"}
if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then
RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"}
- test -n "${CROSS_PREFIX}" && echo Using ${RANLIB}
+ test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} | tee -a configure.log
else
RANLIB=${RANLIB-"ranlib"}
fi
if "${CROSS_PREFIX}nm" --version >/dev/null 2>/dev/null || test $? -lt 126; then
NM=${NM-"${CROSS_PREFIX}nm"}
- test -n "${CROSS_PREFIX}" && echo Using ${NM}
+ test -n "${CROSS_PREFIX}" && echo Using ${NM} | tee -a configure.log
else
NM=${NM-"nm"}
fi
+
+# set defaults before processing command line options
LDCONFIG=${LDCONFIG-"ldconfig"}
LDSHAREDLIBC="${LDSHAREDLIBC--lc}"
+ARCHS=
prefix=${prefix-/usr/local}
exec_prefix=${exec_prefix-'${prefix}'}
libdir=${libdir-'${exec_prefix}/lib'}
@@ -54,20 +67,39 @@ includedir=${includedir-'${prefix}/include'}
mandir=${mandir-'${prefix}/share/man'}
shared_ext='.so'
shared=1
+solo=0
+cover=0
zprefix=0
+zconst=0
build64=0
gcc=0
old_cc="$CC"
old_cflags="$CFLAGS"
+OBJC='$(OBJZ) $(OBJG)'
+PIC_OBJC='$(PIC_OBJZ) $(PIC_OBJG)'
+
+# leave this script, optionally in a bad way
+leave()
+{
+ if test "$*" != "0"; then
+ echo "** $0 aborting." | tee -a configure.log
+ fi
+ rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version
+ echo -------------------- >> configure.log
+ echo >> configure.log
+ echo >> configure.log
+ exit $1
+}
+# process command line options
while test $# -ge 1
do
case "$1" in
-h* | --help)
- echo 'usage:'
- echo ' configure [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]'
- echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]'
- echo ' [--includedir=INCLUDEDIR]'
+ echo 'usage:' | tee -a configure.log
+ echo ' configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log
+ echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log
+ echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log
exit 0 ;;
-p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;;
-e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;;
@@ -81,51 +113,88 @@ case "$1" in
-i* | --includedir) includedir="$2"; shift; shift ;;
-s* | --shared | --enable-shared) shared=1; shift ;;
-t | --static) shared=0; shift ;;
+ --solo) solo=1; shift ;;
+ --cover) cover=1; shift ;;
-z* | --zprefix) zprefix=1; shift ;;
-6* | --64) build64=1; shift ;;
- --sysconfdir=*) echo "ignored option: --sysconfdir"; shift ;;
- --localstatedir=*) echo "ignored option: --localstatedir"; shift ;;
- *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1 ;;
+ -a*=* | --archs=*) ARCHS=`echo $1 | sed 's/.*=//'`; shift ;;
+ --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;;
+ --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;;
+ -c* | --const) zconst=1; shift ;;
+ *)
+ echo "unknown option: $1" | tee -a configure.log
+ echo "$0 --help for help" | tee -a configure.log
+ leave 1;;
esac
done
+# temporary file name
test=ztest$$
+
+# put arguments in log, also put test file in log if used in arguments
+show()
+{
+ case "$*" in
+ *$test.c*)
+ echo === $test.c === >> configure.log
+ cat $test.c >> configure.log
+ echo === >> configure.log;;
+ esac
+ echo $* >> configure.log
+}
+
+# check for gcc vs. cc and set compile and link flags based on the system identified by uname
cat > $test.c <<EOF
extern int getchar();
int hello() {return getchar();}
EOF
-test -z "$CC" && echo Checking for ${CROSS_PREFIX}gcc...
+test -z "$CC" && echo Checking for ${CROSS_PREFIX}gcc... | tee -a configure.log
cc=${CC-${CROSS_PREFIX}gcc}
cflags=${CFLAGS-"-O3"}
# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
case "$cc" in
*gcc*) gcc=1 ;;
+ *clang*) gcc=1 ;;
+esac
+case `$cc -v 2>&1` in
+ *gcc*) gcc=1 ;;
esac
-if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then
+show $cc -c $test.c
+if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then
+ echo ... using gcc >> configure.log
CC="$cc"
+ CFLAGS="${CFLAGS--O3} ${ARCHS}"
SFLAGS="${CFLAGS--O3} -fPIC"
- CFLAGS="${CFLAGS--O3}"
+ LDFLAGS="${LDFLAGS} ${ARCHS}"
if test $build64 -eq 1; then
CFLAGS="${CFLAGS} -m64"
SFLAGS="${SFLAGS} -m64"
fi
if test "${ZLIBGCCWARN}" = "YES"; then
- CFLAGS="${CFLAGS} -Wall -Wextra -pedantic"
+ if test "$zconst" -eq 1; then
+ CFLAGS="${CFLAGS} -Wall -Wextra -Wcast-qual -pedantic -DZLIB_CONST"
+ else
+ CFLAGS="${CFLAGS} -Wall -Wextra -pedantic"
+ fi
fi
if test -z "$uname"; then
uname=`(uname -s || echo unknown) 2>/dev/null`
fi
case "$uname" in
- Linux* | linux* | GNU | GNU/* | *BSD | DragonFly) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"} ;;
+ Linux* | linux* | GNU | GNU/* | solaris*)
+ LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"} ;;
+ *BSD | *bsd* | DragonFly)
+ LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"}
+ LDCONFIG="ldconfig -m" ;;
CYGWIN* | Cygwin* | cygwin* | OS/2*)
EXE='.exe' ;;
- MINGW*|mingw*)
+ MINGW* | mingw*)
# temporary bypass
rm -f $test.[co] $test $test$shared_ext
- echo "Please use win32/Makefile.gcc instead."
- exit 1
+ echo "Please use win32/Makefile.gcc instead." | tee -a configure.log
+ leave 1
LDSHARED=${LDSHARED-"$cc -shared"}
LDSHAREDLIBC=""
EXE='.exe' ;;
@@ -142,17 +211,25 @@ if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then
shared_ext='.sl'
SHAREDLIB='libz.sl' ;;
esac ;;
- Darwin*) shared_ext='.dylib'
+ Darwin* | darwin*)
+ shared_ext='.dylib'
SHAREDLIB=libz$shared_ext
SHAREDLIBV=libz.$VER$shared_ext
SHAREDLIBM=libz.$VER1$shared_ext
- LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"} ;;
+ LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"}
+ if libtool -V 2>&1 | grep Apple > /dev/null; then
+ AR="libtool"
+ else
+ AR="/usr/bin/libtool"
+ fi
+ ARFLAGS="-o" ;;
*) LDSHARED=${LDSHARED-"$cc -shared"} ;;
esac
else
# find system name and corresponding cc options
CC=${CC-cc}
gcc=0
+ echo ... using $CC >> configure.log
if test -z "$uname"; then
uname=`(uname -sr || echo unknown) 2>/dev/null`
fi
@@ -183,19 +260,34 @@ else
CFLAGS=${CFLAGS-"-4 -O"}
LDSHARED=${LDSHARED-"cc"}
RANLIB=${RANLIB-"true"}
- AR_RC="cc -A" ;;
+ AR="cc"
+ ARFLAGS="-A" ;;
SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
CFLAGS=${CFLAGS-"-O3"}
LDSHARED=${LDSHARED-"cc -dy -KPIC -G"} ;;
- SunOS\ 5*) LDSHARED=${LDSHARED-"cc -G"}
- case `(uname -m || echo unknown) 2>/dev/null` in
- i86*)
- SFLAGS=${CFLAGS-"-xpentium -fast -KPIC -R."}
- CFLAGS=${CFLAGS-"-xpentium -fast"} ;;
- *)
- SFLAGS=${CFLAGS-"-fast -xcg92 -KPIC -R."}
- CFLAGS=${CFLAGS-"-fast -xcg92"} ;;
- esac ;;
+ SunOS\ 5* | solaris*)
+ LDSHARED=${LDSHARED-"cc -G -h libz$shared_ext.$VER1"}
+ SFLAGS=${CFLAGS-"-fast -KPIC"}
+ CFLAGS=${CFLAGS-"-fast"}
+ if test $build64 -eq 1; then
+ # old versions of SunPRO/Workshop/Studio don't support -m64,
+ # but newer ones do. Check for it.
+ flag64=`$CC -flags | egrep -- '^-m64'`
+ if test x"$flag64" != x"" ; then
+ CFLAGS="${CFLAGS} -m64"
+ SFLAGS="${SFLAGS} -m64"
+ else
+ case `(uname -m || echo unknown) 2>/dev/null` in
+ i86*)
+ SFLAGS="$SFLAGS -xarch=amd64"
+ CFLAGS="$CFLAGS -xarch=amd64" ;;
+ *)
+ SFLAGS="$SFLAGS -xarch=v9"
+ CFLAGS="$CFLAGS -xarch=v9" ;;
+ esac
+ fi
+ fi
+ ;;
SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
CFLAGS=${CFLAGS-"-O2"}
LDSHARED=${LDSHARED-"ld"} ;;
@@ -225,25 +317,79 @@ else
esac
fi
+# destination names for shared library if not defined above
SHAREDLIB=${SHAREDLIB-"libz$shared_ext"}
SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"}
SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"}
+echo >> configure.log
+
+# define functions for testing compiler and library characteristics and logging the results
+
+cat > $test.c <<EOF
+#error error
+EOF
+if ($CC -c $CFLAGS $test.c) 2>/dev/null; then
+ try()
+ {
+ show $*
+ test "`( $* ) 2>&1 | tee -a configure.log`" = ""
+ }
+ echo - using any output from compiler to indicate an error >> configure.log
+else
+try()
+{
+ show $*
+ ( $* ) >> configure.log 2>&1
+ ret=$?
+ if test $ret -ne 0; then
+ echo "(exit code "$ret")" >> configure.log
+ fi
+ return $ret
+}
+fi
+
+tryboth()
+{
+ show $*
+ got=`( $* ) 2>&1`
+ ret=$?
+ printf %s "$got" >> configure.log
+ if test $ret -ne 0; then
+ return $ret
+ fi
+ test "$got" = ""
+}
+
+cat > $test.c << EOF
+int foo() { return 0; }
+EOF
+echo "Checking for obsessive-compulsive compiler options..." >> configure.log
+if try $CC -c $CFLAGS $test.c; then
+ :
+else
+ echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log
+ leave 1
+fi
+
+echo >> configure.log
+
+# see if shared library build supported
+cat > $test.c <<EOF
+extern int getchar();
+int hello() {return getchar();}
+EOF
if test $shared -eq 1; then
- echo Checking for shared library support...
+ echo Checking for shared library support... | tee -a configure.log
# we must test in two steps (cc then ld), required at least on SunOS 4.x
- if test "`($CC -w -c $SFLAGS $test.c) 2>&1`" = "" &&
- test "`($LDSHARED $SFLAGS -o $test$shared_ext $test.o) 2>&1`" = ""; then
- echo Building shared library $SHAREDLIBV with $CC.
+ if try $CC -w -c $SFLAGS $test.c &&
+ try $LDSHARED $SFLAGS -o $test$shared_ext $test.o; then
+ echo Building shared library $SHAREDLIBV with $CC. | tee -a configure.log
elif test -z "$old_cc" -a -z "$old_cflags"; then
- echo No shared library support.
+ echo No shared library support. | tee -a configure.log
shared=0;
else
- echo Tested $CC -w -c $SFLAGS $test.c
- $CC -w -c $SFLAGS $test.c
- echo Tested $LDSHARED $SFLAGS -o $test$shared_ext $test.o
- $LDSHARED $SFLAGS -o $test$shared_ext $test.o
- echo 'No shared library support; try without defining CC and CFLAGS'
+ echo 'No shared library support; try without defining CC and CFLAGS' | tee -a configure.log
shared=0;
fi
fi
@@ -254,25 +400,43 @@ if test $shared -eq 0; then
SHAREDLIB=""
SHAREDLIBV=""
SHAREDLIBM=""
- echo Building static library $STATICLIB version $VER with $CC.
+ echo Building static library $STATICLIB version $VER with $CC. | tee -a configure.log
else
ALL="static shared"
TEST="all teststatic testshared"
fi
+# check for underscores in external names for use by assembler code
+CPP=${CPP-"$CC -E"}
+case $CFLAGS in
+ *ASMV*)
+ echo >> configure.log
+ show "$NM $test.o | grep _hello"
+ if test "`$NM $test.o | grep _hello | tee -a configure.log`" = ""; then
+ CPP="$CPP -DNO_UNDERLINE"
+ echo Checking for underline in external names... No. | tee -a configure.log
+ else
+ echo Checking for underline in external names... Yes. | tee -a configure.log
+ fi ;;
+esac
+
+echo >> configure.log
+
+# check for large file support, and if none, check for fseeko()
cat > $test.c <<EOF
#include <sys/types.h>
off64_t dummy = 0;
EOF
-if test "`($CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c) 2>&1`" = ""; then
+if try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then
CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1"
SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1"
ALL="${ALL} all64"
TEST="${TEST} test64"
- echo "Checking for off64_t... Yes."
- echo "Checking for fseeko... Yes."
+ echo "Checking for off64_t... Yes." | tee -a configure.log
+ echo "Checking for fseeko... Yes." | tee -a configure.log
else
- echo "Checking for off64_t... No."
+ echo "Checking for off64_t... No." | tee -a configure.log
+ echo >> configure.log
cat > $test.c <<EOF
#include <stdio.h>
int main(void) {
@@ -280,272 +444,335 @@ int main(void) {
return 0;
}
EOF
- if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
- echo "Checking for fseeko... Yes."
+ if try $CC $CFLAGS -o $test $test.c; then
+ echo "Checking for fseeko... Yes." | tee -a configure.log
else
CFLAGS="${CFLAGS} -DNO_FSEEKO"
SFLAGS="${SFLAGS} -DNO_FSEEKO"
- echo "Checking for fseeko... No."
+ echo "Checking for fseeko... No." | tee -a configure.log
fi
fi
+echo >> configure.log
+
+# check for strerror() for use by gz* functions
+cat > $test.c <<EOF
+#include <string.h>
+#include <errno.h>
+int main() { return strlen(strerror(errno)); }
+EOF
+if try $CC $CFLAGS -o $test $test.c; then
+ echo "Checking for strerror... Yes." | tee -a configure.log
+else
+ CFLAGS="${CFLAGS} -DNO_STRERROR"
+ SFLAGS="${SFLAGS} -DNO_STRERROR"
+ echo "Checking for strerror... No." | tee -a configure.log
+fi
+
+# copy clean zconf.h for subsequent edits
cp -p zconf.h.in zconf.h
+echo >> configure.log
+
+# check for unistd.h and save result in zconf.h
cat > $test.c <<EOF
#include <unistd.h>
int main() { return 0; }
EOF
-if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+if try $CC -c $CFLAGS $test.c; then
sed < zconf.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf.temp.h
mv zconf.temp.h zconf.h
- echo "Checking for unistd.h... Yes."
+ echo "Checking for unistd.h... Yes." | tee -a configure.log
+else
+ echo "Checking for unistd.h... No." | tee -a configure.log
+fi
+
+echo >> configure.log
+
+# check for stdarg.h and save result in zconf.h
+cat > $test.c <<EOF
+#include <stdarg.h>
+int main() { return 0; }
+EOF
+if try $CC -c $CFLAGS $test.c; then
+ sed < zconf.h "/^#ifdef HAVE_STDARG_H.* may be/s/def HAVE_STDARG_H\(.*\) may be/ 1\1 was/" > zconf.temp.h
+ mv zconf.temp.h zconf.h
+ echo "Checking for stdarg.h... Yes." | tee -a configure.log
else
- echo "Checking for unistd.h... No."
+ echo "Checking for stdarg.h... No." | tee -a configure.log
fi
+# if the z_ prefix was requested, save that in zconf.h
if test $zprefix -eq 1; then
sed < zconf.h "/#ifdef Z_PREFIX.* may be/s/def Z_PREFIX\(.*\) may be/ 1\1 was/" > zconf.temp.h
mv zconf.temp.h zconf.h
- echo "Using z_ prefix on all symbols."
+ echo >> configure.log
+ echo "Using z_ prefix on all symbols." | tee -a configure.log
fi
+# if --solo compilation was requested, save that in zconf.h and remove gz stuff from object lists
+if test $solo -eq 1; then
+ sed '/#define ZCONF_H/a\
+#define Z_SOLO
+
+' < zconf.h > zconf.temp.h
+ mv zconf.temp.h zconf.h
+OBJC='$(OBJZ)'
+PIC_OBJC='$(PIC_OBJZ)'
+fi
+
+# if code coverage testing was requested, use older gcc if defined, e.g. "gcc-4.2" on Mac OS X
+if test $cover -eq 1; then
+ CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage"
+ if test -n "$GCC_CLASSIC"; then
+ CC=$GCC_CLASSIC
+ fi
+fi
+
+echo >> configure.log
+
+# conduct a series of tests to resolve eight possible cases of using "vs" or "s" printf functions
+# (using stdarg or not), with or without "n" (proving size of buffer), and with or without a
+# return value. The most secure result is vsnprintf() with a return value. snprintf() with a
+# return value is secure as well, but then gzprintf() will be limited to 20 arguments.
cat > $test.c <<EOF
#include <stdio.h>
#include <stdarg.h>
#include "zconf.h"
-
int main()
{
#ifndef STDC
choke me
#endif
-
return 0;
}
EOF
+if try $CC -c $CFLAGS $test.c; then
+ echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()." | tee -a configure.log
-if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()."
-
+ echo >> configure.log
cat > $test.c <<EOF
#include <stdio.h>
#include <stdarg.h>
-
int mytest(const char *fmt, ...)
{
char buf[20];
va_list ap;
-
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
return 0;
}
-
int main()
{
return (mytest("Hello%d\n", 1));
}
EOF
+ if try $CC $CFLAGS -o $test $test.c; then
+ echo "Checking for vsnprintf() in stdio.h... Yes." | tee -a configure.log
- if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
- echo "Checking for vsnprintf() in stdio.h... Yes."
-
+ echo >> configure.log
cat >$test.c <<EOF
#include <stdio.h>
#include <stdarg.h>
-
int mytest(const char *fmt, ...)
{
int n;
char buf[20];
va_list ap;
-
va_start(ap, fmt);
n = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
return n;
}
-
int main()
{
return (mytest("Hello%d\n", 1));
}
EOF
- if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for return value of vsnprintf()... Yes."
+ if try $CC -c $CFLAGS $test.c; then
+ echo "Checking for return value of vsnprintf()... Yes." | tee -a configure.log
else
CFLAGS="$CFLAGS -DHAS_vsnprintf_void"
SFLAGS="$SFLAGS -DHAS_vsnprintf_void"
- echo "Checking for return value of vsnprintf()... No."
- echo " WARNING: apparently vsnprintf() does not return a value. zlib"
- echo " can build but will be open to possible string-format security"
- echo " vulnerabilities."
+ echo "Checking for return value of vsnprintf()... No." | tee -a configure.log
+ echo " WARNING: apparently vsnprintf() does not return a value. zlib" | tee -a configure.log
+ echo " can build but will be open to possible string-format security" | tee -a configure.log
+ echo " vulnerabilities." | tee -a configure.log
fi
else
CFLAGS="$CFLAGS -DNO_vsnprintf"
SFLAGS="$SFLAGS -DNO_vsnprintf"
- echo "Checking for vsnprintf() in stdio.h... No."
- echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib"
- echo " can build but will be open to possible buffer-overflow security"
- echo " vulnerabilities."
+ echo "Checking for vsnprintf() in stdio.h... No." | tee -a configure.log
+ echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" | tee -a configure.log
+ echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log
+ echo " vulnerabilities." | tee -a configure.log
+ echo >> configure.log
cat >$test.c <<EOF
#include <stdio.h>
#include <stdarg.h>
-
int mytest(const char *fmt, ...)
{
int n;
char buf[20];
va_list ap;
-
va_start(ap, fmt);
n = vsprintf(buf, fmt, ap);
va_end(ap);
return n;
}
-
int main()
{
return (mytest("Hello%d\n", 1));
}
EOF
- if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for return value of vsprintf()... Yes."
+ if try $CC -c $CFLAGS $test.c; then
+ echo "Checking for return value of vsprintf()... Yes." | tee -a configure.log
else
CFLAGS="$CFLAGS -DHAS_vsprintf_void"
SFLAGS="$SFLAGS -DHAS_vsprintf_void"
- echo "Checking for return value of vsprintf()... No."
- echo " WARNING: apparently vsprintf() does not return a value. zlib"
- echo " can build but will be open to possible string-format security"
- echo " vulnerabilities."
+ echo "Checking for return value of vsprintf()... No." | tee -a configure.log
+ echo " WARNING: apparently vsprintf() does not return a value. zlib" | tee -a configure.log
+ echo " can build but will be open to possible string-format security" | tee -a configure.log
+ echo " vulnerabilities." | tee -a configure.log
fi
fi
else
- echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()."
+ echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()." | tee -a configure.log
+ echo >> configure.log
cat >$test.c <<EOF
#include <stdio.h>
-
int mytest()
{
char buf[20];
-
snprintf(buf, sizeof(buf), "%s", "foo");
return 0;
}
-
int main()
{
return (mytest());
}
EOF
- if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
- echo "Checking for snprintf() in stdio.h... Yes."
+ if try $CC $CFLAGS -o $test $test.c; then
+ echo "Checking for snprintf() in stdio.h... Yes." | tee -a configure.log
+ echo >> configure.log
cat >$test.c <<EOF
#include <stdio.h>
-
int mytest()
{
char buf[20];
-
return snprintf(buf, sizeof(buf), "%s", "foo");
}
-
int main()
{
return (mytest());
}
EOF
- if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for return value of snprintf()... Yes."
+ if try $CC -c $CFLAGS $test.c; then
+ echo "Checking for return value of snprintf()... Yes." | tee -a configure.log
else
CFLAGS="$CFLAGS -DHAS_snprintf_void"
SFLAGS="$SFLAGS -DHAS_snprintf_void"
- echo "Checking for return value of snprintf()... No."
- echo " WARNING: apparently snprintf() does not return a value. zlib"
- echo " can build but will be open to possible string-format security"
- echo " vulnerabilities."
+ echo "Checking for return value of snprintf()... No." | tee -a configure.log
+ echo " WARNING: apparently snprintf() does not return a value. zlib" | tee -a configure.log
+ echo " can build but will be open to possible string-format security" | tee -a configure.log
+ echo " vulnerabilities." | tee -a configure.log
fi
else
CFLAGS="$CFLAGS -DNO_snprintf"
SFLAGS="$SFLAGS -DNO_snprintf"
- echo "Checking for snprintf() in stdio.h... No."
- echo " WARNING: snprintf() not found, falling back to sprintf(). zlib"
- echo " can build but will be open to possible buffer-overflow security"
- echo " vulnerabilities."
+ echo "Checking for snprintf() in stdio.h... No." | tee -a configure.log
+ echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" | tee -a configure.log
+ echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log
+ echo " vulnerabilities." | tee -a configure.log
+ echo >> configure.log
cat >$test.c <<EOF
#include <stdio.h>
-
int mytest()
{
char buf[20];
-
return sprintf(buf, "%s", "foo");
}
-
int main()
{
return (mytest());
}
EOF
- if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for return value of sprintf()... Yes."
+ if try $CC -c $CFLAGS $test.c; then
+ echo "Checking for return value of sprintf()... Yes." | tee -a configure.log
else
CFLAGS="$CFLAGS -DHAS_sprintf_void"
SFLAGS="$SFLAGS -DHAS_sprintf_void"
- echo "Checking for return value of sprintf()... No."
- echo " WARNING: apparently sprintf() does not return a value. zlib"
- echo " can build but will be open to possible string-format security"
- echo " vulnerabilities."
+ echo "Checking for return value of sprintf()... No." | tee -a configure.log
+ echo " WARNING: apparently sprintf() does not return a value. zlib" | tee -a configure.log
+ echo " can build but will be open to possible string-format security" | tee -a configure.log
+ echo " vulnerabilities." | tee -a configure.log
fi
fi
fi
+# see if we can hide zlib internal symbols that are linked between separate source files
if test "$gcc" -eq 1; then
+ echo >> configure.log
cat > $test.c <<EOF
-#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33)
-# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
-#else
-# define ZLIB_INTERNAL
-#endif
+#define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
int ZLIB_INTERNAL foo;
int main()
{
return 0;
}
EOF
- if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for attribute(visibility) support... Yes."
+ if tryboth $CC -c $CFLAGS $test.c; then
+ CFLAGS="$CFLAGS -DHAVE_HIDDEN"
+ SFLAGS="$SFLAGS -DHAVE_HIDDEN"
+ echo "Checking for attribute(visibility) support... Yes." | tee -a configure.log
else
- CFLAGS="$CFLAGS -DNO_VIZ"
- SFLAGS="$SFLAGS -DNO_VIZ"
- echo "Checking for attribute(visibility) support... No."
+ echo "Checking for attribute(visibility) support... No." | tee -a configure.log
fi
fi
-CPP=${CPP-"$CC -E"}
-case $CFLAGS in
- *ASMV*)
- if test "`$NM $test.o | grep _hello`" = ""; then
- CPP="$CPP -DNO_UNDERLINE"
- echo Checking for underline in external names... No.
- else
- echo Checking for underline in external names... Yes.
- fi ;;
-esac
-
-rm -f $test.[co] $test $test$shared_ext
-
-# udpate Makefile
+# show the results in the log
+echo >> configure.log
+echo ALL = $ALL >> configure.log
+echo AR = $AR >> configure.log
+echo ARFLAGS = $ARFLAGS >> configure.log
+echo CC = $CC >> configure.log
+echo CFLAGS = $CFLAGS >> configure.log
+echo CPP = $CPP >> configure.log
+echo EXE = $EXE >> configure.log
+echo LDCONFIG = $LDCONFIG >> configure.log
+echo LDFLAGS = $LDFLAGS >> configure.log
+echo LDSHARED = $LDSHARED >> configure.log
+echo LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log
+echo OBJC = $OBJC >> configure.log
+echo PIC_OBJC = $PIC_OBJC >> configure.log
+echo RANLIB = $RANLIB >> configure.log
+echo SFLAGS = $SFLAGS >> configure.log
+echo SHAREDLIB = $SHAREDLIB >> configure.log
+echo SHAREDLIBM = $SHAREDLIBM >> configure.log
+echo SHAREDLIBV = $SHAREDLIBV >> configure.log
+echo STATICLIB = $STATICLIB >> configure.log
+echo TEST = $TEST >> configure.log
+echo VER = $VER >> configure.log
+echo Z_U4 = $Z_U4 >> configure.log
+echo exec_prefix = $exec_prefix >> configure.log
+echo includedir = $includedir >> configure.log
+echo libdir = $libdir >> configure.log
+echo mandir = $mandir >> configure.log
+echo prefix = $prefix >> configure.log
+echo sharedlibdir = $sharedlibdir >> configure.log
+echo uname = $uname >> configure.log
+
+# udpate Makefile with the configure results
sed < Makefile.in "
/^CC *=/s#=.*#=$CC#
/^CFLAGS *=/s#=.*#=$CFLAGS#
@@ -557,7 +784,8 @@ sed < Makefile.in "
/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
-/^AR *=/s#=.*#=$AR_RC#
+/^AR *=/s#=.*#=$AR#
+/^ARFLAGS *=/s#=.*#=$ARFLAGS#
/^RANLIB *=/s#=.*#=$RANLIB#
/^LDCONFIG *=/s#=.*#=$LDCONFIG#
/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC#
@@ -568,10 +796,13 @@ sed < Makefile.in "
/^sharedlibdir *=/s#=.*#=$sharedlibdir#
/^includedir *=/s#=.*#=$includedir#
/^mandir *=/s#=.*#=$mandir#
+/^OBJC *=/s#=.*#= $OBJC#
+/^PIC_OBJC *=/s#=.*#= $PIC_OBJC#
/^all: */s#:.*#: $ALL#
/^test: */s#:.*#: $TEST#
" > Makefile
+# create zlib.pc with the configure results
sed < zlib.pc.in "
/^CC *=/s#=.*#=$CC#
/^CFLAGS *=/s#=.*#=$CFLAGS#
@@ -581,7 +812,8 @@ sed < zlib.pc.in "
/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
-/^AR *=/s#=.*#=$AR_RC#
+/^AR *=/s#=.*#=$AR#
+/^ARFLAGS *=/s#=.*#=$ARFLAGS#
/^RANLIB *=/s#=.*#=$RANLIB#
/^EXE *=/s#=.*#=$EXE#
/^prefix *=/s#=.*#=$prefix#
@@ -594,3 +826,6 @@ sed < zlib.pc.in "
" | sed -e "
s/\@VERSION\@/$VER/g;
" > zlib.pc
+
+# done
+leave 0
diff --git a/compat/zlib/contrib/README.contrib b/compat/zlib/contrib/README.contrib
index dd2285d..c66349b 100644
--- a/compat/zlib/contrib/README.contrib
+++ b/compat/zlib/contrib/README.contrib
@@ -75,3 +75,4 @@ untgz/ by Pedro A. Aranda Gutierrez <paag@tid.es>
vstudio/ by Gilles Vollant <info@winimage.com>
Building a minizip-enhanced zlib with Microsoft Visual Studio
+ Includes vc11 from kreuzerkrieg and vc12 from davispuh
diff --git a/compat/zlib/contrib/ada/buffer_demo.adb b/compat/zlib/contrib/ada/buffer_demo.adb
index 8fe6e1c..46b8638 100644
--- a/compat/zlib/contrib/ada/buffer_demo.adb
+++ b/compat/zlib/contrib/ada/buffer_demo.adb
@@ -6,7 +6,7 @@
-- Open source license information is in the zlib.ads file. --
----------------------------------------------------------------
--
--- $Id: buffer_demo.adb,v 1.3 2010/04/20 14:50:10 nijtmans Exp $
+-- $Id: buffer_demo.adb,v 1.3 2004/09/06 06:55:35 vagul Exp $
-- This demo program provided by Dr Steve Sangwine <sjs@essex.ac.uk>
--
diff --git a/compat/zlib/contrib/ada/mtest.adb b/compat/zlib/contrib/ada/mtest.adb
index 5516952..c4dfd08 100644
--- a/compat/zlib/contrib/ada/mtest.adb
+++ b/compat/zlib/contrib/ada/mtest.adb
@@ -8,7 +8,7 @@
-- Continuous test for ZLib multithreading. If the test would fail
-- we should provide thread safe allocation routines for the Z_Stream.
--
--- $Id: mtest.adb,v 1.3 2010/04/20 14:50:10 nijtmans Exp $
+-- $Id: mtest.adb,v 1.4 2004/07/23 07:49:54 vagul Exp $
with ZLib;
with Ada.Streams;
diff --git a/compat/zlib/contrib/ada/read.adb b/compat/zlib/contrib/ada/read.adb
index 6df6a35..1f2efbf 100644
--- a/compat/zlib/contrib/ada/read.adb
+++ b/compat/zlib/contrib/ada/read.adb
@@ -6,7 +6,7 @@
-- Open source license information is in the zlib.ads file. --
----------------------------------------------------------------
--- $Id: read.adb,v 1.3 2010/04/20 14:50:10 nijtmans Exp $
+-- $Id: read.adb,v 1.8 2004/05/31 10:53:40 vagul Exp $
-- Test/demo program for the generic read interface.
diff --git a/compat/zlib/contrib/ada/test.adb b/compat/zlib/contrib/ada/test.adb
index 0edf1d6..90773ac 100644
--- a/compat/zlib/contrib/ada/test.adb
+++ b/compat/zlib/contrib/ada/test.adb
@@ -6,7 +6,7 @@
-- Open source license information is in the zlib.ads file. --
----------------------------------------------------------------
--- $Id: test.adb,v 1.3 2010/04/20 14:50:10 nijtmans Exp $
+-- $Id: test.adb,v 1.17 2003/08/12 12:13:30 vagul Exp $
-- The program has a few aims.
-- 1. Test ZLib.Ada95 thick binding functionality.
diff --git a/compat/zlib/contrib/ada/zlib-streams.adb b/compat/zlib/contrib/ada/zlib-streams.adb
index eac7440..b6497ba 100644
--- a/compat/zlib/contrib/ada/zlib-streams.adb
+++ b/compat/zlib/contrib/ada/zlib-streams.adb
@@ -6,7 +6,7 @@
-- Open source license information is in the zlib.ads file. --
----------------------------------------------------------------
--- $Id: zlib-streams.adb,v 1.3 2010/04/20 14:50:10 nijtmans Exp $
+-- $Id: zlib-streams.adb,v 1.10 2004/05/31 10:53:40 vagul Exp $
with Ada.Unchecked_Deallocation;
diff --git a/compat/zlib/contrib/ada/zlib-streams.ads b/compat/zlib/contrib/ada/zlib-streams.ads
index 68dc0b4..f0193c6b 100644
--- a/compat/zlib/contrib/ada/zlib-streams.ads
+++ b/compat/zlib/contrib/ada/zlib-streams.ads
@@ -6,7 +6,7 @@
-- Open source license information is in the zlib.ads file. --
----------------------------------------------------------------
--- $Id: zlib-streams.ads,v 1.3 2010/04/20 14:50:10 nijtmans Exp $
+-- $Id: zlib-streams.ads,v 1.12 2004/05/31 10:53:40 vagul Exp $
package ZLib.Streams is
diff --git a/compat/zlib/contrib/ada/zlib-thin.adb b/compat/zlib/contrib/ada/zlib-thin.adb
index 7e1f562..0ca4a71 100644
--- a/compat/zlib/contrib/ada/zlib-thin.adb
+++ b/compat/zlib/contrib/ada/zlib-thin.adb
@@ -6,7 +6,7 @@
-- Open source license information is in the zlib.ads file. --
----------------------------------------------------------------
--- $Id: zlib-thin.adb,v 1.3 2010/04/20 14:50:10 nijtmans Exp $
+-- $Id: zlib-thin.adb,v 1.8 2003/12/14 18:27:31 vagul Exp $
package body ZLib.Thin is
diff --git a/compat/zlib/contrib/ada/zlib-thin.ads b/compat/zlib/contrib/ada/zlib-thin.ads
index 7e8e074..d4407eb 100644
--- a/compat/zlib/contrib/ada/zlib-thin.ads
+++ b/compat/zlib/contrib/ada/zlib-thin.ads
@@ -6,7 +6,7 @@
-- Open source license information is in the zlib.ads file. --
----------------------------------------------------------------
--- $Id: zlib-thin.ads,v 1.3 2010/04/20 14:50:10 nijtmans Exp $
+-- $Id: zlib-thin.ads,v 1.11 2004/07/23 06:33:11 vagul Exp $
with Interfaces.C.Strings;
diff --git a/compat/zlib/contrib/ada/zlib.adb b/compat/zlib/contrib/ada/zlib.adb
index ec01b1d..8b6fd68 100644
--- a/compat/zlib/contrib/ada/zlib.adb
+++ b/compat/zlib/contrib/ada/zlib.adb
@@ -6,7 +6,7 @@
-- Open source license information is in the zlib.ads file. --
----------------------------------------------------------------
--- $Id: zlib.adb,v 1.3 2010/04/20 14:50:10 nijtmans Exp $
+-- $Id: zlib.adb,v 1.31 2004/09/06 06:53:19 vagul Exp $
with Ada.Exceptions;
with Ada.Unchecked_Conversion;
diff --git a/compat/zlib/contrib/ada/zlib.ads b/compat/zlib/contrib/ada/zlib.ads
index bdf1397..79ffc40 100644
--- a/compat/zlib/contrib/ada/zlib.ads
+++ b/compat/zlib/contrib/ada/zlib.ads
@@ -25,7 +25,7 @@
-- covered by the GNU Public License. --
------------------------------------------------------------------------------
--- $Id: zlib.ads,v 1.3 2010/04/20 14:50:10 nijtmans Exp $
+-- $Id: zlib.ads,v 1.26 2004/09/06 06:53:19 vagul Exp $
with Ada.Streams;
diff --git a/compat/zlib/contrib/asm586/README.586 b/compat/zlib/contrib/asm586/README.586
deleted file mode 100644
index 6bb78f3..0000000
--- a/compat/zlib/contrib/asm586/README.586
+++ /dev/null
@@ -1,43 +0,0 @@
-This is a patched version of zlib modified to use
-Pentium-optimized assembly code in the deflation algorithm. The files
-changed/added by this patch are:
-
-README.586
-match.S
-
-The effectiveness of these modifications is a bit marginal, as the the
-program's bottleneck seems to be mostly L1-cache contention, for which
-there is no real way to work around without rewriting the basic
-algorithm. The speedup on average is around 5-10% (which is generally
-less than the amount of variance between subsequent executions).
-However, when used at level 9 compression, the cache contention can
-drop enough for the assembly version to achieve 10-20% speedup (and
-sometimes more, depending on the amount of overall redundancy in the
-files). Even here, though, cache contention can still be the limiting
-factor, depending on the nature of the program using the zlib library.
-This may also mean that better improvements will be seen on a Pentium
-with MMX, which suffers much less from L1-cache contention, but I have
-not yet verified this.
-
-Note that this code has been tailored for the Pentium in particular,
-and will not perform well on the Pentium Pro (due to the use of a
-partial register in the inner loop).
-
-If you are using an assembler other than GNU as, you will have to
-translate match.S to use your assembler's syntax. (Have fun.)
-
-Brian Raiter
-breadbox@muppetlabs.com
-April, 1998
-
-
-Added for zlib 1.1.3:
-
-The patches come from
-http://www.muppetlabs.com/~breadbox/software/assembly.html
-
-To compile zlib with this asm file, copy match.S to the zlib directory
-then do:
-
-CFLAGS="-O3 -DASMV" ./configure
-make OBJA=match.o
diff --git a/compat/zlib/contrib/asm586/match.S b/compat/zlib/contrib/asm586/match.S
deleted file mode 100644
index 0368b35..0000000
--- a/compat/zlib/contrib/asm586/match.S
+++ /dev/null
@@ -1,364 +0,0 @@
-/* match.s -- Pentium-optimized version of longest_match()
- * Written for zlib 1.1.2
- * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License.
- */
-
-#ifndef NO_UNDERLINE
-#define match_init _match_init
-#define longest_match _longest_match
-#endif
-
-#define MAX_MATCH (258)
-#define MIN_MATCH (3)
-#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
-#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
-
-/* stack frame offsets */
-
-#define wmask 0 /* local copy of s->wmask */
-#define window 4 /* local copy of s->window */
-#define windowbestlen 8 /* s->window + bestlen */
-#define chainlenscanend 12 /* high word: current chain len */
- /* low word: last bytes sought */
-#define scanstart 16 /* first two bytes of string */
-#define scanalign 20 /* dword-misalignment of string */
-#define nicematch 24 /* a good enough match size */
-#define bestlen 28 /* size of best match so far */
-#define scan 32 /* ptr to string wanting match */
-
-#define LocalVarsSize (36)
-/* saved ebx 36 */
-/* saved edi 40 */
-/* saved esi 44 */
-/* saved ebp 48 */
-/* return address 52 */
-#define deflatestate 56 /* the function arguments */
-#define curmatch 60
-
-/* Offsets for fields in the deflate_state structure. These numbers
- * are calculated from the definition of deflate_state, with the
- * assumption that the compiler will dword-align the fields. (Thus,
- * changing the definition of deflate_state could easily cause this
- * program to crash horribly, without so much as a warning at
- * compile time. Sigh.)
- */
-
-/* All the +zlib1222add offsets are due to the addition of fields
- * in zlib in the deflate_state structure since the asm code was first written
- * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
- * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
- * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
- */
-
-#define zlib1222add (8)
-
-#define dsWSize (36+zlib1222add)
-#define dsWMask (44+zlib1222add)
-#define dsWindow (48+zlib1222add)
-#define dsPrev (56+zlib1222add)
-#define dsMatchLen (88+zlib1222add)
-#define dsPrevMatch (92+zlib1222add)
-#define dsStrStart (100+zlib1222add)
-#define dsMatchStart (104+zlib1222add)
-#define dsLookahead (108+zlib1222add)
-#define dsPrevLen (112+zlib1222add)
-#define dsMaxChainLen (116+zlib1222add)
-#define dsGoodMatch (132+zlib1222add)
-#define dsNiceMatch (136+zlib1222add)
-
-
-.file "match.S"
-
-.globl match_init, longest_match
-
-.text
-
-/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
-
-longest_match:
-
-/* Save registers that the compiler may be using, and adjust %esp to */
-/* make room for our stack frame. */
-
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %ebx
- subl $LocalVarsSize, %esp
-
-/* Retrieve the function arguments. %ecx will hold cur_match */
-/* throughout the entire function. %edx will hold the pointer to the */
-/* deflate_state structure during the function's setup (before */
-/* entering the main loop). */
-
- movl deflatestate(%esp), %edx
- movl curmatch(%esp), %ecx
-
-/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
-
- movl dsNiceMatch(%edx), %eax
- movl dsLookahead(%edx), %ebx
- cmpl %eax, %ebx
- jl LookaheadLess
- movl %eax, %ebx
-LookaheadLess: movl %ebx, nicematch(%esp)
-
-/* register Bytef *scan = s->window + s->strstart; */
-
- movl dsWindow(%edx), %esi
- movl %esi, window(%esp)
- movl dsStrStart(%edx), %ebp
- lea (%esi,%ebp), %edi
- movl %edi, scan(%esp)
-
-/* Determine how many bytes the scan ptr is off from being */
-/* dword-aligned. */
-
- movl %edi, %eax
- negl %eax
- andl $3, %eax
- movl %eax, scanalign(%esp)
-
-/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
-/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
-
- movl dsWSize(%edx), %eax
- subl $MIN_LOOKAHEAD, %eax
- subl %eax, %ebp
- jg LimitPositive
- xorl %ebp, %ebp
-LimitPositive:
-
-/* unsigned chain_length = s->max_chain_length; */
-/* if (s->prev_length >= s->good_match) { */
-/* chain_length >>= 2; */
-/* } */
-
- movl dsPrevLen(%edx), %eax
- movl dsGoodMatch(%edx), %ebx
- cmpl %ebx, %eax
- movl dsMaxChainLen(%edx), %ebx
- jl LastMatchGood
- shrl $2, %ebx
-LastMatchGood:
-
-/* chainlen is decremented once beforehand so that the function can */
-/* use the sign flag instead of the zero flag for the exit test. */
-/* It is then shifted into the high word, to make room for the scanend */
-/* scanend value, which it will always accompany. */
-
- decl %ebx
- shll $16, %ebx
-
-/* int best_len = s->prev_length; */
-
- movl dsPrevLen(%edx), %eax
- movl %eax, bestlen(%esp)
-
-/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
-
- addl %eax, %esi
- movl %esi, windowbestlen(%esp)
-
-/* register ush scan_start = *(ushf*)scan; */
-/* register ush scan_end = *(ushf*)(scan+best_len-1); */
-
- movw (%edi), %bx
- movw %bx, scanstart(%esp)
- movw -1(%edi,%eax), %bx
- movl %ebx, chainlenscanend(%esp)
-
-/* Posf *prev = s->prev; */
-/* uInt wmask = s->w_mask; */
-
- movl dsPrev(%edx), %edi
- movl dsWMask(%edx), %edx
- mov %edx, wmask(%esp)
-
-/* Jump into the main loop. */
-
- jmp LoopEntry
-
-.balign 16
-
-/* do {
- * match = s->window + cur_match;
- * if (*(ushf*)(match+best_len-1) != scan_end ||
- * *(ushf*)match != scan_start) continue;
- * [...]
- * } while ((cur_match = prev[cur_match & wmask]) > limit
- * && --chain_length != 0);
- *
- * Here is the inner loop of the function. The function will spend the
- * majority of its time in this loop, and majority of that time will
- * be spent in the first ten instructions.
- *
- * Within this loop:
- * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
- * %ecx = curmatch
- * %edx = curmatch & wmask
- * %esi = windowbestlen - i.e., (window + bestlen)
- * %edi = prev
- * %ebp = limit
- *
- * Two optimization notes on the choice of instructions:
- *
- * The first instruction uses a 16-bit address, which costs an extra,
- * unpairable cycle. This is cheaper than doing a 32-bit access and
- * zeroing the high word, due to the 3-cycle misalignment penalty which
- * would occur half the time. This also turns out to be cheaper than
- * doing two separate 8-bit accesses, as the memory is so rarely in the
- * L1 cache.
- *
- * The window buffer, however, apparently spends a lot of time in the
- * cache, and so it is faster to retrieve the word at the end of the
- * match string with two 8-bit loads. The instructions that test the
- * word at the beginning of the match string, however, are executed
- * much less frequently, and there it was cheaper to use 16-bit
- * instructions, which avoided the necessity of saving off and
- * subsequently reloading one of the other registers.
- */
-LookupLoop:
- /* 1 U & V */
- movw (%edi,%edx,2), %cx /* 2 U pipe */
- movl wmask(%esp), %edx /* 2 V pipe */
- cmpl %ebp, %ecx /* 3 U pipe */
- jbe LeaveNow /* 3 V pipe */
- subl $0x00010000, %ebx /* 4 U pipe */
- js LeaveNow /* 4 V pipe */
-LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
- andl %ecx, %edx /* 5 V pipe */
- cmpb %bl, %al /* 6 U pipe */
- jnz LookupLoop /* 6 V pipe */
- movb (%esi,%ecx), %ah
- cmpb %bh, %ah
- jnz LookupLoop
- movl window(%esp), %eax
- movw (%eax,%ecx), %ax
- cmpw scanstart(%esp), %ax
- jnz LookupLoop
-
-/* Store the current value of chainlen. */
-
- movl %ebx, chainlenscanend(%esp)
-
-/* Point %edi to the string under scrutiny, and %esi to the string we */
-/* are hoping to match it up with. In actuality, %esi and %edi are */
-/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
-/* initialized to -(MAX_MATCH_8 - scanalign). */
-
- movl window(%esp), %esi
- movl scan(%esp), %edi
- addl %ecx, %esi
- movl scanalign(%esp), %eax
- movl $(-MAX_MATCH_8), %edx
- lea MAX_MATCH_8(%edi,%eax), %edi
- lea MAX_MATCH_8(%esi,%eax), %esi
-
-/* Test the strings for equality, 8 bytes at a time. At the end,
- * adjust %edx so that it is offset to the exact byte that mismatched.
- *
- * We already know at this point that the first three bytes of the
- * strings match each other, and they can be safely passed over before
- * starting the compare loop. So what this code does is skip over 0-3
- * bytes, as much as necessary in order to dword-align the %edi
- * pointer. (%esi will still be misaligned three times out of four.)
- *
- * It should be confessed that this loop usually does not represent
- * much of the total running time. Replacing it with a more
- * straightforward "rep cmpsb" would not drastically degrade
- * performance.
- */
-LoopCmps:
- movl (%esi,%edx), %eax
- movl (%edi,%edx), %ebx
- xorl %ebx, %eax
- jnz LeaveLoopCmps
- movl 4(%esi,%edx), %eax
- movl 4(%edi,%edx), %ebx
- xorl %ebx, %eax
- jnz LeaveLoopCmps4
- addl $8, %edx
- jnz LoopCmps
- jmp LenMaximum
-LeaveLoopCmps4: addl $4, %edx
-LeaveLoopCmps: testl $0x0000FFFF, %eax
- jnz LenLower
- addl $2, %edx
- shrl $16, %eax
-LenLower: subb $1, %al
- adcl $0, %edx
-
-/* Calculate the length of the match. If it is longer than MAX_MATCH, */
-/* then automatically accept it as the best possible match and leave. */
-
- lea (%edi,%edx), %eax
- movl scan(%esp), %edi
- subl %edi, %eax
- cmpl $MAX_MATCH, %eax
- jge LenMaximum
-
-/* If the length of the match is not longer than the best match we */
-/* have so far, then forget it and return to the lookup loop. */
-
- movl deflatestate(%esp), %edx
- movl bestlen(%esp), %ebx
- cmpl %ebx, %eax
- jg LongerMatch
- movl chainlenscanend(%esp), %ebx
- movl windowbestlen(%esp), %esi
- movl dsPrev(%edx), %edi
- movl wmask(%esp), %edx
- andl %ecx, %edx
- jmp LookupLoop
-
-/* s->match_start = cur_match; */
-/* best_len = len; */
-/* if (len >= nice_match) break; */
-/* scan_end = *(ushf*)(scan+best_len-1); */
-
-LongerMatch: movl nicematch(%esp), %ebx
- movl %eax, bestlen(%esp)
- movl %ecx, dsMatchStart(%edx)
- cmpl %ebx, %eax
- jge LeaveNow
- movl window(%esp), %esi
- addl %eax, %esi
- movl %esi, windowbestlen(%esp)
- movl chainlenscanend(%esp), %ebx
- movw -1(%edi,%eax), %bx
- movl dsPrev(%edx), %edi
- movl %ebx, chainlenscanend(%esp)
- movl wmask(%esp), %edx
- andl %ecx, %edx
- jmp LookupLoop
-
-/* Accept the current string, with the maximum possible length. */
-
-LenMaximum: movl deflatestate(%esp), %edx
- movl $MAX_MATCH, bestlen(%esp)
- movl %ecx, dsMatchStart(%edx)
-
-/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
-/* return s->lookahead; */
-
-LeaveNow:
- movl deflatestate(%esp), %edx
- movl bestlen(%esp), %ebx
- movl dsLookahead(%edx), %eax
- cmpl %eax, %ebx
- jg LookaheadRet
- movl %ebx, %eax
-LookaheadRet:
-
-/* Restore the stack and return from whence we came. */
-
- addl $LocalVarsSize, %esp
- popl %ebx
- popl %esi
- popl %edi
- popl %ebp
-match_init: ret
diff --git a/compat/zlib/contrib/asm686/match.S b/compat/zlib/contrib/asm686/match.S
index 06817e1..fa42109 100644
--- a/compat/zlib/contrib/asm686/match.S
+++ b/compat/zlib/contrib/asm686/match.S
@@ -83,17 +83,25 @@
.text
/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
+.cfi_sections .debug_frame
longest_match:
+.cfi_startproc
/* Save registers that the compiler may be using, and adjust %esp to */
/* make room for our stack frame. */
pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset ebp, -8
pushl %edi
+ .cfi_def_cfa_offset 12
pushl %esi
+ .cfi_def_cfa_offset 16
pushl %ebx
+ .cfi_def_cfa_offset 20
subl $LocalVarsSize, %esp
+ .cfi_def_cfa_offset LocalVarsSize+20
/* Retrieve the function arguments. %ecx will hold cur_match */
/* throughout the entire function. %edx will hold the pointer to the */
@@ -108,7 +116,7 @@ longest_match:
/* if (s->prev_length >= s->good_match) { */
/* chain_length >>= 2; */
/* } */
-
+
movl dsPrevLen(%edx), %eax
movl dsGoodMatch(%edx), %ebx
cmpl %ebx, %eax
@@ -336,8 +344,14 @@ LookaheadRet:
/* Restore the stack and return from whence we came. */
addl $LocalVarsSize, %esp
+ .cfi_def_cfa_offset 20
popl %ebx
+ .cfi_def_cfa_offset 16
popl %esi
+ .cfi_def_cfa_offset 12
popl %edi
+ .cfi_def_cfa_offset 8
popl %ebp
+ .cfi_def_cfa_offset 4
+.cfi_endproc
match_init: ret
diff --git a/compat/zlib/contrib/blast/blast.c b/compat/zlib/contrib/blast/blast.c
index 4ce697a..69ef0fe 100644
--- a/compat/zlib/contrib/blast/blast.c
+++ b/compat/zlib/contrib/blast/blast.c
@@ -1,7 +1,7 @@
/* blast.c
- * Copyright (C) 2003 Mark Adler
+ * Copyright (C) 2003, 2012 Mark Adler
* For conditions of distribution and use, see copyright notice in blast.h
- * version 1.1, 16 Feb 2003
+ * version 1.2, 24 Oct 2012
*
* blast.c decompresses data compressed by the PKWare Compression Library.
* This function provides functionality similar to the explode() function of
@@ -22,6 +22,8 @@
*
* 1.0 12 Feb 2003 - First version
* 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data
+ * 1.2 24 Oct 2012 - Add note about using binary mode in stdio
+ * - Fix comparisons of differently signed integers
*/
#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
@@ -279,7 +281,7 @@ local int decomp(struct state *s)
int dict; /* log2(dictionary size) - 6 */
int symbol; /* decoded symbol, extra bits for distance */
int len; /* length for copy */
- int dist; /* distance for copy */
+ unsigned dist; /* distance for copy */
int copy; /* copy counter */
unsigned char *from, *to; /* copy pointers */
static int virgin = 1; /* build tables once */
diff --git a/compat/zlib/contrib/blast/blast.h b/compat/zlib/contrib/blast/blast.h
index ce9e541..658cfd3 100644
--- a/compat/zlib/contrib/blast/blast.h
+++ b/compat/zlib/contrib/blast/blast.h
@@ -1,6 +1,6 @@
/* blast.h -- interface for blast.c
- Copyright (C) 2003 Mark Adler
- version 1.1, 16 Feb 2003
+ Copyright (C) 2003, 2012 Mark Adler
+ version 1.2, 24 Oct 2012
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
@@ -28,6 +28,10 @@
* that library. (Note: PKWare overused the "implode" verb, and the format
* used by their library implode() function is completely different and
* incompatible with the implode compression method supported by PKZIP.)
+ *
+ * The binary mode for stdio functions should be used to assure that the
+ * compressed data is not corrupted when read or written. For example:
+ * fopen(..., "rb") and fopen(..., "wb").
*/
diff --git a/compat/zlib/contrib/delphi/ZLib.pas b/compat/zlib/contrib/delphi/ZLib.pas
index 0d86fb5..a579974 100644
--- a/compat/zlib/contrib/delphi/ZLib.pas
+++ b/compat/zlib/contrib/delphi/ZLib.pas
@@ -152,7 +152,7 @@ procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
const OutBuf: Pointer; BufSize: Integer);
const
- zlib_version = '1.2.5';
+ zlib_version = '1.2.8';
type
EZlibError = class(Exception);
diff --git a/compat/zlib/contrib/delphi/zlibd32.mak b/compat/zlib/contrib/delphi/zlibd32.mak
index 0d0699a..9bb00b7 100644
--- a/compat/zlib/contrib/delphi/zlibd32.mak
+++ b/compat/zlib/contrib/delphi/zlibd32.mak
@@ -63,9 +63,9 @@ uncompr.obj: uncompr.c zlib.h zconf.h
zutil.obj: zutil.c zutil.h zlib.h zconf.h
-example.obj: example.c zlib.h zconf.h
+example.obj: test/example.c zlib.h zconf.h
-minigzip.obj: minigzip.c zlib.h zconf.h
+minigzip.obj: test/minigzip.c zlib.h zconf.h
# For the sake of the old Borland make,
diff --git a/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs b/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
index 3bbcc8c..b273d54 100644
--- a/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
+++ b/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
@@ -1,5 +1,5 @@
//
-// © Copyright Henrik Ravn 2004
+// © Copyright Henrik Ravn 2004
//
// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -156,7 +156,7 @@ namespace DotZLibTests
public void Info_Version()
{
Info info = new Info();
- Assert.AreEqual("1.2.5", Info.Version);
+ Assert.AreEqual("1.2.8", Info.Version);
Assert.AreEqual(32, info.SizeOfUInt);
Assert.AreEqual(32, info.SizeOfULong);
Assert.AreEqual(32, info.SizeOfPointer);
diff --git a/compat/zlib/contrib/infback9/infback9.c b/compat/zlib/contrib/infback9/infback9.c
index 7bbe90c..05fb3e3 100644
--- a/compat/zlib/contrib/infback9/infback9.c
+++ b/compat/zlib/contrib/infback9/infback9.c
@@ -222,14 +222,13 @@ out_func out;
void FAR *out_desc;
{
struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
+ z_const unsigned char FAR *next; /* next input */
unsigned char FAR *put; /* next output */
unsigned have; /* available input */
unsigned long left; /* available output */
inflate_mode mode; /* current inflate mode */
int lastblock; /* true if processing last block */
int wrap; /* true if the window has wrapped */
- unsigned long write; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
unsigned long hold; /* bit buffer */
unsigned bits; /* bits in bit buffer */
@@ -259,7 +258,6 @@ void FAR *out_desc;
strm->msg = Z_NULL;
mode = TYPE;
lastblock = 0;
- write = 0;
wrap = 0;
window = state->window;
next = strm->next_in;
diff --git a/compat/zlib/contrib/infback9/inftree9.c b/compat/zlib/contrib/infback9/inftree9.c
index 306c5f1..4a73ad2 100644
--- a/compat/zlib/contrib/infback9/inftree9.c
+++ b/compat/zlib/contrib/infback9/inftree9.c
@@ -1,5 +1,5 @@
/* inftree9.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2010 Mark Adler
+ * Copyright (C) 1995-2013 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -9,7 +9,7 @@
#define MAXBITS 15
const char inflate9_copyright[] =
- " inflate9 1.2.5 Copyright 1995-2010 Mark Adler ";
+ " inflate9 1.2.8 Copyright 1995-2013 Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
@@ -64,7 +64,7 @@ unsigned short FAR *work;
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
- 133, 133, 133, 133, 144, 73, 195};
+ 133, 133, 133, 133, 144, 72, 78};
static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
diff --git a/compat/zlib/contrib/iostream2/zstream.h b/compat/zlib/contrib/iostream2/zstream.h
index ba5e328..43d2332 100644
--- a/compat/zlib/contrib/iostream2/zstream.h
+++ b/compat/zlib/contrib/iostream2/zstream.h
@@ -21,7 +21,7 @@
/*
* zstream.h - C++ interface to the 'zlib' general purpose compression library
- * $Id: zstream.h,v 1.3 2010/04/20 14:50:10 nijtmans Exp $
+ * $Id: zstream.h 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $
*/
#include <strstream.h>
diff --git a/compat/zlib/contrib/masm686/match.asm b/compat/zlib/contrib/masm686/match.asm
deleted file mode 100644
index 4b03a71..0000000
--- a/compat/zlib/contrib/masm686/match.asm
+++ /dev/null
@@ -1,413 +0,0 @@
-
-; match.asm -- Pentium-Pro optimized version of longest_match()
-;
-; Updated for zlib 1.1.3 and converted to MASM 6.1x
-; Copyright (C) 2000 Dan Higdon <hdan@kinesoft.com>
-; and Chuck Walbourn <chuckw@kinesoft.com>
-; Corrections by Cosmin Truta <cosmint@cs.ubbcluj.ro>
-;
-; This is free software; you can redistribute it and/or modify it
-; under the terms of the GNU General Public License.
-
-; Based on match.S
-; Written for zlib 1.1.2
-; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
-;
-; Modified by Gilles Vollant (2005) for add gzhead and gzindex
-
- .686P
- .MODEL FLAT
-
-;===========================================================================
-; EQUATES
-;===========================================================================
-
-MAX_MATCH EQU 258
-MIN_MATCH EQU 3
-MIN_LOOKAHEAD EQU (MAX_MATCH + MIN_MATCH + 1)
-MAX_MATCH_8 EQU ((MAX_MATCH + 7) AND (NOT 7))
-
-;===========================================================================
-; STRUCTURES
-;===========================================================================
-
-; This STRUCT assumes a 4-byte alignment
-
-DEFLATE_STATE STRUCT
-ds_strm dd ?
-ds_status dd ?
-ds_pending_buf dd ?
-ds_pending_buf_size dd ?
-ds_pending_out dd ?
-ds_pending dd ?
-ds_wrap dd ?
-; gzhead and gzindex are added in zlib 1.2.2.2 (see deflate.h)
-ds_gzhead dd ?
-ds_gzindex dd ?
-ds_data_type db ?
-ds_method db ?
- db ? ; padding
- db ? ; padding
-ds_last_flush dd ?
-ds_w_size dd ? ; used
-ds_w_bits dd ?
-ds_w_mask dd ? ; used
-ds_window dd ? ; used
-ds_window_size dd ?
-ds_prev dd ? ; used
-ds_head dd ?
-ds_ins_h dd ?
-ds_hash_size dd ?
-ds_hash_bits dd ?
-ds_hash_mask dd ?
-ds_hash_shift dd ?
-ds_block_start dd ?
-ds_match_length dd ? ; used
-ds_prev_match dd ? ; used
-ds_match_available dd ?
-ds_strstart dd ? ; used
-ds_match_start dd ? ; used
-ds_lookahead dd ? ; used
-ds_prev_length dd ? ; used
-ds_max_chain_length dd ? ; used
-ds_max_laxy_match dd ?
-ds_level dd ?
-ds_strategy dd ?
-ds_good_match dd ? ; used
-ds_nice_match dd ? ; used
-
-; Don't need anymore of the struct for match
-DEFLATE_STATE ENDS
-
-;===========================================================================
-; CODE
-;===========================================================================
-_TEXT SEGMENT
-
-;---------------------------------------------------------------------------
-; match_init
-;---------------------------------------------------------------------------
- ALIGN 4
-PUBLIC _match_init
-_match_init PROC
- ; no initialization needed
- ret
-_match_init ENDP
-
-;---------------------------------------------------------------------------
-; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
-;---------------------------------------------------------------------------
- ALIGN 4
-
-PUBLIC _longest_match
-_longest_match PROC
-
-; Since this code uses EBP for a scratch register, the stack frame must
-; be manually constructed and referenced relative to the ESP register.
-
-; Stack image
-; Variables
-chainlenwmask = 0 ; high word: current chain len
- ; low word: s->wmask
-window = 4 ; local copy of s->window
-windowbestlen = 8 ; s->window + bestlen
-scanend = 12 ; last two bytes of string
-scanstart = 16 ; first two bytes of string
-scanalign = 20 ; dword-misalignment of string
-nicematch = 24 ; a good enough match size
-bestlen = 28 ; size of best match so far
-scan = 32 ; ptr to string wanting match
-varsize = 36 ; number of bytes (also offset to last saved register)
-
-; Saved Registers (actually pushed into place)
-ebx_save = 36
-edi_save = 40
-esi_save = 44
-ebp_save = 48
-
-; Parameters
-retaddr = 52
-deflatestate = 56
-curmatch = 60
-
-; Save registers that the compiler may be using
- push ebp
- push edi
- push esi
- push ebx
-
-; Allocate local variable space
- sub esp,varsize
-
-; Retrieve the function arguments. ecx will hold cur_match
-; throughout the entire function. edx will hold the pointer to the
-; deflate_state structure during the function's setup (before
-; entering the main loop).
-
- mov edx, [esp+deflatestate]
-ASSUME edx:PTR DEFLATE_STATE
-
- mov ecx, [esp+curmatch]
-
-; uInt wmask = s->w_mask;
-; unsigned chain_length = s->max_chain_length;
-; if (s->prev_length >= s->good_match) {
-; chain_length >>= 2;
-; }
-
- mov eax, [edx].ds_prev_length
- mov ebx, [edx].ds_good_match
- cmp eax, ebx
- mov eax, [edx].ds_w_mask
- mov ebx, [edx].ds_max_chain_length
- jl SHORT LastMatchGood
- shr ebx, 2
-LastMatchGood:
-
-; chainlen is decremented once beforehand so that the function can
-; use the sign flag instead of the zero flag for the exit test.
-; It is then shifted into the high word, to make room for the wmask
-; value, which it will always accompany.
-
- dec ebx
- shl ebx, 16
- or ebx, eax
- mov [esp+chainlenwmask], ebx
-
-; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- mov eax, [edx].ds_nice_match
- mov ebx, [edx].ds_lookahead
- cmp ebx, eax
- jl SHORT LookaheadLess
- mov ebx, eax
-LookaheadLess:
- mov [esp+nicematch], ebx
-
-;/* register Bytef *scan = s->window + s->strstart; */
-
- mov esi, [edx].ds_window
- mov [esp+window], esi
- mov ebp, [edx].ds_strstart
- lea edi, [esi+ebp]
- mov [esp+scan],edi
-
-;/* Determine how many bytes the scan ptr is off from being */
-;/* dword-aligned. */
-
- mov eax, edi
- neg eax
- and eax, 3
- mov [esp+scanalign], eax
-
-;/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
-;/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
-
- mov eax, [edx].ds_w_size
- sub eax, MIN_LOOKAHEAD
- sub ebp, eax
- jg SHORT LimitPositive
- xor ebp, ebp
-LimitPositive:
-
-;/* int best_len = s->prev_length; */
-
- mov eax, [edx].ds_prev_length
- mov [esp+bestlen], eax
-
-;/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
-
- add esi, eax
- mov [esp+windowbestlen], esi
-
-;/* register ush scan_start = *(ushf*)scan; */
-;/* register ush scan_end = *(ushf*)(scan+best_len-1); */
-;/* Posf *prev = s->prev; */
-
- movzx ebx, WORD PTR[edi]
- mov [esp+scanstart], ebx
- movzx ebx, WORD PTR[eax+edi-1]
- mov [esp+scanend], ebx
- mov edi, [edx].ds_prev
-
-;/* Jump into the main loop. */
-
- mov edx, [esp+chainlenwmask]
- jmp SHORT LoopEntry
-
-;/* do {
-; * match = s->window + cur_match;
-; * if (*(ushf*)(match+best_len-1) != scan_end ||
-; * *(ushf*)match != scan_start) continue;
-; * [...]
-; * } while ((cur_match = prev[cur_match & wmask]) > limit
-; * && --chain_length != 0);
-; *
-; * Here is the inner loop of the function. The function will spend the
-; * majority of its time in this loop, and majority of that time will
-; * be spent in the first ten instructions.
-; *
-; * Within this loop:
-; * %ebx = scanend
-; * %ecx = curmatch
-; * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
-; * %esi = windowbestlen - i.e., (window + bestlen)
-; * %edi = prev
-; * %ebp = limit
-; */
-
- ALIGN 4
-LookupLoop:
- and ecx, edx
- movzx ecx, WORD PTR[edi+ecx*2]
- cmp ecx, ebp
- jbe LeaveNow
- sub edx, 000010000H
- js LeaveNow
-
-LoopEntry:
- movzx eax, WORD PTR[esi+ecx-1]
- cmp eax, ebx
- jnz SHORT LookupLoop
-
- mov eax, [esp+window]
- movzx eax, WORD PTR[eax+ecx]
- cmp eax, [esp+scanstart]
- jnz SHORT LookupLoop
-
-;/* Store the current value of chainlen. */
-
- mov [esp+chainlenwmask], edx
-
-;/* Point %edi to the string under scrutiny, and %esi to the string we */
-;/* are hoping to match it up with. In actuality, %esi and %edi are */
-;/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
-;/* initialized to -(MAX_MATCH_8 - scanalign). */
-
- mov esi, [esp+window]
- mov edi, [esp+scan]
- add esi, ecx
- mov eax, [esp+scanalign]
- mov edx, -MAX_MATCH_8
- lea edi, [edi+eax+MAX_MATCH_8]
- lea esi, [esi+eax+MAX_MATCH_8]
-
-;/* Test the strings for equality, 8 bytes at a time. At the end,
-; * adjust %edx so that it is offset to the exact byte that mismatched.
-; *
-; * We already know at this point that the first three bytes of the
-; * strings match each other, and they can be safely passed over before
-; * starting the compare loop. So what this code does is skip over 0-3
-; * bytes, as much as necessary in order to dword-align the %edi
-; * pointer. (%esi will still be misaligned three times out of four.)
-; *
-; * It should be confessed that this loop usually does not represent
-; * much of the total running time. Replacing it with a more
-; * straightforward "rep cmpsb" would not drastically degrade
-; * performance.
-; */
-
-LoopCmps:
- mov eax, DWORD PTR[esi+edx]
- xor eax, DWORD PTR[edi+edx]
- jnz SHORT LeaveLoopCmps
-
- mov eax, DWORD PTR[esi+edx+4]
- xor eax, DWORD PTR[edi+edx+4]
- jnz SHORT LeaveLoopCmps4
-
- add edx, 8
- jnz SHORT LoopCmps
- jmp LenMaximum
- ALIGN 4
-
-LeaveLoopCmps4:
- add edx, 4
-
-LeaveLoopCmps:
- test eax, 00000FFFFH
- jnz SHORT LenLower
-
- add edx, 2
- shr eax, 16
-
-LenLower:
- sub al, 1
- adc edx, 0
-
-;/* Calculate the length of the match. If it is longer than MAX_MATCH, */
-;/* then automatically accept it as the best possible match and leave. */
-
- lea eax, [edi+edx]
- mov edi, [esp+scan]
- sub eax, edi
- cmp eax, MAX_MATCH
- jge SHORT LenMaximum
-
-;/* If the length of the match is not longer than the best match we */
-;/* have so far, then forget it and return to the lookup loop. */
-
- mov edx, [esp+deflatestate]
- mov ebx, [esp+bestlen]
- cmp eax, ebx
- jg SHORT LongerMatch
- mov esi, [esp+windowbestlen]
- mov edi, [edx].ds_prev
- mov ebx, [esp+scanend]
- mov edx, [esp+chainlenwmask]
- jmp LookupLoop
- ALIGN 4
-
-;/* s->match_start = cur_match; */
-;/* best_len = len; */
-;/* if (len >= nice_match) break; */
-;/* scan_end = *(ushf*)(scan+best_len-1); */
-
-LongerMatch:
- mov ebx, [esp+nicematch]
- mov [esp+bestlen], eax
- mov [edx].ds_match_start, ecx
- cmp eax, ebx
- jge SHORT LeaveNow
- mov esi, [esp+window]
- add esi, eax
- mov [esp+windowbestlen], esi
- movzx ebx, WORD PTR[edi+eax-1]
- mov edi, [edx].ds_prev
- mov [esp+scanend], ebx
- mov edx, [esp+chainlenwmask]
- jmp LookupLoop
- ALIGN 4
-
-;/* Accept the current string, with the maximum possible length. */
-
-LenMaximum:
- mov edx, [esp+deflatestate]
- mov DWORD PTR[esp+bestlen], MAX_MATCH
- mov [edx].ds_match_start, ecx
-
-;/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
-;/* return s->lookahead; */
-
-LeaveNow:
- mov edx, [esp+deflatestate]
- mov ebx, [esp+bestlen]
- mov eax, [edx].ds_lookahead
- cmp ebx, eax
- jg SHORT LookaheadRet
- mov eax, ebx
-LookaheadRet:
-
-; Restore the stack and return from whence we came.
-
- add esp, varsize
- pop ebx
- pop esi
- pop edi
- pop ebp
- ret
-
-_longest_match ENDP
-
-_TEXT ENDS
-END
diff --git a/compat/zlib/contrib/masmx64/gvmat64.obj b/compat/zlib/contrib/masmx64/gvmat64.obj
deleted file mode 100644
index a49ca02..0000000
--- a/compat/zlib/contrib/masmx64/gvmat64.obj
+++ /dev/null
Binary files differ
diff --git a/compat/zlib/contrib/masmx64/inffasx64.obj b/compat/zlib/contrib/masmx64/inffasx64.obj
deleted file mode 100644
index 8df5d82..0000000
--- a/compat/zlib/contrib/masmx64/inffasx64.obj
+++ /dev/null
Binary files differ
diff --git a/compat/zlib/contrib/masmx86/gvmat32.asm b/compat/zlib/contrib/masmx86/gvmat32.asm
deleted file mode 100644
index 874bb2d..0000000
--- a/compat/zlib/contrib/masmx86/gvmat32.asm
+++ /dev/null
@@ -1,972 +0,0 @@
-; gvmat32.asm -- Asm portion of the optimized longest_match for 32 bits x86
-; Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
-; File written by Gilles Vollant, by modifiying the longest_match
-; from Jean-loup Gailly in deflate.c
-;
-; http://www.zlib.net
-; http://www.winimage.com/zLibDll
-; http://www.muppetlabs.com/~breadbox/software/assembly.html
-;
-; For Visual C++ 4.x and higher and ML 6.x and higher
-; ml.exe is in directory \MASM611C of Win95 DDK
-; ml.exe is also distributed in http://www.masm32.com/masmdl.htm
-; and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/
-;
-; this file contain two implementation of longest_match
-;
-; longest_match_7fff : written 1996 by Gilles Vollant optimized for
-; first Pentium. Assume s->w_mask == 0x7fff
-; longest_match_686 : written by Brian raiter (1998), optimized for Pentium Pro
-;
-; for using an seembly version of longest_match, you need define ASMV in project
-; There is two way in using gvmat32.asm
-;
-; A) Suggested method
-; if you want include both longest_match_7fff and longest_match_686
-; compile the asm file running
-; ml /coff /Zi /Flgvmat32.lst /c gvmat32.asm
-; and include gvmat32c.c in your project
-; if you have an old cpu (386,486 or first Pentium) and s->w_mask==0x7fff,
-; longest_match_7fff will be used
-; if you have a more modern CPU (Pentium Pro, II and higher)
-; longest_match_686 will be used
-; on old cpu with s->w_mask!=0x7fff, longest_match_686 will be used,
-; but this is not a sitation you'll find often
-;
-; B) Alternative
-; if you are not interresed in old cpu performance and want the smaller
-; binaries possible
-;
-; compile the asm file running
-; ml /coff /Zi /c /Flgvmat32.lst /DNOOLDPENTIUMCODE gvmat32.asm
-; and do not include gvmat32c.c in your project (ou define also
-; NOOLDPENTIUMCODE)
-;
-; note : as I known, longest_match_686 is very faster than longest_match_7fff
-; on pentium Pro/II/III, faster (but less) in P4, but it seem
-; longest_match_7fff can be faster (very very litte) on AMD Athlon64/K8
-;
-; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2
-
-;uInt longest_match_7fff(s, cur_match)
-; deflate_state *s;
-; IPos cur_match; /* current match */
-
- NbStack equ 76
- cur_match equ dword ptr[esp+NbStack-0]
- str_s equ dword ptr[esp+NbStack-4]
-; 5 dword on top (ret,ebp,esi,edi,ebx)
- adrret equ dword ptr[esp+NbStack-8]
- pushebp equ dword ptr[esp+NbStack-12]
- pushedi equ dword ptr[esp+NbStack-16]
- pushesi equ dword ptr[esp+NbStack-20]
- pushebx equ dword ptr[esp+NbStack-24]
-
- chain_length equ dword ptr [esp+NbStack-28]
- limit equ dword ptr [esp+NbStack-32]
- best_len equ dword ptr [esp+NbStack-36]
- window equ dword ptr [esp+NbStack-40]
- prev equ dword ptr [esp+NbStack-44]
- scan_start equ word ptr [esp+NbStack-48]
- wmask equ dword ptr [esp+NbStack-52]
- match_start_ptr equ dword ptr [esp+NbStack-56]
- nice_match equ dword ptr [esp+NbStack-60]
- scan equ dword ptr [esp+NbStack-64]
-
- windowlen equ dword ptr [esp+NbStack-68]
- match_start equ dword ptr [esp+NbStack-72]
- strend equ dword ptr [esp+NbStack-76]
- NbStackAdd equ (NbStack-24)
-
- .386p
-
- name gvmatch
- .MODEL FLAT
-
-
-
-; all the +zlib1222add offsets are due to the addition of fields
-; in zlib in the deflate_state structure since the asm code was first written
-; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
-; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
-; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
-
- zlib1222add equ 8
-
-; Note : these value are good with a 8 bytes boundary pack structure
- dep_chain_length equ 74h+zlib1222add
- dep_window equ 30h+zlib1222add
- dep_strstart equ 64h+zlib1222add
- dep_prev_length equ 70h+zlib1222add
- dep_nice_match equ 88h+zlib1222add
- dep_w_size equ 24h+zlib1222add
- dep_prev equ 38h+zlib1222add
- dep_w_mask equ 2ch+zlib1222add
- dep_good_match equ 84h+zlib1222add
- dep_match_start equ 68h+zlib1222add
- dep_lookahead equ 6ch+zlib1222add
-
-
-_TEXT segment
-
-IFDEF NOUNDERLINE
- IFDEF NOOLDPENTIUMCODE
- public longest_match
- public match_init
- ELSE
- public longest_match_7fff
- public cpudetect32
- public longest_match_686
- ENDIF
-ELSE
- IFDEF NOOLDPENTIUMCODE
- public _longest_match
- public _match_init
- ELSE
- public _longest_match_7fff
- public _cpudetect32
- public _longest_match_686
- ENDIF
-ENDIF
-
- MAX_MATCH equ 258
- MIN_MATCH equ 3
- MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)
-
-
-
-IFNDEF NOOLDPENTIUMCODE
-IFDEF NOUNDERLINE
-longest_match_7fff proc near
-ELSE
-_longest_match_7fff proc near
-ENDIF
-
- mov edx,[esp+4]
-
-
-
- push ebp
- push edi
- push esi
- push ebx
-
- sub esp,NbStackAdd
-
-; initialize or check the variables used in match.asm.
- mov ebp,edx
-
-; chain_length = s->max_chain_length
-; if (prev_length>=good_match) chain_length >>= 2
- mov edx,[ebp+dep_chain_length]
- mov ebx,[ebp+dep_prev_length]
- cmp [ebp+dep_good_match],ebx
- ja noshr
- shr edx,2
-noshr:
-; we increment chain_length because in the asm, the --chain_lenght is in the beginning of the loop
- inc edx
- mov edi,[ebp+dep_nice_match]
- mov chain_length,edx
- mov eax,[ebp+dep_lookahead]
- cmp eax,edi
-; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
- jae nolookaheadnicematch
- mov edi,eax
-nolookaheadnicematch:
-; best_len = s->prev_length
- mov best_len,ebx
-
-; window = s->window
- mov esi,[ebp+dep_window]
- mov ecx,[ebp+dep_strstart]
- mov window,esi
-
- mov nice_match,edi
-; scan = window + strstart
- add esi,ecx
- mov scan,esi
-; dx = *window
- mov dx,word ptr [esi]
-; bx = *(window+best_len-1)
- mov bx,word ptr [esi+ebx-1]
- add esi,MAX_MATCH-1
-; scan_start = *scan
- mov scan_start,dx
-; strend = scan + MAX_MATCH-1
- mov strend,esi
-; bx = scan_end = *(window+best_len-1)
-
-; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
-; s->strstart - (IPos)MAX_DIST(s) : NIL;
-
- mov esi,[ebp+dep_w_size]
- sub esi,MIN_LOOKAHEAD
-; here esi = MAX_DIST(s)
- sub ecx,esi
- ja nodist
- xor ecx,ecx
-nodist:
- mov limit,ecx
-
-; prev = s->prev
- mov edx,[ebp+dep_prev]
- mov prev,edx
-
-;
- mov edx,dword ptr [ebp+dep_match_start]
- mov bp,scan_start
- mov eax,cur_match
- mov match_start,edx
-
- mov edx,window
- mov edi,edx
- add edi,best_len
- mov esi,prev
- dec edi
-; windowlen = window + best_len -1
- mov windowlen,edi
-
- jmp beginloop2
- align 4
-
-; here, in the loop
-; eax = ax = cur_match
-; ecx = limit
-; bx = scan_end
-; bp = scan_start
-; edi = windowlen (window + best_len -1)
-; esi = prev
-
-
-;// here; chain_length <=16
-normalbeg0add16:
- add chain_length,16
- jz exitloop
-normalbeg0:
- cmp word ptr[edi+eax],bx
- je normalbeg2noroll
-rcontlabnoroll:
-; cur_match = prev[cur_match & wmask]
- and eax,7fffh
- mov ax,word ptr[esi+eax*2]
-; if cur_match > limit, go to exitloop
- cmp ecx,eax
- jnb exitloop
-; if --chain_length != 0, go to exitloop
- dec chain_length
- jnz normalbeg0
- jmp exitloop
-
-normalbeg2noroll:
-; if (scan_start==*(cur_match+window)) goto normalbeg2
- cmp bp,word ptr[edx+eax]
- jne rcontlabnoroll
- jmp normalbeg2
-
-contloop3:
- mov edi,windowlen
-
-; cur_match = prev[cur_match & wmask]
- and eax,7fffh
- mov ax,word ptr[esi+eax*2]
-; if cur_match > limit, go to exitloop
- cmp ecx,eax
-jnbexitloopshort1:
- jnb exitloop
-; if --chain_length != 0, go to exitloop
-
-
-; begin the main loop
-beginloop2:
- sub chain_length,16+1
-; if chain_length <=16, don't use the unrolled loop
- jna normalbeg0add16
-
-do16:
- cmp word ptr[edi+eax],bx
- je normalbeg2dc0
-
-maccn MACRO lab
- and eax,7fffh
- mov ax,word ptr[esi+eax*2]
- cmp ecx,eax
- jnb exitloop
- cmp word ptr[edi+eax],bx
- je lab
- ENDM
-
-rcontloop0:
- maccn normalbeg2dc1
-
-rcontloop1:
- maccn normalbeg2dc2
-
-rcontloop2:
- maccn normalbeg2dc3
-
-rcontloop3:
- maccn normalbeg2dc4
-
-rcontloop4:
- maccn normalbeg2dc5
-
-rcontloop5:
- maccn normalbeg2dc6
-
-rcontloop6:
- maccn normalbeg2dc7
-
-rcontloop7:
- maccn normalbeg2dc8
-
-rcontloop8:
- maccn normalbeg2dc9
-
-rcontloop9:
- maccn normalbeg2dc10
-
-rcontloop10:
- maccn short normalbeg2dc11
-
-rcontloop11:
- maccn short normalbeg2dc12
-
-rcontloop12:
- maccn short normalbeg2dc13
-
-rcontloop13:
- maccn short normalbeg2dc14
-
-rcontloop14:
- maccn short normalbeg2dc15
-
-rcontloop15:
- and eax,7fffh
- mov ax,word ptr[esi+eax*2]
- cmp ecx,eax
- jnb exitloop
-
- sub chain_length,16
- ja do16
- jmp normalbeg0add16
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-normbeg MACRO rcontlab,valsub
-; if we are here, we know that *(match+best_len-1) == scan_end
- cmp bp,word ptr[edx+eax]
-; if (match != scan_start) goto rcontlab
- jne rcontlab
-; calculate the good chain_length, and we'll compare scan and match string
- add chain_length,16-valsub
- jmp iseq
- ENDM
-
-
-normalbeg2dc11:
- normbeg rcontloop11,11
-
-normalbeg2dc12:
- normbeg short rcontloop12,12
-
-normalbeg2dc13:
- normbeg short rcontloop13,13
-
-normalbeg2dc14:
- normbeg short rcontloop14,14
-
-normalbeg2dc15:
- normbeg short rcontloop15,15
-
-normalbeg2dc10:
- normbeg rcontloop10,10
-
-normalbeg2dc9:
- normbeg rcontloop9,9
-
-normalbeg2dc8:
- normbeg rcontloop8,8
-
-normalbeg2dc7:
- normbeg rcontloop7,7
-
-normalbeg2dc6:
- normbeg rcontloop6,6
-
-normalbeg2dc5:
- normbeg rcontloop5,5
-
-normalbeg2dc4:
- normbeg rcontloop4,4
-
-normalbeg2dc3:
- normbeg rcontloop3,3
-
-normalbeg2dc2:
- normbeg rcontloop2,2
-
-normalbeg2dc1:
- normbeg rcontloop1,1
-
-normalbeg2dc0:
- normbeg rcontloop0,0
-
-
-; we go in normalbeg2 because *(ushf*)(match+best_len-1) == scan_end
-
-normalbeg2:
- mov edi,window
-
- cmp bp,word ptr[edi+eax]
- jne contloop3 ; if *(ushf*)match != scan_start, continue
-
-iseq:
-; if we are here, we know that *(match+best_len-1) == scan_end
-; and (match == scan_start)
-
- mov edi,edx
- mov esi,scan ; esi = scan
- add edi,eax ; edi = window + cur_match = match
-
- mov edx,[esi+3] ; compare manually dword at match+3
- xor edx,[edi+3] ; and scan +3
-
- jz begincompare ; if equal, go to long compare
-
-; we will determine the unmatch byte and calculate len (in esi)
- or dl,dl
- je eq1rr
- mov esi,3
- jmp trfinval
-eq1rr:
- or dx,dx
- je eq1
-
- mov esi,4
- jmp trfinval
-eq1:
- and edx,0ffffffh
- jz eq11
- mov esi,5
- jmp trfinval
-eq11:
- mov esi,6
- jmp trfinval
-
-begincompare:
- ; here we now scan and match begin same
- add edi,6
- add esi,6
- mov ecx,(MAX_MATCH-(2+4))/4 ; scan for at most MAX_MATCH bytes
- repe cmpsd ; loop until mismatch
-
- je trfin ; go to trfin if not unmatch
-; we determine the unmatch byte
- sub esi,4
- mov edx,[edi-4]
- xor edx,[esi]
-
- or dl,dl
- jnz trfin
- inc esi
-
- or dx,dx
- jnz trfin
- inc esi
-
- and edx,0ffffffh
- jnz trfin
- inc esi
-
-trfin:
- sub esi,scan ; esi = len
-trfinval:
-; here we have finised compare, and esi contain len of equal string
- cmp esi,best_len ; if len > best_len, go newbestlen
- ja short newbestlen
-; now we restore edx, ecx and esi, for the big loop
- mov esi,prev
- mov ecx,limit
- mov edx,window
- jmp contloop3
-
-newbestlen:
- mov best_len,esi ; len become best_len
-
- mov match_start,eax ; save new position as match_start
- cmp esi,nice_match ; if best_len >= nice_match, exit
- jae exitloop
- mov ecx,scan
- mov edx,window ; restore edx=window
- add ecx,esi
- add esi,edx
-
- dec esi
- mov windowlen,esi ; windowlen = window + best_len-1
- mov bx,[ecx-1] ; bx = *(scan+best_len-1) = scan_end
-
-; now we restore ecx and esi, for the big loop :
- mov esi,prev
- mov ecx,limit
- jmp contloop3
-
-exitloop:
-; exit : s->match_start=match_start
- mov ebx,match_start
- mov ebp,str_s
- mov ecx,best_len
- mov dword ptr [ebp+dep_match_start],ebx
- mov eax,dword ptr [ebp+dep_lookahead]
- cmp ecx,eax
- ja minexlo
- mov eax,ecx
-minexlo:
-; return min(best_len,s->lookahead)
-
-; restore stack and register ebx,esi,edi,ebp
- add esp,NbStackAdd
-
- pop ebx
- pop esi
- pop edi
- pop ebp
- ret
-InfoAuthor:
-; please don't remove this string !
-; Your are free use gvmat32 in any fre or commercial apps if you don't remove the string in the binary!
- db 0dh,0ah,"GVMat32 optimised assembly code written 1996-98 by Gilles Vollant",0dh,0ah
-
-
-
-IFDEF NOUNDERLINE
-longest_match_7fff endp
-ELSE
-_longest_match_7fff endp
-ENDIF
-
-
-IFDEF NOUNDERLINE
-cpudetect32 proc near
-ELSE
-_cpudetect32 proc near
-ENDIF
-
- push ebx
-
- pushfd ; push original EFLAGS
- pop eax ; get original EFLAGS
- mov ecx, eax ; save original EFLAGS
- xor eax, 40000h ; flip AC bit in EFLAGS
- push eax ; save new EFLAGS value on stack
- popfd ; replace current EFLAGS value
- pushfd ; get new EFLAGS
- pop eax ; store new EFLAGS in EAX
- xor eax, ecx ; can’t toggle AC bit, processor=80386
- jz end_cpu_is_386 ; jump if 80386 processor
- push ecx
- popfd ; restore AC bit in EFLAGS first
-
- pushfd
- pushfd
- pop ecx
-
- mov eax, ecx ; get original EFLAGS
- xor eax, 200000h ; flip ID bit in EFLAGS
- push eax ; save new EFLAGS value on stack
- popfd ; replace current EFLAGS value
- pushfd ; get new EFLAGS
- pop eax ; store new EFLAGS in EAX
- popfd ; restore original EFLAGS
- xor eax, ecx ; can’t toggle ID bit,
- je is_old_486 ; processor=old
-
- mov eax,1
- db 0fh,0a2h ;CPUID
-
-exitcpudetect:
- pop ebx
- ret
-
-end_cpu_is_386:
- mov eax,0300h
- jmp exitcpudetect
-
-is_old_486:
- mov eax,0400h
- jmp exitcpudetect
-
-IFDEF NOUNDERLINE
-cpudetect32 endp
-ELSE
-_cpudetect32 endp
-ENDIF
-ENDIF
-
-MAX_MATCH equ 258
-MIN_MATCH equ 3
-MIN_LOOKAHEAD equ (MAX_MATCH + MIN_MATCH + 1)
-MAX_MATCH_8_ equ ((MAX_MATCH + 7) AND 0FFF0h)
-
-
-;;; stack frame offsets
-
-chainlenwmask equ esp + 0 ; high word: current chain len
- ; low word: s->wmask
-window equ esp + 4 ; local copy of s->window
-windowbestlen equ esp + 8 ; s->window + bestlen
-scanstart equ esp + 16 ; first two bytes of string
-scanend equ esp + 12 ; last two bytes of string
-scanalign equ esp + 20 ; dword-misalignment of string
-nicematch equ esp + 24 ; a good enough match size
-bestlen equ esp + 28 ; size of best match so far
-scan equ esp + 32 ; ptr to string wanting match
-
-LocalVarsSize equ 36
-; saved ebx byte esp + 36
-; saved edi byte esp + 40
-; saved esi byte esp + 44
-; saved ebp byte esp + 48
-; return address byte esp + 52
-deflatestate equ esp + 56 ; the function arguments
-curmatch equ esp + 60
-
-;;; Offsets for fields in the deflate_state structure. These numbers
-;;; are calculated from the definition of deflate_state, with the
-;;; assumption that the compiler will dword-align the fields. (Thus,
-;;; changing the definition of deflate_state could easily cause this
-;;; program to crash horribly, without so much as a warning at
-;;; compile time. Sigh.)
-
-dsWSize equ 36+zlib1222add
-dsWMask equ 44+zlib1222add
-dsWindow equ 48+zlib1222add
-dsPrev equ 56+zlib1222add
-dsMatchLen equ 88+zlib1222add
-dsPrevMatch equ 92+zlib1222add
-dsStrStart equ 100+zlib1222add
-dsMatchStart equ 104+zlib1222add
-dsLookahead equ 108+zlib1222add
-dsPrevLen equ 112+zlib1222add
-dsMaxChainLen equ 116+zlib1222add
-dsGoodMatch equ 132+zlib1222add
-dsNiceMatch equ 136+zlib1222add
-
-
-;;; match.asm -- Pentium-Pro-optimized version of longest_match()
-;;; Written for zlib 1.1.2
-;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
-;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html
-;;;
-;;; This is free software; you can redistribute it and/or modify it
-;;; under the terms of the GNU General Public License.
-
-;GLOBAL _longest_match, _match_init
-
-
-;SECTION .text
-
-;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
-
-;_longest_match:
-IFDEF NOOLDPENTIUMCODE
- IFDEF NOUNDERLINE
- longest_match proc near
- ELSE
- _longest_match proc near
- ENDIF
-ELSE
- IFDEF NOUNDERLINE
- longest_match_686 proc near
- ELSE
- _longest_match_686 proc near
- ENDIF
-ENDIF
-
-;;; Save registers that the compiler may be using, and adjust esp to
-;;; make room for our stack frame.
-
- push ebp
- push edi
- push esi
- push ebx
- sub esp, LocalVarsSize
-
-;;; Retrieve the function arguments. ecx will hold cur_match
-;;; throughout the entire function. edx will hold the pointer to the
-;;; deflate_state structure during the function's setup (before
-;;; entering the main loop.
-
- mov edx, [deflatestate]
- mov ecx, [curmatch]
-
-;;; uInt wmask = s->w_mask;
-;;; unsigned chain_length = s->max_chain_length;
-;;; if (s->prev_length >= s->good_match) {
-;;; chain_length >>= 2;
-;;; }
-
- mov eax, [edx + dsPrevLen]
- mov ebx, [edx + dsGoodMatch]
- cmp eax, ebx
- mov eax, [edx + dsWMask]
- mov ebx, [edx + dsMaxChainLen]
- jl LastMatchGood
- shr ebx, 2
-LastMatchGood:
-
-;;; chainlen is decremented once beforehand so that the function can
-;;; use the sign flag instead of the zero flag for the exit test.
-;;; It is then shifted into the high word, to make room for the wmask
-;;; value, which it will always accompany.
-
- dec ebx
- shl ebx, 16
- or ebx, eax
- mov [chainlenwmask], ebx
-
-;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- mov eax, [edx + dsNiceMatch]
- mov ebx, [edx + dsLookahead]
- cmp ebx, eax
- jl LookaheadLess
- mov ebx, eax
-LookaheadLess: mov [nicematch], ebx
-
-;;; register Bytef *scan = s->window + s->strstart;
-
- mov esi, [edx + dsWindow]
- mov [window], esi
- mov ebp, [edx + dsStrStart]
- lea edi, [esi + ebp]
- mov [scan], edi
-
-;;; Determine how many bytes the scan ptr is off from being
-;;; dword-aligned.
-
- mov eax, edi
- neg eax
- and eax, 3
- mov [scanalign], eax
-
-;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
-;;; s->strstart - (IPos)MAX_DIST(s) : NIL;
-
- mov eax, [edx + dsWSize]
- sub eax, MIN_LOOKAHEAD
- sub ebp, eax
- jg LimitPositive
- xor ebp, ebp
-LimitPositive:
-
-;;; int best_len = s->prev_length;
-
- mov eax, [edx + dsPrevLen]
- mov [bestlen], eax
-
-;;; Store the sum of s->window + best_len in esi locally, and in esi.
-
- add esi, eax
- mov [windowbestlen], esi
-
-;;; register ush scan_start = *(ushf*)scan;
-;;; register ush scan_end = *(ushf*)(scan+best_len-1);
-;;; Posf *prev = s->prev;
-
- movzx ebx, word ptr [edi]
- mov [scanstart], ebx
- movzx ebx, word ptr [edi + eax - 1]
- mov [scanend], ebx
- mov edi, [edx + dsPrev]
-
-;;; Jump into the main loop.
-
- mov edx, [chainlenwmask]
- jmp short LoopEntry
-
-align 4
-
-;;; do {
-;;; match = s->window + cur_match;
-;;; if (*(ushf*)(match+best_len-1) != scan_end ||
-;;; *(ushf*)match != scan_start) continue;
-;;; [...]
-;;; } while ((cur_match = prev[cur_match & wmask]) > limit
-;;; && --chain_length != 0);
-;;;
-;;; Here is the inner loop of the function. The function will spend the
-;;; majority of its time in this loop, and majority of that time will
-;;; be spent in the first ten instructions.
-;;;
-;;; Within this loop:
-;;; ebx = scanend
-;;; ecx = curmatch
-;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
-;;; esi = windowbestlen - i.e., (window + bestlen)
-;;; edi = prev
-;;; ebp = limit
-
-LookupLoop:
- and ecx, edx
- movzx ecx, word ptr [edi + ecx*2]
- cmp ecx, ebp
- jbe LeaveNow
- sub edx, 00010000h
- js LeaveNow
-LoopEntry: movzx eax, word ptr [esi + ecx - 1]
- cmp eax, ebx
- jnz LookupLoop
- mov eax, [window]
- movzx eax, word ptr [eax + ecx]
- cmp eax, [scanstart]
- jnz LookupLoop
-
-;;; Store the current value of chainlen.
-
- mov [chainlenwmask], edx
-
-;;; Point edi to the string under scrutiny, and esi to the string we
-;;; are hoping to match it up with. In actuality, esi and edi are
-;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
-;;; initialized to -(MAX_MATCH_8 - scanalign).
-
- mov esi, [window]
- mov edi, [scan]
- add esi, ecx
- mov eax, [scanalign]
- mov edx, 0fffffef8h; -(MAX_MATCH_8)
- lea edi, [edi + eax + 0108h] ;MAX_MATCH_8]
- lea esi, [esi + eax + 0108h] ;MAX_MATCH_8]
-
-;;; Test the strings for equality, 8 bytes at a time. At the end,
-;;; adjust edx so that it is offset to the exact byte that mismatched.
-;;;
-;;; We already know at this point that the first three bytes of the
-;;; strings match each other, and they can be safely passed over before
-;;; starting the compare loop. So what this code does is skip over 0-3
-;;; bytes, as much as necessary in order to dword-align the edi
-;;; pointer. (esi will still be misaligned three times out of four.)
-;;;
-;;; It should be confessed that this loop usually does not represent
-;;; much of the total running time. Replacing it with a more
-;;; straightforward "rep cmpsb" would not drastically degrade
-;;; performance.
-
-LoopCmps:
- mov eax, [esi + edx]
- xor eax, [edi + edx]
- jnz LeaveLoopCmps
- mov eax, [esi + edx + 4]
- xor eax, [edi + edx + 4]
- jnz LeaveLoopCmps4
- add edx, 8
- jnz LoopCmps
- jmp short LenMaximum
-LeaveLoopCmps4: add edx, 4
-LeaveLoopCmps: test eax, 0000FFFFh
- jnz LenLower
- add edx, 2
- shr eax, 16
-LenLower: sub al, 1
- adc edx, 0
-
-;;; Calculate the length of the match. If it is longer than MAX_MATCH,
-;;; then automatically accept it as the best possible match and leave.
-
- lea eax, [edi + edx]
- mov edi, [scan]
- sub eax, edi
- cmp eax, MAX_MATCH
- jge LenMaximum
-
-;;; If the length of the match is not longer than the best match we
-;;; have so far, then forget it and return to the lookup loop.
-
- mov edx, [deflatestate]
- mov ebx, [bestlen]
- cmp eax, ebx
- jg LongerMatch
- mov esi, [windowbestlen]
- mov edi, [edx + dsPrev]
- mov ebx, [scanend]
- mov edx, [chainlenwmask]
- jmp LookupLoop
-
-;;; s->match_start = cur_match;
-;;; best_len = len;
-;;; if (len >= nice_match) break;
-;;; scan_end = *(ushf*)(scan+best_len-1);
-
-LongerMatch: mov ebx, [nicematch]
- mov [bestlen], eax
- mov [edx + dsMatchStart], ecx
- cmp eax, ebx
- jge LeaveNow
- mov esi, [window]
- add esi, eax
- mov [windowbestlen], esi
- movzx ebx, word ptr [edi + eax - 1]
- mov edi, [edx + dsPrev]
- mov [scanend], ebx
- mov edx, [chainlenwmask]
- jmp LookupLoop
-
-;;; Accept the current string, with the maximum possible length.
-
-LenMaximum: mov edx, [deflatestate]
- mov dword ptr [bestlen], MAX_MATCH
- mov [edx + dsMatchStart], ecx
-
-;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
-;;; return s->lookahead;
-
-LeaveNow:
- mov edx, [deflatestate]
- mov ebx, [bestlen]
- mov eax, [edx + dsLookahead]
- cmp ebx, eax
- jg LookaheadRet
- mov eax, ebx
-LookaheadRet:
-
-;;; Restore the stack and return from whence we came.
-
- add esp, LocalVarsSize
- pop ebx
- pop esi
- pop edi
- pop ebp
-
- ret
-; please don't remove this string !
-; Your can freely use gvmat32 in any free or commercial app if you don't remove the string in the binary!
- db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah
-
-
-IFDEF NOOLDPENTIUMCODE
- IFDEF NOUNDERLINE
- longest_match endp
- ELSE
- _longest_match endp
- ENDIF
-
- IFDEF NOUNDERLINE
- match_init proc near
- ret
- match_init endp
- ELSE
- _match_init proc near
- ret
- _match_init endp
- ENDIF
-ELSE
- IFDEF NOUNDERLINE
- longest_match_686 endp
- ELSE
- _longest_match_686 endp
- ENDIF
-ENDIF
-
-_TEXT ends
-end
diff --git a/compat/zlib/contrib/masmx86/gvmat32.obj b/compat/zlib/contrib/masmx86/gvmat32.obj
deleted file mode 100644
index ebb3262..0000000
--- a/compat/zlib/contrib/masmx86/gvmat32.obj
+++ /dev/null
Binary files differ
diff --git a/compat/zlib/contrib/masmx86/gvmat32c.c b/compat/zlib/contrib/masmx86/gvmat32c.c
deleted file mode 100644
index 7ad2b27..0000000
--- a/compat/zlib/contrib/masmx86/gvmat32c.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86
- * Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
- * File written by Gilles Vollant, by modifiying the longest_match
- * from Jean-loup Gailly in deflate.c
- * it prepare all parameters and call the assembly longest_match_gvasm
- * longest_match execute standard C code is wmask != 0x7fff
- * (assembly code is faster with a fixed wmask)
- *
- * Read comment at beginning of gvmat32.asm for more information
- */
-
-#if defined(ASMV) && (!defined(NOOLDPENTIUMCODE))
-#include "deflate.h"
-
-/* if your C compiler don't add underline before function name,
- define ADD_UNDERLINE_ASMFUNC */
-#ifdef ADD_UNDERLINE_ASMFUNC
-#define longest_match_7fff _longest_match_7fff
-#define longest_match_686 _longest_match_686
-#define cpudetect32 _cpudetect32
-#endif
-
-
-unsigned long cpudetect32();
-
-uInt longest_match_c(
- deflate_state *s,
- IPos cur_match); /* current match */
-
-
-uInt longest_match_7fff(
- deflate_state *s,
- IPos cur_match); /* current match */
-
-uInt longest_match_686(
- deflate_state *s,
- IPos cur_match); /* current match */
-
-
-static uInt iIsPPro=2;
-
-void match_init ()
-{
- iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
-}
-
-uInt longest_match(
- deflate_state *s,
- IPos cur_match) /* current match */
-{
- if (iIsPPro!=0)
- return longest_match_686(s,cur_match);
-
- if (s->w_mask != 0x7fff)
- return longest_match_686(s,cur_match);
-
- /* now ((s->w_mask == 0x7fff) && (iIsPPro==0)) */
- return longest_match_7fff(s,cur_match);
-}
-
-
-#endif /* defined(ASMV) && (!defined(NOOLDPENTIUMCODE)) */
diff --git a/compat/zlib/contrib/masmx86/inffas32.asm b/compat/zlib/contrib/masmx86/inffas32.asm
index 92ac22a..03d20f8 100644
--- a/compat/zlib/contrib/masmx86/inffas32.asm
+++ b/compat/zlib/contrib/masmx86/inffas32.asm
@@ -73,11 +73,6 @@ inflate_fast_use_mmx:
_TEXT segment
-PUBLIC _inflate_fast
-
-ALIGN 4
-_inflate_fast:
- jmp inflate_fast_entry
@@ -163,7 +158,8 @@ distbits_state equ (76+4+zlib1222sup) ;/* state->distbits */
;SECTION .text
ALIGN 4
-inflate_fast_entry:
+_inflate_fast proc near
+.FPO (16, 4, 0, 0, 1, 0)
push edi
push esi
push ebp
@@ -1078,6 +1074,7 @@ L_done:
pop esi
pop edi
ret
+_inflate_fast endp
_TEXT ends
end
diff --git a/compat/zlib/contrib/masmx86/inffas32.obj b/compat/zlib/contrib/masmx86/inffas32.obj
deleted file mode 100644
index bd6664d..0000000
--- a/compat/zlib/contrib/masmx86/inffas32.obj
+++ /dev/null
Binary files differ
diff --git a/compat/zlib/contrib/masmx86/match686.asm b/compat/zlib/contrib/masmx86/match686.asm
index 1eaf555..3b09212 100644
--- a/compat/zlib/contrib/masmx86/match686.asm
+++ b/compat/zlib/contrib/masmx86/match686.asm
@@ -195,6 +195,7 @@ dsNiceMatch equ 136+zlib1222add
ELSE
_longest_match proc near
ENDIF
+.FPO (9, 4, 0, 0, 1, 0)
;;; Save registers that the compiler may be using, and adjust esp to
;;; make room for our stack frame.
diff --git a/compat/zlib/contrib/masmx86/mkasm.bat b/compat/zlib/contrib/masmx86/mkasm.bat
deleted file mode 100755
index 70a51f8..0000000
--- a/compat/zlib/contrib/masmx86/mkasm.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-cl /DASMV /I..\.. /O2 /c gvmat32c.c
-ml /coff /Zi /c /Flgvmat32.lst gvmat32.asm
-ml /coff /Zi /c /Flinffas32.lst inffas32.asm
diff --git a/compat/zlib/contrib/minizip/ChangeLogUnzip b/compat/zlib/contrib/minizip/ChangeLogUnzip
deleted file mode 100644
index 50ca6a9..0000000
--- a/compat/zlib/contrib/minizip/ChangeLogUnzip
+++ /dev/null
@@ -1,67 +0,0 @@
-Change in 1.01e (12 feb 05)
-- Fix in zipOpen2 for globalcomment (Rolf Kalbermatter)
-- Fix possible memory leak in unzip.c (Zoran Stevanovic)
-
-Change in 1.01b (20 may 04)
-- Integrate patch from Debian package (submited by Mark Brown)
-- Add tools mztools from Xavier Roche
-
-Change in 1.01 (8 may 04)
-- fix buffer overrun risk in unzip.c (Xavier Roche)
-- fix a minor buffer insecurity in minizip.c (Mike Whittaker)
-
-Change in 1.00: (10 sept 03)
-- rename to 1.00
-- cosmetic code change
-
-Change in 0.22: (19 May 03)
-- crypting support (unless you define NOCRYPT)
-- append file in existing zipfile
-
-Change in 0.21: (10 Mar 03)
-- bug fixes
-
-Change in 0.17: (27 Jan 02)
-- bug fixes
-
-Change in 0.16: (19 Jan 02)
-- Support of ioapi for virtualize zip file access
-
-Change in 0.15: (19 Mar 98)
-- fix memory leak in minizip.c
-
-Change in 0.14: (10 Mar 98)
-- fix bugs in minizip.c sample for zipping big file
-- fix problem in month in date handling
-- fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for
- comment handling
-
-Change in 0.13: (6 Mar 98)
-- fix bugs in zip.c
-- add real minizip sample
-
-Change in 0.12: (4 Mar 98)
-- add zip.c and zip.h for creates .zip file
-- fix change_file_date in miniunz.c for Unix (Jean-loup Gailly)
-- fix miniunz.c for file without specific record for directory
-
-Change in 0.11: (3 Mar 98)
-- fix bug in unzGetCurrentFileInfo for get extra field and comment
-- enhance miniunz sample, remove the bad unztst.c sample
-
-Change in 0.10: (2 Mar 98)
-- fix bug in unzReadCurrentFile
-- rename unzip* to unz* function and structure
-- remove Windows-like hungary notation variable name
-- modify some structure in unzip.h
-- add somes comment in source
-- remove unzipGetcCurrentFile function
-- replace ZUNZEXPORT by ZEXPORT
-- add unzGetLocalExtrafield for get the local extrafield info
-- add a new sample, miniunz.c
-
-Change in 0.4: (25 Feb 98)
-- suppress the type unzipFileInZip.
- Only on file in the zipfile can be open at the same time
-- fix somes typo in code
-- added tm_unz structure in unzip_file_info (date/time in readable format)
diff --git a/compat/zlib/contrib/minizip/Makefile.am b/compat/zlib/contrib/minizip/Makefile.am
new file mode 100644
index 0000000..d343011
--- /dev/null
+++ b/compat/zlib/contrib/minizip/Makefile.am
@@ -0,0 +1,45 @@
+lib_LTLIBRARIES = libminizip.la
+
+if COND_DEMOS
+bin_PROGRAMS = miniunzip minizip
+endif
+
+zlib_top_srcdir = $(top_srcdir)/../..
+zlib_top_builddir = $(top_builddir)/../..
+
+AM_CPPFLAGS = -I$(zlib_top_srcdir)
+AM_LDFLAGS = -L$(zlib_top_builddir)
+
+if WIN32
+iowin32_src = iowin32.c
+iowin32_h = iowin32.h
+endif
+
+libminizip_la_SOURCES = \
+ ioapi.c \
+ mztools.c \
+ unzip.c \
+ zip.c \
+ ${iowin32_src}
+
+libminizip_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0 -lz
+
+minizip_includedir = $(includedir)/minizip
+minizip_include_HEADERS = \
+ crypt.h \
+ ioapi.h \
+ mztools.h \
+ unzip.h \
+ zip.h \
+ ${iowin32_h}
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = minizip.pc
+
+EXTRA_PROGRAMS = miniunzip minizip
+
+miniunzip_SOURCES = miniunz.c
+miniunzip_LDADD = libminizip.la
+
+minizip_SOURCES = minizip.c
+minizip_LDADD = libminizip.la -lz
diff --git a/compat/zlib/contrib/minizip/configure.ac b/compat/zlib/contrib/minizip/configure.ac
new file mode 100644
index 0000000..827a4e0
--- /dev/null
+++ b/compat/zlib/contrib/minizip/configure.ac
@@ -0,0 +1,32 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_INIT([minizip], [1.2.8], [bugzilla.redhat.com])
+AC_CONFIG_SRCDIR([minizip.c])
+AM_INIT_AUTOMAKE([foreign])
+LT_INIT
+
+AC_MSG_CHECKING([whether to build example programs])
+AC_ARG_ENABLE([demos], AC_HELP_STRING([--enable-demos], [build example programs]))
+AM_CONDITIONAL([COND_DEMOS], [test "$enable_demos" = yes])
+if test "$enable_demos" = yes
+then
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+
+case "${host}" in
+ *-mingw* | mingw*)
+ WIN32="yes"
+ ;;
+ *)
+ ;;
+esac
+AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"])
+
+
+AC_SUBST([HAVE_UNISTD_H], [0])
+AC_CHECK_HEADER([unistd.h], [HAVE_UNISTD_H=1], [])
+AC_CONFIG_FILES([Makefile minizip.pc])
+AC_OUTPUT
diff --git a/compat/zlib/contrib/minizip/crypt.h b/compat/zlib/contrib/minizip/crypt.h
index a01d08d..1e9e820 100644
--- a/compat/zlib/contrib/minizip/crypt.h
+++ b/compat/zlib/contrib/minizip/crypt.h
@@ -32,7 +32,7 @@
/***********************************************************************
* Return the next byte in the pseudo-random sequence
*/
-static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
+static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
{
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
* unpredictable manner on 16-bit systems; not a problem
@@ -45,7 +45,7 @@ static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
/***********************************************************************
* Update the encryption keys with the next byte of plain text
*/
-static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
+static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)
{
(*(pkeys+0)) = CRC32((*(pkeys+0)), c);
(*(pkeys+1)) += (*(pkeys+0)) & 0xff;
@@ -62,7 +62,7 @@ static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int
* Initialize the encryption keys and the random header according to
* the given password.
*/
-static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
+static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab)
{
*(pkeys+0) = 305419896L;
*(pkeys+1) = 591751049L;
@@ -91,7 +91,7 @@ static int crypthead(const char* passwd, /* password string */
unsigned char* buf, /* where to write header */
int bufSize,
unsigned long* pkeys,
- const unsigned long* pcrc_32_tab,
+ const z_crc_t* pcrc_32_tab,
unsigned long crcForCrypting)
{
int n; /* index in random header */
diff --git a/compat/zlib/contrib/minizip/ioapi.c b/compat/zlib/contrib/minizip/ioapi.c
index 49958f6..7f5c191 100644
--- a/compat/zlib/contrib/minizip/ioapi.c
+++ b/compat/zlib/contrib/minizip/ioapi.c
@@ -10,10 +10,22 @@
*/
-#if (defined(_WIN32))
+#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS)))
#define _CRT_SECURE_NO_WARNINGS
#endif
+#if defined(__APPLE__) || defined(IOAPI_NO_64)
+// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
+#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
+#define FTELLO_FUNC(stream) ftello(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
+#else
+#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
+#define FTELLO_FUNC(stream) ftello64(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
+#endif
+
+
#include "ioapi.h"
voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
@@ -47,7 +59,7 @@ ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream
else
{
uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
- if ((tell_uLong) == ((uLong)-1))
+ if ((tell_uLong) == MAXU32)
return (ZPOS64_T)-1;
else
return tell_uLong;
@@ -112,7 +124,7 @@ static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename,
mode_fopen = "wb";
if ((filename!=NULL) && (mode_fopen != NULL))
- file = fopen64((const char*)filename, mode_fopen);
+ file = FOPEN_FUNC((const char*)filename, mode_fopen);
return file;
}
@@ -142,7 +154,7 @@ static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
{
ZPOS64_T ret;
- ret = ftello64((FILE *)stream);
+ ret = FTELLO_FUNC((FILE *)stream);
return ret;
}
@@ -188,7 +200,7 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T
}
ret = 0;
- if(fseeko64((FILE *)stream, offset, fseek_origin) != 0)
+ if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0)
ret = -1;
return ret;
diff --git a/compat/zlib/contrib/minizip/ioapi.h b/compat/zlib/contrib/minizip/ioapi.h
index 8309c4c..8dcbdb0 100644
--- a/compat/zlib/contrib/minizip/ioapi.h
+++ b/compat/zlib/contrib/minizip/ioapi.h
@@ -21,7 +21,7 @@
#ifndef _ZLIBIOAPI64_H
#define _ZLIBIOAPI64_H
-#if (!defined(_WIN32)) && (!defined(WIN32))
+#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
// Linux needs this to support file operation on files larger then 4+GB
// But might need better if/def to select just the platforms that needs them.
@@ -38,6 +38,7 @@
#ifndef _FILE_OFFSET_BIT
#define _FILE_OFFSET_BIT 64
#endif
+
#endif
#include <stdio.h>
@@ -49,6 +50,11 @@
#define ftello64 ftell
#define fseeko64 fseek
#else
+#ifdef __FreeBSD__
+#define fopen64 fopen
+#define ftello64 ftello
+#define fseeko64 fseeko
+#endif
#ifdef _MSC_VER
#define fopen64 fopen
#if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
@@ -85,6 +91,8 @@ typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
typedef uint64_t ZPOS64_T;
#else
+/* Maximum unsigned 32-bit value used as placeholder for zip64 */
+#define MAXU32 0xffffffff
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ZPOS64_T;
diff --git a/compat/zlib/contrib/minizip/iowin32.c b/compat/zlib/contrib/minizip/iowin32.c
index 6a2a883..a46d96c 100644
--- a/compat/zlib/contrib/minizip/iowin32.c
+++ b/compat/zlib/contrib/minizip/iowin32.c
@@ -25,6 +25,13 @@
#define INVALID_SET_FILE_POINTER ((DWORD)-1)
#endif
+
+#if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API)))
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
+#define IOWIN32_USING_WINRT_API 1
+#endif
+#endif
+
voidpf ZCALLBACK win32_open_file_func OF((voidpf opaque, const char* filename, int mode));
uLong ZCALLBACK win32_read_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
uLong ZCALLBACK win32_write_file_func OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
@@ -93,8 +100,22 @@ voidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int
win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+#ifdef IOWIN32_USING_WINRT_API
+#ifdef UNICODE
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+#else
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ {
+ WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
+ MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
+ hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+ }
+#endif
+#else
if ((filename!=NULL) && (dwDesiredAccess != 0))
hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#endif
return win32_build_iowin(hFile);
}
@@ -108,8 +129,17 @@ voidpf ZCALLBACK win32_open64_file_funcA (voidpf opaque,const void* filename,int
win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+#ifdef IOWIN32_USING_WINRT_API
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ {
+ WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
+ MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
+ hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+ }
+#else
if ((filename!=NULL) && (dwDesiredAccess != 0))
hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#endif
return win32_build_iowin(hFile);
}
@@ -123,8 +153,13 @@ voidpf ZCALLBACK win32_open64_file_funcW (voidpf opaque,const void* filename,int
win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+#ifdef IOWIN32_USING_WINRT_API
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ hFile = CreateFile2((LPCWSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition,NULL);
+#else
if ((filename!=NULL) && (dwDesiredAccess != 0))
hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#endif
return win32_build_iowin(hFile);
}
@@ -138,8 +173,22 @@ voidpf ZCALLBACK win32_open_file_func (voidpf opaque,const char* filename,int mo
win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+#ifdef IOWIN32_USING_WINRT_API
+#ifdef UNICODE
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+#else
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ {
+ WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
+ MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
+ hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+ }
+#endif
+#else
if ((filename!=NULL) && (dwDesiredAccess != 0))
hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#endif
return win32_build_iowin(hFile);
}
@@ -188,6 +237,26 @@ uLong ZCALLBACK win32_write_file_func (voidpf opaque,voidpf stream,const void* b
return ret;
}
+static BOOL MySetFilePointerEx(HANDLE hFile, LARGE_INTEGER pos, LARGE_INTEGER *newPos, DWORD dwMoveMethod)
+{
+#ifdef IOWIN32_USING_WINRT_API
+ return SetFilePointerEx(hFile, pos, newPos, dwMoveMethod);
+#else
+ LONG lHigh = pos.HighPart;
+ DWORD dwNewPos = SetFilePointer(hFile, pos.LowPart, &lHigh, FILE_CURRENT);
+ BOOL fOk = TRUE;
+ if (dwNewPos == 0xFFFFFFFF)
+ if (GetLastError() != NO_ERROR)
+ fOk = FALSE;
+ if ((newPos != NULL) && (fOk))
+ {
+ newPos->LowPart = dwNewPos;
+ newPos->HighPart = lHigh;
+ }
+ return fOk;
+#endif
+}
+
long ZCALLBACK win32_tell_file_func (voidpf opaque,voidpf stream)
{
long ret=-1;
@@ -196,15 +265,17 @@ long ZCALLBACK win32_tell_file_func (voidpf opaque,voidpf stream)
hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
if (hFile != NULL)
{
- DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
- if (dwSet == INVALID_SET_FILE_POINTER)
+ LARGE_INTEGER pos;
+ pos.QuadPart = 0;
+
+ if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT))
{
DWORD dwErr = GetLastError();
((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
ret = -1;
}
else
- ret=(long)dwSet;
+ ret=(long)pos.LowPart;
}
return ret;
}
@@ -218,17 +289,17 @@ ZPOS64_T ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream)
if (hFile)
{
- LARGE_INTEGER li;
- li.QuadPart = 0;
- li.u.LowPart = SetFilePointer(hFile, li.u.LowPart, &li.u.HighPart, FILE_CURRENT);
- if ( (li.LowPart == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
+ LARGE_INTEGER pos;
+ pos.QuadPart = 0;
+
+ if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT))
{
DWORD dwErr = GetLastError();
((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
ret = (ZPOS64_T)-1;
}
else
- ret=li.QuadPart;
+ ret=pos.QuadPart;
}
return ret;
}
@@ -258,8 +329,9 @@ long ZCALLBACK win32_seek_file_func (voidpf opaque,voidpf stream,uLong offset,in
if (hFile != NULL)
{
- DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);
- if (dwSet == INVALID_SET_FILE_POINTER)
+ LARGE_INTEGER pos;
+ pos.QuadPart = offset;
+ if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod))
{
DWORD dwErr = GetLastError();
((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
@@ -296,9 +368,9 @@ long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream,ZPOS64_T off
if (hFile)
{
- LARGE_INTEGER* li = (LARGE_INTEGER*)&offset;
- DWORD dwSet = SetFilePointer(hFile, li->u.LowPart, &li->u.HighPart, dwMoveMethod);
- if (dwSet == INVALID_SET_FILE_POINTER)
+ LARGE_INTEGER pos;
+ pos.QuadPart = offset;
+ if (!MySetFilePointerEx(hFile, pos, NULL, FILE_CURRENT))
{
DWORD dwErr = GetLastError();
((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
diff --git a/compat/zlib/contrib/minizip/miniunz.c b/compat/zlib/contrib/minizip/miniunz.c
index 9ed009f..3d65401 100644
--- a/compat/zlib/contrib/minizip/miniunz.c
+++ b/compat/zlib/contrib/minizip/miniunz.c
@@ -12,7 +12,7 @@
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
*/
-#ifndef _WIN32
+#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
#ifndef __USE_FILE_OFFSET64
#define __USE_FILE_OFFSET64
#endif
@@ -27,6 +27,18 @@
#endif
#endif
+#ifdef __APPLE__
+// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
+#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
+#define FTELLO_FUNC(stream) ftello(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
+#else
+#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
+#define FTELLO_FUNC(stream) ftello64(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
+#endif
+
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -34,14 +46,15 @@
#include <errno.h>
#include <fcntl.h>
-#ifdef unix
-# include <unistd.h>
-# include <utime.h>
-#else
+#ifdef _WIN32
# include <direct.h>
# include <io.h>
+#else
+# include <unistd.h>
+# include <utime.h>
#endif
+
#include "unzip.h"
#define CASESENSITIVITY (0)
@@ -84,7 +97,7 @@ void change_file_date(filename,dosdate,tmu_date)
SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
CloseHandle(hFile);
#else
-#ifdef unix
+#ifdef unix || __APPLE__
struct utimbuf ut;
struct tm newdate;
newdate.tm_sec = tmu_date.tm_sec;
@@ -114,10 +127,10 @@ int mymkdir(dirname)
int ret=0;
#ifdef _WIN32
ret = _mkdir(dirname);
-#else
-#ifdef unix
+#elif unix
+ ret = mkdir (dirname,0775);
+#elif __APPLE__
ret = mkdir (dirname,0775);
-#endif
#endif
return ret;
}
@@ -364,7 +377,7 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
{
char rep=0;
FILE* ftestexist;
- ftestexist = fopen64(write_filename,"rb");
+ ftestexist = FOPEN_FUNC(write_filename,"rb");
if (ftestexist!=NULL)
{
fclose(ftestexist);
@@ -395,8 +408,7 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
if ((skip==0) && (err==UNZ_OK))
{
- fout=fopen64(write_filename,"wb");
-
+ fout=FOPEN_FUNC(write_filename,"wb");
/* some zipfile don't contain directory alone before file */
if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
(filename_withoutpath!=(char*)filename_inzip))
@@ -405,7 +417,7 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
*(filename_withoutpath-1)='\0';
makedir(write_filename);
*(filename_withoutpath-1)=c;
- fout=fopen64(write_filename,"wb");
+ fout=FOPEN_FUNC(write_filename,"wb");
}
if (fout==NULL)
diff --git a/compat/zlib/contrib/minizip/miniunzip.1 b/compat/zlib/contrib/minizip/miniunzip.1
new file mode 100644
index 0000000..111ac69
--- /dev/null
+++ b/compat/zlib/contrib/minizip/miniunzip.1
@@ -0,0 +1,63 @@
+.\" Hey, EMACS: -*- nroff -*-
+.TH miniunzip 1 "Nov 7, 2001"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh disable hyphenation
+.\" .hy enable hyphenation
+.\" .ad l left justify
+.\" .ad b justify to both left and right margins
+.\" .nf disable filling
+.\" .fi enable filling
+.\" .br insert line break
+.\" .sp <n> insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+miniunzip - uncompress and examine ZIP archives
+.SH SYNOPSIS
+.B miniunzip
+.RI [ -exvlo ]
+zipfile [ files_to_extract ] [-d tempdir]
+.SH DESCRIPTION
+.B minizip
+is a simple tool which allows the extraction of compressed file
+archives in the ZIP format used by the MS-DOS utility PKZIP. It was
+written as a demonstration of the
+.IR zlib (3)
+library and therefore lack many of the features of the
+.IR unzip (1)
+program.
+.SH OPTIONS
+A number of options are supported. With the exception of
+.BI \-d\ tempdir
+these must be supplied before any
+other arguments and are:
+.TP
+.BI \-l\ ,\ \-\-v
+List the files in the archive without extracting them.
+.TP
+.B \-o
+Overwrite files without prompting for confirmation.
+.TP
+.B \-x
+Extract files (default).
+.PP
+The
+.I zipfile
+argument is the name of the archive to process. The next argument can be used
+to specify a single file to extract from the archive.
+
+Lastly, the following option can be specified at the end of the command-line:
+.TP
+.BI \-d\ tempdir
+Extract the archive in the directory
+.I tempdir
+rather than the current directory.
+.SH SEE ALSO
+.BR minizip (1),
+.BR zlib (3),
+.BR unzip (1).
+.SH AUTHOR
+This program was written by Gilles Vollant. This manual page was
+written by Mark Brown <broonie@sirena.org.uk>. The -d tempdir option
+was added by Dirk Eddelbuettel <edd@debian.org>.
diff --git a/compat/zlib/contrib/minizip/minizip.1 b/compat/zlib/contrib/minizip/minizip.1
new file mode 100644
index 0000000..1154484
--- /dev/null
+++ b/compat/zlib/contrib/minizip/minizip.1
@@ -0,0 +1,46 @@
+.\" Hey, EMACS: -*- nroff -*-
+.TH minizip 1 "May 2, 2001"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh disable hyphenation
+.\" .hy enable hyphenation
+.\" .ad l left justify
+.\" .ad b justify to both left and right margins
+.\" .nf disable filling
+.\" .fi enable filling
+.\" .br insert line break
+.\" .sp <n> insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+minizip - create ZIP archives
+.SH SYNOPSIS
+.B minizip
+.RI [ -o ]
+zipfile [ " files" ... ]
+.SH DESCRIPTION
+.B minizip
+is a simple tool which allows the creation of compressed file archives
+in the ZIP format used by the MS-DOS utility PKZIP. It was written as
+a demonstration of the
+.IR zlib (3)
+library and therefore lack many of the features of the
+.IR zip (1)
+program.
+.SH OPTIONS
+The first argument supplied is the name of the ZIP archive to create or
+.RI -o
+in which case it is ignored and the second argument treated as the
+name of the ZIP file. If the ZIP file already exists it will be
+overwritten.
+.PP
+Subsequent arguments specify a list of files to place in the ZIP
+archive. If none are specified then an empty archive will be created.
+.SH SEE ALSO
+.BR miniunzip (1),
+.BR zlib (3),
+.BR zip (1).
+.SH AUTHOR
+This program was written by Gilles Vollant. This manual page was
+written by Mark Brown <broonie@sirena.org.uk>.
+
diff --git a/compat/zlib/contrib/minizip/minizip.c b/compat/zlib/contrib/minizip/minizip.c
index 7a4fa5a..4288962 100644
--- a/compat/zlib/contrib/minizip/minizip.c
+++ b/compat/zlib/contrib/minizip/minizip.c
@@ -13,7 +13,7 @@
*/
-#ifndef _WIN32
+#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
#ifndef __USE_FILE_OFFSET64
#define __USE_FILE_OFFSET64
#endif
@@ -28,6 +28,19 @@
#endif
#endif
+#ifdef __APPLE__
+// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
+#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
+#define FTELLO_FUNC(stream) ftello(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
+#else
+#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
+#define FTELLO_FUNC(stream) ftello64(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
+#endif
+
+
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -35,14 +48,14 @@
#include <errno.h>
#include <fcntl.h>
-#ifdef unix
+#ifdef _WIN32
+# include <direct.h>
+# include <io.h>
+#else
# include <unistd.h>
# include <utime.h>
# include <sys/types.h>
# include <sys/stat.h>
-#else
-# include <direct.h>
-# include <io.h>
#endif
#include "zip.h"
@@ -81,7 +94,7 @@ uLong filetime(f, tmzip, dt)
return ret;
}
#else
-#ifdef unix
+#ifdef unix || __APPLE__
uLong filetime(f, tmzip, dt)
char *f; /* name of file to get info on */
tm_zip *tmzip; /* return value: access, modific. and creation times */
@@ -142,7 +155,7 @@ int check_exist_file(filename)
{
FILE* ftestexist;
int ret = 1;
- ftestexist = fopen64(filename,"rb");
+ ftestexist = FOPEN_FUNC(filename,"rb");
if (ftestexist==NULL)
ret = 0;
else
@@ -173,7 +186,8 @@ int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigne
{
unsigned long calculate_crc=0;
int err=ZIP_OK;
- FILE * fin = fopen64(filenameinzip,"rb");
+ FILE * fin = FOPEN_FUNC(filenameinzip,"rb");
+
unsigned long size_read = 0;
unsigned long total_read = 0;
if (fin==NULL)
@@ -211,13 +225,12 @@ int isLargeFile(const char* filename)
{
int largeFile = 0;
ZPOS64_T pos = 0;
- FILE* pFile = fopen64(filename, "rb");
+ FILE* pFile = FOPEN_FUNC(filename, "rb");
if(pFile != NULL)
{
- int n = fseeko64(pFile, 0, SEEK_END);
-
- pos = ftello64(pFile);
+ int n = FSEEKO_FUNC(pFile, 0, SEEK_END);
+ pos = FTELLO_FUNC(pFile);
printf("File : %s is %lld bytes\n", filename, pos);
@@ -447,7 +460,7 @@ int main(argc,argv)
printf("error in opening %s in zipfile\n",filenameinzip);
else
{
- fin = fopen64(filenameinzip,"rb");
+ fin = FOPEN_FUNC(filenameinzip,"rb");
if (fin==NULL)
{
err=ZIP_ERRNO;
diff --git a/compat/zlib/contrib/minizip/minizip.pc.in b/compat/zlib/contrib/minizip/minizip.pc.in
new file mode 100644
index 0000000..69b5b7f
--- /dev/null
+++ b/compat/zlib/contrib/minizip/minizip.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/minizip
+
+Name: minizip
+Description: Minizip zip file manipulation library
+Requires:
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lminizip
+Libs.private: -lz
+Cflags: -I${includedir}
diff --git a/compat/zlib/contrib/minizip/mztools.c b/compat/zlib/contrib/minizip/mztools.c
index f9092e6..96891c2 100644
--- a/compat/zlib/contrib/minizip/mztools.c
+++ b/compat/zlib/contrib/minizip/mztools.c
@@ -42,7 +42,7 @@ uLong* bytesRecovered;
int entries = 0;
uLong totalBytes = 0;
char header[30];
- char filename[256];
+ char filename[1024];
char extra[1024];
int offset = 0;
int offsetCD = 0;
@@ -73,9 +73,14 @@ uLong* bytesRecovered;
/* Filename */
if (fnsize > 0) {
- if (fread(filename, 1, fnsize, fpZip) == fnsize) {
- if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
- offset += fnsize;
+ if (fnsize < sizeof(filename)) {
+ if (fread(filename, 1, fnsize, fpZip) == fnsize) {
+ if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
+ offset += fnsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
} else {
err = Z_ERRNO;
break;
@@ -91,9 +96,14 @@ uLong* bytesRecovered;
/* Extra field */
if (extsize > 0) {
- if (fread(extra, 1, extsize, fpZip) == extsize) {
- if (fwrite(extra, 1, extsize, fpOut) == extsize) {
- offset += extsize;
+ if (extsize < sizeof(extra)) {
+ if (fread(extra, 1, extsize, fpZip) == extsize) {
+ if (fwrite(extra, 1, extsize, fpOut) == extsize) {
+ offset += extsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
} else {
err = Z_ERRNO;
break;
diff --git a/compat/zlib/contrib/minizip/mztools.h b/compat/zlib/contrib/minizip/mztools.h
index 88b3459..a49a426 100644
--- a/compat/zlib/contrib/minizip/mztools.h
+++ b/compat/zlib/contrib/minizip/mztools.h
@@ -28,4 +28,10 @@ extern int ZEXPORT unzRepair(const char* file,
uLong* nRecovered,
uLong* bytesRecovered);
+
+#ifdef __cplusplus
+}
+#endif
+
+
#endif
diff --git a/compat/zlib/contrib/minizip/unzip.c b/compat/zlib/contrib/minizip/unzip.c
index 7617f41..9093504 100644
--- a/compat/zlib/contrib/minizip/unzip.c
+++ b/compat/zlib/contrib/minizip/unzip.c
@@ -188,7 +188,7 @@ typedef struct
# ifndef NOUNCRYPT
unsigned long keys[3]; /* keys defining the pseudo-random sequence */
- const unsigned long* pcrc_32_tab;
+ const z_crc_t* pcrc_32_tab;
# endif
} unz64_s;
@@ -801,9 +801,9 @@ extern unzFile ZEXPORT unzOpen64 (const void *path)
}
/*
- Close a ZipFile opened with unzipOpen.
- If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
- these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+ Close a ZipFile opened with unzOpen.
+ If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+ these files MUST be closed with unzCloseCurrentFile before call unzClose.
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzClose (unzFile file)
{
@@ -1040,26 +1040,26 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
{
uLong uL;
- if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1)
+ if(file_info.uncompressed_size == MAXU32)
{
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
err=UNZ_ERRNO;
}
- if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1)
+ if(file_info.compressed_size == MAXU32)
{
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
err=UNZ_ERRNO;
}
- if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1)
+ if(file_info_internal.offset_curfile == MAXU32)
{
/* Relative Header offset */
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
err=UNZ_ERRNO;
}
- if(file_info.disk_num_start == (unsigned long)-1)
+ if(file_info.disk_num_start == MAXU32)
{
/* Disk Start Number */
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
@@ -1145,7 +1145,7 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
szFileName,fileNameBufferSize,
extraField,extraFieldBufferSize,
szComment,commentBufferSize);
- if (err==UNZ_OK)
+ if ((err==UNZ_OK) && (pfile_info != NULL))
{
pfile_info->version = file_info64.version;
pfile_info->version_needed = file_info64.version_needed;
@@ -1223,7 +1223,7 @@ extern int ZEXPORT unzGoToNextFile (unzFile file)
/*
Try locate the file szFileName in the zipfile.
- For the iCaseSensitivity signification, see unzipStringFileNameCompare
+ For the iCaseSensitivity signification, see unzStringFileNameCompare
return value :
UNZ_OK if the file is found. It becomes the current file.
@@ -1696,7 +1696,7 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
return UNZ_PARAMERROR;
- if ((pfile_in_zip_read_info->read_buffer == NULL))
+ if (pfile_in_zip_read_info->read_buffer == NULL)
return UNZ_END_OF_LIST_OF_FILE;
if (len==0)
return 0;
@@ -1998,7 +1998,7 @@ extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
}
/*
- Close the file in zip opened with unzipOpenCurrentFile
+ Close the file in zip opened with unzOpenCurrentFile
Return UNZ_CRCERROR if all the file was read but the CRC is not good
*/
extern int ZEXPORT unzCloseCurrentFile (unzFile file)
diff --git a/compat/zlib/contrib/minizip/unzip.h b/compat/zlib/contrib/minizip/unzip.h
index 3183968..2104e39 100644
--- a/compat/zlib/contrib/minizip/unzip.h
+++ b/compat/zlib/contrib/minizip/unzip.h
@@ -197,9 +197,9 @@ extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
extern int ZEXPORT unzClose OF((unzFile file));
/*
- Close a ZipFile opened with unzipOpen.
+ Close a ZipFile opened with unzOpen.
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
- these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+ these files MUST be closed with unzCloseCurrentFile before call unzClose.
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
diff --git a/compat/zlib/contrib/minizip/zip.c b/compat/zlib/contrib/minizip/zip.c
index 3c34fc8..ea54853 100644
--- a/compat/zlib/contrib/minizip/zip.c
+++ b/compat/zlib/contrib/minizip/zip.c
@@ -157,7 +157,7 @@ typedef struct
ZPOS64_T totalUncompressedData;
#ifndef NOCRYPT
unsigned long keys[3]; /* keys defining the pseudo-random sequence */
- const unsigned long* pcrc_32_tab;
+ const z_crc_t* pcrc_32_tab;
int crypt_header_size;
#endif
} curfile64_info;
@@ -1067,6 +1067,7 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
int err = ZIP_OK;
# ifdef NOCRYPT
+ (crcForCrypting);
if (password != NULL)
return ZIP_PARAMERROR;
# endif
@@ -1114,9 +1115,9 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
zi->ci.flag = flagBase;
if ((level==8) || (level==9))
zi->ci.flag |= 2;
- if ((level==2))
+ if (level==2)
zi->ci.flag |= 4;
- if ((level==1))
+ if (level==1)
zi->ci.flag |= 6;
if (password != NULL)
zi->ci.flag |= 1;
@@ -1710,7 +1711,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_s
if (err==ZIP_OK)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
- if(uncompressed_size >= 0xffffffff)
+ if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )
{
if(zi->ci.pos_zip64extrainfo > 0)
{
@@ -1724,6 +1725,8 @@ extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_s
if (err==ZIP_OK) /* uncompressed size, unknown */
err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
}
+ else
+ err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
}
else
{
@@ -1852,7 +1855,7 @@ int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir,
err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
}
else
- err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
}
return err;
@@ -1919,7 +1922,7 @@ extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
free_linkedlist(&(zi->central_dir));
pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
- if(pos >= 0xffffffff)
+ if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
{
ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
diff --git a/compat/zlib/contrib/pascal/zlibd32.mak b/compat/zlib/contrib/pascal/zlibd32.mak
index 0d0699a..9bb00b7 100644
--- a/compat/zlib/contrib/pascal/zlibd32.mak
+++ b/compat/zlib/contrib/pascal/zlibd32.mak
@@ -63,9 +63,9 @@ uncompr.obj: uncompr.c zlib.h zconf.h
zutil.obj: zutil.c zutil.h zlib.h zconf.h
-example.obj: example.c zlib.h zconf.h
+example.obj: test/example.c zlib.h zconf.h
-minigzip.obj: minigzip.c zlib.h zconf.h
+minigzip.obj: test/minigzip.c zlib.h zconf.h
# For the sake of the old Borland make,
diff --git a/compat/zlib/contrib/pascal/zlibpas.pas b/compat/zlib/contrib/pascal/zlibpas.pas
index 637ae3a..e6a0782 100644
--- a/compat/zlib/contrib/pascal/zlibpas.pas
+++ b/compat/zlib/contrib/pascal/zlibpas.pas
@@ -10,7 +10,8 @@ unit zlibpas;
interface
const
- ZLIB_VERSION = '1.2.5';
+ ZLIB_VERSION = '1.2.8';
+ ZLIB_VERNUM = $1280;
type
alloc_func = function(opaque: Pointer; items, size: Integer): Pointer;
@@ -45,6 +46,23 @@ type
reserved: LongInt; (* reserved for future use *)
end;
+ gz_headerp = ^gz_header;
+ gz_header = packed record
+ text: Integer; (* true if compressed data believed to be text *)
+ time: LongInt; (* modification time *)
+ xflags: Integer; (* extra flags (not used when writing a gzip file) *)
+ os: Integer; (* operating system *)
+ extra: PChar; (* pointer to extra field or Z_NULL if none *)
+ extra_len: Integer; (* extra field length (valid if extra != Z_NULL) *)
+ extra_max: Integer; (* space at extra (only when reading header) *)
+ name: PChar; (* pointer to zero-terminated file name or Z_NULL *)
+ name_max: Integer; (* space at name (only when reading header) *)
+ comment: PChar; (* pointer to zero-terminated comment or Z_NULL *)
+ comm_max: Integer; (* space at comment (only when reading header) *)
+ hcrc: Integer; (* true if there was or will be a header crc *)
+ done: Integer; (* true when done reading gzip header *)
+ end;
+
(* constants *)
const
Z_NO_FLUSH = 0;
@@ -52,6 +70,8 @@ const
Z_SYNC_FLUSH = 2;
Z_FULL_FLUSH = 3;
Z_FINISH = 4;
+ Z_BLOCK = 5;
+ Z_TREES = 6;
Z_OK = 0;
Z_STREAM_END = 1;
@@ -71,9 +91,11 @@ const
Z_FILTERED = 1;
Z_HUFFMAN_ONLY = 2;
Z_RLE = 3;
+ Z_FIXED = 4;
Z_DEFAULT_STRATEGY = 0;
Z_BINARY = 0;
+ Z_TEXT = 1;
Z_ASCII = 1;
Z_UNKNOWN = 2;
@@ -96,14 +118,21 @@ function deflateSetDictionary(var strm: z_stream; const dictionary: PChar;
function deflateCopy(var dest, source: z_stream): Integer;
function deflateReset(var strm: z_stream): Integer;
function deflateParams(var strm: z_stream; level, strategy: Integer): Integer;
+function deflateTune(var strm: z_stream; good_length, max_lazy, nice_length, max_chain: Integer): Integer;
function deflateBound(var strm: z_stream; sourceLen: LongInt): LongInt;
+function deflatePending(var strm: z_stream; var pending: Integer; var bits: Integer): Integer;
function deflatePrime(var strm: z_stream; bits, value: Integer): Integer;
+function deflateSetHeader(var strm: z_stream; head: gz_header): Integer;
function inflateInit2(var strm: z_stream; windowBits: Integer): Integer;
function inflateSetDictionary(var strm: z_stream; const dictionary: PChar;
dictLength: Integer): Integer;
function inflateSync(var strm: z_stream): Integer;
function inflateCopy(var dest, source: z_stream): Integer;
function inflateReset(var strm: z_stream): Integer;
+function inflateReset2(var strm: z_stream; windowBits: Integer): Integer;
+function inflatePrime(var strm: z_stream; bits, value: Integer): Integer;
+function inflateMark(var strm: z_stream): LongInt;
+function inflateGetHeader(var strm: z_stream; var head: gz_header): Integer;
function inflateBackInit(var strm: z_stream;
windowBits: Integer; window: PChar): Integer;
function inflateBack(var strm: z_stream; in_fn: in_func; in_desc: Pointer;
@@ -123,7 +152,9 @@ function uncompress(dest: PChar; var destLen: LongInt;
(* checksum functions *)
function adler32(adler: LongInt; const buf: PChar; len: Integer): LongInt;
+function adler32_combine(adler1, adler2, len2: LongInt): LongInt;
function crc32(crc: LongInt; const buf: PChar; len: Integer): LongInt;
+function crc32_combine(crc1, crc2, len2: LongInt): LongInt;
(* various hacks, don't look :) *)
function deflateInit_(var strm: z_stream; level: Integer;
@@ -155,10 +186,12 @@ implementation
{$L zutil.obj}
function adler32; external;
+function adler32_combine; external;
function compress; external;
function compress2; external;
function compressBound; external;
function crc32; external;
+function crc32_combine; external;
function deflate; external;
function deflateBound; external;
function deflateCopy; external;
@@ -166,18 +199,25 @@ function deflateEnd; external;
function deflateInit_; external;
function deflateInit2_; external;
function deflateParams; external;
+function deflatePending; external;
function deflatePrime; external;
function deflateReset; external;
function deflateSetDictionary; external;
+function deflateSetHeader; external;
+function deflateTune; external;
function inflate; external;
function inflateBack; external;
function inflateBackEnd; external;
function inflateBackInit_; external;
function inflateCopy; external;
function inflateEnd; external;
+function inflateGetHeader; external;
function inflateInit_; external;
function inflateInit2_; external;
+function inflateMark; external;
+function inflatePrime; external;
function inflateReset; external;
+function inflateReset2; external;
function inflateSetDictionary; external;
function inflateSync; external;
function uncompress; external;
diff --git a/compat/zlib/contrib/puff/Makefile b/compat/zlib/contrib/puff/Makefile
index b6b6940..0e2594c 100644
--- a/compat/zlib/contrib/puff/Makefile
+++ b/compat/zlib/contrib/puff/Makefile
@@ -1,8 +1,42 @@
-puff: puff.c puff.h
- cc -DTEST -o puff puff.c
+CFLAGS=-O
+
+puff: puff.o pufftest.o
+
+puff.o: puff.h
+
+pufftest.o: puff.h
test: puff
puff zeros.raw
+puft: puff.c puff.h pufftest.o
+ cc -fprofile-arcs -ftest-coverage -o puft puff.c pufftest.o
+
+# puff full coverage test (should say 100%)
+cov: puft
+ @rm -f *.gcov *.gcda
+ @puft -w zeros.raw 2>&1 | cat > /dev/null
+ @echo '04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+ @echo '00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+ @echo '00 00 00 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 254
+ @echo '00 01 00 fe ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+ @echo '01 01 00 fe ff 0a' | xxd -r -p | puft -f 2>&1 | cat > /dev/null
+ @echo '02 7e ff ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246
+ @echo '02' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+ @echo '04 80 49 92 24 49 92 24 0f b4 ff ff c3 04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+ @echo '04 80 49 92 24 49 92 24 71 ff ff 93 11 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 249
+ @echo '04 c0 81 08 00 00 00 00 20 7f eb 0b 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246
+ @echo '0b 00 00' | xxd -r -p | puft -f 2>&1 | cat > /dev/null
+ @echo '1a 07' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246
+ @echo '0c c0 81 00 00 00 00 00 90 ff 6b 04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 245
+ @puft -f zeros.raw 2>&1 | cat > /dev/null
+ @echo 'fc 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 253
+ @echo '04 00 fe ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 252
+ @echo '04 00 24 49' | xxd -r -p | puft 2> /dev/null || test $$? -eq 251
+ @echo '04 80 49 92 24 49 92 24 0f b4 ff ff c3 84' | xxd -r -p | puft 2> /dev/null || test $$? -eq 248
+ @echo '04 00 24 e9 ff ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 250
+ @echo '04 00 24 e9 ff 6d' | xxd -r -p | puft 2> /dev/null || test $$? -eq 247
+ @gcov -n puff.c
+
clean:
- rm -f puff puff.o
+ rm -f puff puft *.o *.gc*
diff --git a/compat/zlib/contrib/puff/puff.c b/compat/zlib/contrib/puff/puff.c
index 650694e..ba58483 100644
--- a/compat/zlib/contrib/puff/puff.c
+++ b/compat/zlib/contrib/puff/puff.c
@@ -1,8 +1,8 @@
/*
* puff.c
- * Copyright (C) 2002-2010 Mark Adler
+ * Copyright (C) 2002-2013 Mark Adler
* For conditions of distribution and use, see copyright notice in puff.h
- * version 2.1, 4 Apr 2010
+ * version 2.3, 21 Jan 2013
*
* puff.c is a simple inflate written to be an unambiguous way to specify the
* deflate format. It is not written for speed but rather simplicity. As a
@@ -49,9 +49,9 @@
* - Fix fixed codes table error
* - Provide a scanning mode for determining size of
* uncompressed data
- * 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Jean-loup]
+ * 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Gailly]
* - Add a puff.h file for the interface
- * - Add braces in puff() for else do [Jean-loup]
+ * - Add braces in puff() for else do [Gailly]
* - Use indexes instead of pointers for readability
* 1.4 31 Mar 2002 - Simplify construct() code set check
* - Fix some comments
@@ -69,13 +69,20 @@
* - Allow TEST code to read from piped stdin
* 2.1 4 Apr 2010 - Avoid variable initialization for happier compilers
* - Avoid unsigned comparisons for even happier compilers
+ * 2.2 25 Apr 2010 - Fix bug in variable initializations [Oberhumer]
+ * - Add const where appropriate [Oberhumer]
+ * - Split if's and ?'s for coverage testing
+ * - Break out test code to separate file
+ * - Move NIL to puff.h
+ * - Allow incomplete code only if single code length is 1
+ * - Add full code coverage test to Makefile
+ * 2.3 21 Jan 2013 - Check for invalid code length codes in dynamic blocks
*/
#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
#include "puff.h" /* prototype for puff() */
#define local static /* for local function definitions */
-#define NIL ((unsigned char *)0) /* for no output option */
/*
* Maximums for allocations and loops. It is not useful to change these --
@@ -95,7 +102,7 @@ struct state {
unsigned long outcnt; /* bytes written to out so far */
/* input state */
- unsigned char *in; /* input buffer */
+ const unsigned char *in; /* input buffer */
unsigned long inlen; /* available input at in */
unsigned long incnt; /* bytes read so far */
int bitbuf; /* bit buffer */
@@ -123,7 +130,8 @@ local int bits(struct state *s, int need)
/* load at least need bits into val */
val = s->bitbuf;
while (s->bitcnt < need) {
- if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */
+ if (s->incnt == s->inlen)
+ longjmp(s->env, 1); /* out of input */
val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */
s->bitcnt += 8;
}
@@ -162,7 +170,8 @@ local int stored(struct state *s)
s->bitcnt = 0;
/* get length and check against its one's complement */
- if (s->incnt + 4 > s->inlen) return 2; /* not enough input */
+ if (s->incnt + 4 > s->inlen)
+ return 2; /* not enough input */
len = s->in[s->incnt++];
len |= s->in[s->incnt++] << 8;
if (s->in[s->incnt++] != (~len & 0xff) ||
@@ -170,7 +179,8 @@ local int stored(struct state *s)
return -2; /* didn't match complement! */
/* copy len bytes from in to out */
- if (s->incnt + len > s->inlen) return 2; /* not enough input */
+ if (s->incnt + len > s->inlen)
+ return 2; /* not enough input */
if (s->out != NIL) {
if (s->outcnt + len > s->outlen)
return 1; /* not enough output space */
@@ -222,7 +232,7 @@ struct huffman {
* in the deflate format. See the format notes for fixed() and dynamic().
*/
#ifdef SLOW
-local int decode(struct state *s, struct huffman *h)
+local int decode(struct state *s, const struct huffman *h)
{
int len; /* current number of bits in code */
int code; /* len bits being decoded */
@@ -250,7 +260,7 @@ local int decode(struct state *s, struct huffman *h)
* a few percent larger.
*/
#else /* !SLOW */
-local int decode(struct state *s, struct huffman *h)
+local int decode(struct state *s, const struct huffman *h)
{
int len; /* current number of bits in code */
int code; /* len bits being decoded */
@@ -283,10 +293,13 @@ local int decode(struct state *s, struct huffman *h)
len++;
}
left = (MAXBITS+1) - len;
- if (left == 0) break;
- if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */
+ if (left == 0)
+ break;
+ if (s->incnt == s->inlen)
+ longjmp(s->env, 1); /* out of input */
bitbuf = s->in[s->incnt++];
- if (left > 8) left = 8;
+ if (left > 8)
+ left = 8;
}
return -10; /* ran out of codes */
}
@@ -324,7 +337,7 @@ local int decode(struct state *s, struct huffman *h)
* - Within a given code length, the symbols are kept in ascending order for
* the code bits definition.
*/
-local int construct(struct huffman *h, short *length, int n)
+local int construct(struct huffman *h, const short *length, int n)
{
int symbol; /* current symbol when stepping through length[] */
int len; /* current length when stepping through h->count[] */
@@ -344,7 +357,8 @@ local int construct(struct huffman *h, short *length, int n)
for (len = 1; len <= MAXBITS; len++) {
left <<= 1; /* one more bit, double codes left */
left -= h->count[len]; /* deduct count from possible codes */
- if (left < 0) return left; /* over-subscribed--return negative */
+ if (left < 0)
+ return left; /* over-subscribed--return negative */
} /* left > 0 means incomplete */
/* generate offsets into symbol table for each length for sorting */
@@ -420,8 +434,8 @@ local int construct(struct huffman *h, short *length, int n)
* defined to do the wrong thing in this case.
*/
local int codes(struct state *s,
- struct huffman *lencode,
- struct huffman *distcode)
+ const struct huffman *lencode,
+ const struct huffman *distcode)
{
int symbol; /* decoded symbol */
int len; /* length for copy */
@@ -444,11 +458,13 @@ local int codes(struct state *s,
/* decode literals and length/distance pairs */
do {
symbol = decode(s, lencode);
- if (symbol < 0) return symbol; /* invalid symbol */
+ if (symbol < 0)
+ return symbol; /* invalid symbol */
if (symbol < 256) { /* literal: symbol is the byte */
/* write out the literal */
if (s->out != NIL) {
- if (s->outcnt == s->outlen) return 1;
+ if (s->outcnt == s->outlen)
+ return 1;
s->out[s->outcnt] = symbol;
}
s->outcnt++;
@@ -456,12 +472,14 @@ local int codes(struct state *s,
else if (symbol > 256) { /* length */
/* get and compute length */
symbol -= 257;
- if (symbol >= 29) return -10; /* invalid fixed code */
+ if (symbol >= 29)
+ return -10; /* invalid fixed code */
len = lens[symbol] + bits(s, lext[symbol]);
/* get and check distance */
symbol = decode(s, distcode);
- if (symbol < 0) return symbol; /* invalid symbol */
+ if (symbol < 0)
+ return symbol; /* invalid symbol */
dist = dists[symbol] + bits(s, dext[symbol]);
#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
if (dist > s->outcnt)
@@ -470,13 +488,15 @@ local int codes(struct state *s,
/* copy length bytes from distance bytes back */
if (s->out != NIL) {
- if (s->outcnt + len > s->outlen) return 1;
+ if (s->outcnt + len > s->outlen)
+ return 1;
while (len--) {
s->out[s->outcnt] =
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
- dist > s->outcnt ? 0 :
+ dist > s->outcnt ?
+ 0 :
#endif
- s->out[s->outcnt - dist];
+ s->out[s->outcnt - dist];
s->outcnt++;
}
}
@@ -525,6 +545,12 @@ local int fixed(struct state *s)
int symbol;
short lengths[FIXLCODES];
+ /* construct lencode and distcode */
+ lencode.count = lencnt;
+ lencode.symbol = lensym;
+ distcode.count = distcnt;
+ distcode.symbol = distsym;
+
/* literal/length table */
for (symbol = 0; symbol < 144; symbol++)
lengths[symbol] = 8;
@@ -541,12 +567,6 @@ local int fixed(struct state *s)
lengths[symbol] = 5;
construct(&distcode, lengths, MAXDCODES);
- /* construct lencode and distcode */
- lencode.count = lencnt;
- lencode.symbol = lensym;
- distcode.count = distcnt;
- distcode.symbol = distsym;
-
/* do this just once */
virgin = 0;
}
@@ -675,7 +695,8 @@ local int dynamic(struct state *s)
/* build huffman table for code lengths codes (use lencode temporarily) */
err = construct(&lencode, lengths, 19);
- if (err != 0) return -4; /* require complete code set here */
+ if (err != 0) /* require complete code set here */
+ return -4;
/* read length/literal and distance code length tables */
index = 0;
@@ -684,12 +705,15 @@ local int dynamic(struct state *s)
int len; /* last length to repeat */
symbol = decode(s, &lencode);
+ if (symbol < 0)
+ return symbol; /* invalid symbol */
if (symbol < 16) /* length in 0..15 */
lengths[index++] = symbol;
else { /* repeat instruction */
len = 0; /* assume repeating zeros */
if (symbol == 16) { /* repeat last length 3..6 times */
- if (index == 0) return -5; /* no last length! */
+ if (index == 0)
+ return -5; /* no last length! */
len = lengths[index - 1]; /* last length */
symbol = 3 + bits(s, 2);
}
@@ -710,13 +734,13 @@ local int dynamic(struct state *s)
/* build huffman table for literal/length codes */
err = construct(&lencode, lengths, nlen);
- if (err < 0 || (err > 0 && nlen - lencode.count[0] != 1))
- return -7; /* only allow incomplete codes if just one code */
+ if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1]))
+ return -7; /* incomplete code ok only for single length 1 code */
/* build huffman table for distance codes */
err = construct(&distcode, lengths + nlen, ndist);
- if (err < 0 || (err > 0 && ndist - distcode.count[0] != 1))
- return -8; /* only allow incomplete codes if just one code */
+ if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1]))
+ return -8; /* incomplete code ok only for single length 1 code */
/* decode data until end-of-block code */
return codes(s, &lencode, &distcode);
@@ -768,7 +792,7 @@ local int dynamic(struct state *s)
*/
int puff(unsigned char *dest, /* pointer to destination pointer */
unsigned long *destlen, /* amount of output space */
- unsigned char *source, /* pointer to source data pointer */
+ const unsigned char *source, /* pointer to source data pointer */
unsigned long *sourcelen) /* amount of input available */
{
struct state s; /* input/output state */
@@ -795,11 +819,15 @@ int puff(unsigned char *dest, /* pointer to destination pointer */
do {
last = bits(&s, 1); /* one if last block */
type = bits(&s, 2); /* block type 0..3 */
- err = type == 0 ? stored(&s) :
- (type == 1 ? fixed(&s) :
- (type == 2 ? dynamic(&s) :
- -1)); /* type == 3, invalid */
- if (err != 0) break; /* return with error */
+ err = type == 0 ?
+ stored(&s) :
+ (type == 1 ?
+ fixed(&s) :
+ (type == 2 ?
+ dynamic(&s) :
+ -1)); /* type == 3, invalid */
+ if (err != 0)
+ break; /* return with error */
} while (!last);
}
@@ -810,146 +838,3 @@ int puff(unsigned char *dest, /* pointer to destination pointer */
}
return err;
}
-
-#ifdef TEST
-/* Examples of how to use puff().
-
- Usage: puff [-w] [-nnn] file
- ... | puff [-w] [-nnn]
-
- where file is the input file with deflate data, nnn is the number of bytes
- of input to skip before inflating (e.g. to skip a zlib or gzip header), and
- -w is used to write the decompressed data to stdout */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-/* Return size times approximately the cube root of 2, keeping the result as 1,
- 3, or 5 times a power of 2 -- the result is always > size, until the result
- is the maximum value of an unsigned long, where it remains. This is useful
- to keep reallocations less than ~33% over the actual data. */
-local size_t bythirds(size_t size)
-{
- int n;
- size_t m;
-
- m = size;
- for (n = 0; m; n++)
- m >>= 1;
- if (n < 3)
- return size + 1;
- n -= 3;
- m = size >> n;
- m += m == 6 ? 2 : 1;
- m <<= n;
- return m > size ? m : (size_t)(-1);
-}
-
-/* Read the input file *name, or stdin if name is NULL, into allocated memory.
- Reallocate to larger buffers until the entire file is read in. Return a
- pointer to the allocated data, or NULL if there was a memory allocation
- failure. *len is the number of bytes of data read from the input file (even
- if load() returns NULL). If the input file was empty or could not be opened
- or read, *len is zero. */
-local void *load(char *name, size_t *len)
-{
- size_t size;
- void *buf, *swap;
- FILE *in;
-
- *len = 0;
- buf = malloc(size = 4096);
- if (buf == NULL)
- return NULL;
- in = name == NULL ? stdin : fopen(name, "rb");
- if (in != NULL) {
- for (;;) {
- *len += fread((char *)buf + *len, 1, size - *len, in);
- if (*len < size) break;
- size = bythirds(size);
- if (size == *len || (swap = realloc(buf, size)) == NULL) {
- free(buf);
- buf = NULL;
- break;
- }
- buf = swap;
- }
- fclose(in);
- }
- return buf;
-}
-
-int main(int argc, char **argv)
-{
- int ret, put = 0;
- unsigned skip = 0;
- char *arg, *name = NULL;
- unsigned char *source = NULL, *dest;
- size_t len = 0;
- unsigned long sourcelen, destlen;
-
- /* process arguments */
- while (arg = *++argv, --argc)
- if (arg[0] == '-') {
- if (arg[1] == 'w' && arg[2] == 0)
- put = 1;
- else if (arg[1] >= '0' && arg[1] <= '9')
- skip = (unsigned)atoi(arg + 1);
- else {
- fprintf(stderr, "invalid option %s\n", arg);
- return 3;
- }
- }
- else if (name != NULL) {
- fprintf(stderr, "only one file name allowed\n");
- return 3;
- }
- else
- name = arg;
- source = load(name, &len);
- if (source == NULL) {
- fprintf(stderr, "memory allocation failure\n");
- return 4;
- }
- if (len == 0) {
- fprintf(stderr, "could not read %s, or it was empty\n",
- name == NULL ? "<stdin>" : name);
- free(source);
- return 3;
- }
- if (skip >= len) {
- fprintf(stderr, "skip request of %d leaves no input\n", skip);
- free(source);
- return 3;
- }
-
- /* test inflate data with offset skip */
- len -= skip;
- sourcelen = (unsigned long)len;
- ret = puff(NIL, &destlen, source + skip, &sourcelen);
- if (ret)
- fprintf(stderr, "puff() failed with return code %d\n", ret);
- else {
- fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen);
- if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n",
- len - sourcelen);
- }
-
- /* if requested, inflate again and write decompressd data to stdout */
- if (put) {
- dest = malloc(destlen);
- if (dest == NULL) {
- fprintf(stderr, "memory allocation failure\n");
- free(source);
- return 4;
- }
- puff(dest, &destlen, source + skip, &sourcelen);
- fwrite(dest, 1, destlen, stdout);
- free(dest);
- }
-
- /* clean up */
- free(source);
- return ret;
-}
-#endif
diff --git a/compat/zlib/contrib/puff/puff.h b/compat/zlib/contrib/puff/puff.h
index 88d1b38..e23a245 100644
--- a/compat/zlib/contrib/puff/puff.h
+++ b/compat/zlib/contrib/puff/puff.h
@@ -1,6 +1,6 @@
/* puff.h
- Copyright (C) 2002-2010 Mark Adler, all rights reserved
- version 2.1, 4 Apr 2010
+ Copyright (C) 2002-2013 Mark Adler, all rights reserved
+ version 2.3, 21 Jan 2013
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
@@ -25,7 +25,11 @@
/*
* See puff.c for purpose and usage.
*/
+#ifndef NIL
+# define NIL ((unsigned char *)0) /* for no output option */
+#endif
+
int puff(unsigned char *dest, /* pointer to destination pointer */
unsigned long *destlen, /* amount of output space */
- unsigned char *source, /* pointer to source data pointer */
+ const unsigned char *source, /* pointer to source data pointer */
unsigned long *sourcelen); /* amount of input available */
diff --git a/compat/zlib/contrib/puff/pufftest.c b/compat/zlib/contrib/puff/pufftest.c
new file mode 100644
index 0000000..7764814
--- /dev/null
+++ b/compat/zlib/contrib/puff/pufftest.c
@@ -0,0 +1,165 @@
+/*
+ * pufftest.c
+ * Copyright (C) 2002-2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in puff.h
+ * version 2.3, 21 Jan 2013
+ */
+
+/* Example of how to use puff().
+
+ Usage: puff [-w] [-f] [-nnn] file
+ ... | puff [-w] [-f] [-nnn]
+
+ where file is the input file with deflate data, nnn is the number of bytes
+ of input to skip before inflating (e.g. to skip a zlib or gzip header), and
+ -w is used to write the decompressed data to stdout. -f is for coverage
+ testing, and causes pufftest to fail with not enough output space (-f does
+ a write like -w, so -w is not required). */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "puff.h"
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+# include <fcntl.h>
+# include <io.h>
+# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+# define SET_BINARY_MODE(file)
+#endif
+
+#define local static
+
+/* Return size times approximately the cube root of 2, keeping the result as 1,
+ 3, or 5 times a power of 2 -- the result is always > size, until the result
+ is the maximum value of an unsigned long, where it remains. This is useful
+ to keep reallocations less than ~33% over the actual data. */
+local size_t bythirds(size_t size)
+{
+ int n;
+ size_t m;
+
+ m = size;
+ for (n = 0; m; n++)
+ m >>= 1;
+ if (n < 3)
+ return size + 1;
+ n -= 3;
+ m = size >> n;
+ m += m == 6 ? 2 : 1;
+ m <<= n;
+ return m > size ? m : (size_t)(-1);
+}
+
+/* Read the input file *name, or stdin if name is NULL, into allocated memory.
+ Reallocate to larger buffers until the entire file is read in. Return a
+ pointer to the allocated data, or NULL if there was a memory allocation
+ failure. *len is the number of bytes of data read from the input file (even
+ if load() returns NULL). If the input file was empty or could not be opened
+ or read, *len is zero. */
+local void *load(const char *name, size_t *len)
+{
+ size_t size;
+ void *buf, *swap;
+ FILE *in;
+
+ *len = 0;
+ buf = malloc(size = 4096);
+ if (buf == NULL)
+ return NULL;
+ in = name == NULL ? stdin : fopen(name, "rb");
+ if (in != NULL) {
+ for (;;) {
+ *len += fread((char *)buf + *len, 1, size - *len, in);
+ if (*len < size) break;
+ size = bythirds(size);
+ if (size == *len || (swap = realloc(buf, size)) == NULL) {
+ free(buf);
+ buf = NULL;
+ break;
+ }
+ buf = swap;
+ }
+ fclose(in);
+ }
+ return buf;
+}
+
+int main(int argc, char **argv)
+{
+ int ret, put = 0, fail = 0;
+ unsigned skip = 0;
+ char *arg, *name = NULL;
+ unsigned char *source = NULL, *dest;
+ size_t len = 0;
+ unsigned long sourcelen, destlen;
+
+ /* process arguments */
+ while (arg = *++argv, --argc)
+ if (arg[0] == '-') {
+ if (arg[1] == 'w' && arg[2] == 0)
+ put = 1;
+ else if (arg[1] == 'f' && arg[2] == 0)
+ fail = 1, put = 1;
+ else if (arg[1] >= '0' && arg[1] <= '9')
+ skip = (unsigned)atoi(arg + 1);
+ else {
+ fprintf(stderr, "invalid option %s\n", arg);
+ return 3;
+ }
+ }
+ else if (name != NULL) {
+ fprintf(stderr, "only one file name allowed\n");
+ return 3;
+ }
+ else
+ name = arg;
+ source = load(name, &len);
+ if (source == NULL) {
+ fprintf(stderr, "memory allocation failure\n");
+ return 4;
+ }
+ if (len == 0) {
+ fprintf(stderr, "could not read %s, or it was empty\n",
+ name == NULL ? "<stdin>" : name);
+ free(source);
+ return 3;
+ }
+ if (skip >= len) {
+ fprintf(stderr, "skip request of %d leaves no input\n", skip);
+ free(source);
+ return 3;
+ }
+
+ /* test inflate data with offset skip */
+ len -= skip;
+ sourcelen = (unsigned long)len;
+ ret = puff(NIL, &destlen, source + skip, &sourcelen);
+ if (ret)
+ fprintf(stderr, "puff() failed with return code %d\n", ret);
+ else {
+ fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen);
+ if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n",
+ len - sourcelen);
+ }
+
+ /* if requested, inflate again and write decompressd data to stdout */
+ if (put && ret == 0) {
+ if (fail)
+ destlen >>= 1;
+ dest = malloc(destlen);
+ if (dest == NULL) {
+ fprintf(stderr, "memory allocation failure\n");
+ free(source);
+ return 4;
+ }
+ puff(dest, &destlen, source + skip, &sourcelen);
+ SET_BINARY_MODE(stdout);
+ fwrite(dest, 1, destlen, stdout);
+ free(dest);
+ }
+
+ /* clean up */
+ free(source);
+ return ret;
+}
diff --git a/compat/zlib/contrib/puff/zeros.raw b/compat/zlib/contrib/puff/zeros.raw
index 637b7be..0a90e76 100644
--- a/compat/zlib/contrib/puff/zeros.raw
+++ b/compat/zlib/contrib/puff/zeros.raw
Binary files differ
diff --git a/compat/zlib/contrib/testzlib/testzlib.c b/compat/zlib/contrib/testzlib/testzlib.c
index 135888e..5f659de 100644
--- a/compat/zlib/contrib/testzlib/testzlib.c
+++ b/compat/zlib/contrib/testzlib/testzlib.c
@@ -116,10 +116,10 @@ DWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPe
return dwRet;
}
-int ReadFileMemory(const char* filename,long* plFileSize,void** pFilePtr)
+int ReadFileMemory(const char* filename,long* plFileSize,unsigned char** pFilePtr)
{
FILE* stream;
- void* ptr;
+ unsigned char* ptr;
int retVal=1;
stream=fopen(filename, "rb");
if (stream==NULL)
diff --git a/compat/zlib/contrib/vstudio/readme.txt b/compat/zlib/contrib/vstudio/readme.txt
index 904888b..bfdcd9d 100644
--- a/compat/zlib/contrib/vstudio/readme.txt
+++ b/compat/zlib/contrib/vstudio/readme.txt
@@ -1,8 +1,8 @@
-Building instructions for the DLL versions of Zlib 1.2.4
+Building instructions for the DLL versions of Zlib 1.2.8
========================================================
This directory contains projects that build zlib and minizip using
-Microsoft Visual C++ 9.0/10.0, and Visual C++ .
+Microsoft Visual C++ 9.0/10.0.
You don't need to build these projects yourself. You can download the
binaries from:
@@ -10,9 +10,6 @@ binaries from:
More information can be found at this site.
-first compile assembly code by running
-bld_ml64.bat in contrib\masmx64
-bld_ml32.bat in contrib\masmx86
@@ -20,13 +17,21 @@ bld_ml32.bat in contrib\masmx86
Build instructions for Visual Studio 2008 (32 bits or 64 bits)
--------------------------------------------------------------
- Uncompress current zlib, including all contrib/* files
-- Open contrib\vstudio\vc9\zlibvc.sln with Microsoft Visual C++ 2008.0
+- Compile assembly code (with Visual Studio Command Prompt) by running:
+ bld_ml64.bat (in contrib\masmx64)
+ bld_ml32.bat (in contrib\masmx86)
+- Open contrib\vstudio\vc9\zlibvc.sln with Microsoft Visual C++ 2008
- Or run: vcbuild /rebuild contrib\vstudio\vc9\zlibvc.sln "Release|Win32"
Build instructions for Visual Studio 2010 (32 bits or 64 bits)
--------------------------------------------------------------
- Uncompress current zlib, including all contrib/* files
-- Open contrib\vstudio\vc10\zlibvc.sln with Microsoft Visual C++ 2010.0
+- Open contrib\vstudio\vc10\zlibvc.sln with Microsoft Visual C++ 2010
+
+Build instructions for Visual Studio 2012 (32 bits or 64 bits)
+--------------------------------------------------------------
+- Uncompress current zlib, including all contrib/* files
+- Open contrib\vstudio\vc11\zlibvc.sln with Microsoft Visual C++ 2012
Important
diff --git a/compat/zlib/contrib/vstudio/vc10/miniunz.vcxproj.user b/compat/zlib/contrib/vstudio/vc10/miniunz.vcxproj.user
deleted file mode 100644
index 695b5c7..0000000
--- a/compat/zlib/contrib/vstudio/vc10/miniunz.vcxproj.user
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-</Project> \ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/minizip.vcxproj.user b/compat/zlib/contrib/vstudio/vc10/minizip.vcxproj.user
deleted file mode 100644
index 695b5c7..0000000
--- a/compat/zlib/contrib/vstudio/vc10/minizip.vcxproj.user
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-</Project> \ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/testzlib.vcxproj.user b/compat/zlib/contrib/vstudio/vc10/testzlib.vcxproj.user
deleted file mode 100644
index 695b5c7..0000000
--- a/compat/zlib/contrib/vstudio/vc10/testzlib.vcxproj.user
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-</Project> \ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj b/compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj
index 2d62815..bcb08ff 100644
--- a/compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj
+++ b/compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj
@@ -139,7 +139,7 @@
</ClCompile>
<Link>
<AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
@@ -169,7 +169,7 @@
</ClCompile>
<Link>
<AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
@@ -200,7 +200,7 @@
</ClCompile>
<Link>
<AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
@@ -227,7 +227,7 @@
</ClCompile>
<Link>
<AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
@@ -257,7 +257,7 @@
</ClCompile>
<Link>
<AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
@@ -288,7 +288,7 @@
</ClCompile>
<Link>
<AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
diff --git a/compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.user b/compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.user
deleted file mode 100644
index 695b5c7..0000000
--- a/compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.user
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-</Project> \ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/zlib.rc b/compat/zlib/contrib/vstudio/vc10/zlib.rc
index f822450..73f6476 100644
--- a/compat/zlib/contrib/vstudio/vc10/zlib.rc
+++ b/compat/zlib/contrib/vstudio/vc10/zlib.rc
@@ -2,8 +2,8 @@
#define IDR_VERSION1 1
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
- FILEVERSION 1,2,5,0
- PRODUCTVERSION 1,2,5,0
+ FILEVERSION 1,2,8,0
+ PRODUCTVERSION 1,2,8,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS32
@@ -17,12 +17,12 @@ BEGIN
BEGIN
VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
- VALUE "FileVersion", "1.2.5\0"
+ VALUE "FileVersion", "1.2.8\0"
VALUE "InternalName", "zlib\0"
- VALUE "OriginalFilename", "zlib.dll\0"
+ VALUE "OriginalFilename", "zlibwapi.dll\0"
VALUE "ProductName", "ZLib.DLL\0"
VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
- VALUE "LegalCopyright", "(C) 1995-2010 Jean-loup Gailly & Mark Adler\0"
+ VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0"
END
END
BLOCK "VarFileInfo"
diff --git a/compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj b/compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj
index 2682fca..b9f2bbe 100644
--- a/compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj
+++ b/compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj
@@ -182,6 +182,10 @@
<OutputFile>$(OutDir)zlibstat.lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
@@ -210,6 +214,10 @@
<OutputFile>$(OutDir)zlibstat.lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
<ClCompile>
@@ -266,6 +274,10 @@
<OutputFile>$(OutDir)zlibstat.lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
<Midl>
@@ -326,6 +338,10 @@
<OutputFile>$(OutDir)zlibstat.lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
<Midl>
diff --git a/compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.user b/compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.user
deleted file mode 100644
index 695b5c7..0000000
--- a/compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.user
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-</Project> \ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/zlibvc.def b/compat/zlib/contrib/vstudio/vc10/zlibvc.def
index 0269ef7..6367046 100644
--- a/compat/zlib/contrib/vstudio/vc10/zlibvc.def
+++ b/compat/zlib/contrib/vstudio/vc10/zlibvc.def
@@ -1,7 +1,7 @@
LIBRARY
; zlib data compression and ZIP file I/O library
-VERSION 1.24
+VERSION 1.2.8
EXPORTS
adler32 @1
@@ -55,6 +55,7 @@ EXPORTS
gzungetc @49
zlibCompileFlags @50
deflatePrime @51
+ deflatePending @52
unzOpen @61
unzClose @62
@@ -128,3 +129,15 @@ EXPORTS
inflatePrime @158
inflateReset2 @159
inflateUndermine @160
+
+; zlib1 v1.2.6 added:
+ gzgetc_ @161
+ inflateResetKeep @163
+ deflateResetKeep @164
+
+; zlib1 v1.2.7 added:
+ gzopen_w @165
+
+; zlib1 v1.2.8 added:
+ inflateGetDictionary @166
+ gzvprintf @167
diff --git a/compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj b/compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj
index 9862398..6ff9ddb 100644
--- a/compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj
+++ b/compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj
@@ -180,6 +180,12 @@
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">zlibwapid</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">zlibwapid</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">zlibwapi</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
@@ -214,19 +220,19 @@
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
- <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
- <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
- <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
</Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
<Midl>
@@ -262,18 +268,14 @@
</ResourceCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
- <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
- <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
- <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
- <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -311,19 +313,19 @@
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
- <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
- <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
- <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
- <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
</Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
@@ -357,17 +359,17 @@
</ResourceCompile>
<Link>
<AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
- <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
- <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
<SubSystem>Windows</SubSystem>
- <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
</Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
<Midl>
@@ -445,15 +447,11 @@
<Culture>0x040c</Culture>
</ResourceCompile>
<Link>
- <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
- <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
- <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
<SubSystem>Windows</SubSystem>
- <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
@@ -536,17 +534,17 @@
</ResourceCompile>
<Link>
<AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
- <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
- <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
- <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
<SubSystem>Windows</SubSystem>
- <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
</Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
<Midl>
diff --git a/compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.user b/compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.user
deleted file mode 100644
index 695b5c7..0000000
--- a/compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.user
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-</Project> \ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc11/miniunz.vcxproj b/compat/zlib/contrib/vstudio/vc11/miniunz.vcxproj
new file mode 100644
index 0000000..8f9f20b
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/miniunz.vcxproj
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694382A}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\minizip\miniunz.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc11/minizip.vcxproj b/compat/zlib/contrib/vstudio/vc11/minizip.vcxproj
new file mode 100644
index 0000000..c93d9e6
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/minizip.vcxproj
@@ -0,0 +1,311 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\minizip\minizip.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc11/testzlib.vcxproj b/compat/zlib/contrib/vstudio/vc11/testzlib.vcxproj
new file mode 100644
index 0000000..6d55954
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/testzlib.vcxproj
@@ -0,0 +1,426 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>
+ <RootNamespace>testzlib</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\testzlib\testzlib.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj b/compat/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj
new file mode 100644
index 0000000..9f20c78
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694366A}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\testzlib\testzlib.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc7/zlib.rc b/compat/zlib/contrib/vstudio/vc11/zlib.rc
index 72cb8b4..73f6476 100644
--- a/compat/zlib/contrib/vstudio/vc7/zlib.rc
+++ b/compat/zlib/contrib/vstudio/vc11/zlib.rc
@@ -2,8 +2,8 @@
#define IDR_VERSION1 1
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
- FILEVERSION 1,2,3,0
- PRODUCTVERSION 1,2,3,0
+ FILEVERSION 1,2,8,0
+ PRODUCTVERSION 1,2,8,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS32
@@ -16,13 +16,13 @@ BEGIN
//language ID = U.S. English, char set = Windows, Multilingual
BEGIN
- VALUE "FileDescription", "zlib data compression library\0"
- VALUE "FileVersion", "1.2.3.0\0"
+ VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
+ VALUE "FileVersion", "1.2.8\0"
VALUE "InternalName", "zlib\0"
- VALUE "OriginalFilename", "zlib.dll\0"
+ VALUE "OriginalFilename", "zlibwapi.dll\0"
VALUE "ProductName", "ZLib.DLL\0"
VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
- VALUE "LegalCopyright", "(C) 1995-2003 Jean-loup Gailly & Mark Adler\0"
+ VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0"
END
END
BLOCK "VarFileInfo"
diff --git a/compat/zlib/contrib/vstudio/vc11/zlibstat.vcxproj b/compat/zlib/contrib/vstudio/vc11/zlibstat.vcxproj
new file mode 100644
index 0000000..806b76a
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/zlibstat.vcxproj
@@ -0,0 +1,464 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\gzclose.c" />
+ <ClCompile Include="..\..\..\gzlib.c" />
+ <ClCompile Include="..\..\..\gzread.c" />
+ <ClCompile Include="..\..\..\gzwrite.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\minizip\ioapi.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\minizip\unzip.c" />
+ <ClCompile Include="..\..\minizip\zip.c" />
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="zlib.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="zlibvc.def" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc7/zlibvc.def b/compat/zlib/contrib/vstudio/vc11/zlibvc.def
index a40e715..6367046 100644
--- a/compat/zlib/contrib/vstudio/vc7/zlibvc.def
+++ b/compat/zlib/contrib/vstudio/vc11/zlibvc.def
@@ -1,7 +1,7 @@
+LIBRARY
+; zlib data compression and ZIP file I/O library
-VERSION 1.23
-
-HEAPSIZE 1048576,8192
+VERSION 1.2.8
EXPORTS
adler32 @1
@@ -55,6 +55,7 @@ EXPORTS
gzungetc @49
zlibCompileFlags @50
deflatePrime @51
+ deflatePending @52
unzOpen @61
unzClose @62
@@ -90,3 +91,53 @@ EXPORTS
unzGoToFilePos @101
fill_win32_filefunc @110
+
+; zlibwapi v1.2.4 added:
+ fill_win32_filefunc64 @111
+ fill_win32_filefunc64A @112
+ fill_win32_filefunc64W @113
+
+ unzOpen64 @120
+ unzOpen2_64 @121
+ unzGetGlobalInfo64 @122
+ unzGetCurrentFileInfo64 @124
+ unzGetCurrentFileZStreamPos64 @125
+ unztell64 @126
+ unzGetFilePos64 @127
+ unzGoToFilePos64 @128
+
+ zipOpen64 @130
+ zipOpen2_64 @131
+ zipOpenNewFileInZip64 @132
+ zipOpenNewFileInZip2_64 @133
+ zipOpenNewFileInZip3_64 @134
+ zipOpenNewFileInZip4_64 @135
+ zipCloseFileInZipRaw64 @136
+
+; zlib1 v1.2.4 added:
+ adler32_combine @140
+ crc32_combine @142
+ deflateSetHeader @144
+ deflateTune @145
+ gzbuffer @146
+ gzclose_r @147
+ gzclose_w @148
+ gzdirect @149
+ gzoffset @150
+ inflateGetHeader @156
+ inflateMark @157
+ inflatePrime @158
+ inflateReset2 @159
+ inflateUndermine @160
+
+; zlib1 v1.2.6 added:
+ gzgetc_ @161
+ inflateResetKeep @163
+ deflateResetKeep @164
+
+; zlib1 v1.2.7 added:
+ gzopen_w @165
+
+; zlib1 v1.2.8 added:
+ inflateGetDictionary @166
+ gzvprintf @167
diff --git a/compat/zlib/contrib/vstudio/vc8/zlibvc.sln b/compat/zlib/contrib/vstudio/vc11/zlibvc.sln
index a815a55..9fcbafd 100644
--- a/compat/zlib/contrib/vstudio/vc8/zlibvc.sln
+++ b/compat/zlib/contrib/vstudio/vc11/zlibvc.sln
@@ -1,26 +1,17 @@

-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestZlibDll", "testzlibdll.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}"
- ProjectSection(ProjectDependencies) = postProject
- {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}
- EndProjectSection
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
- ProjectSection(ProjectDependencies) = postProject
- {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}
- EndProjectSection
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
- ProjectSection(ProjectDependencies) = postProject
- {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}
- EndProjectSection
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -35,108 +26,90 @@ Global
ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Win32
{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32
{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32
{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64
{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Win32
{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32
{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = ReleaseWithoutAsm|x64
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = ReleaseWithoutAsm|x64
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Win32
{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32
{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32
{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64
{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Win32
{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32
{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32
{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64
{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
- {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium
- {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Win32
{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32
{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32
{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64
{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64
- {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium
- {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Win32
{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32
{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32
{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64
{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64
- {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
- {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
- {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Itanium
- {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|Itanium
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32
{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32
{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Itanium
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|Itanium
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Win32
{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32
{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32
{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64
{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Win32
{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32
{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32
{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64
{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Itanium
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/compat/zlib/contrib/vstudio/vc11/zlibvc.vcxproj b/compat/zlib/contrib/vstudio/vc11/zlibvc.vcxproj
new file mode 100644
index 0000000..c65b95f
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/zlibvc.vcxproj
@@ -0,0 +1,688 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{8FD826F8-3739-44E6-8CC8-997122E53B8D}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">zlibwapi</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\contrib\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\gzclose.c" />
+ <ClCompile Include="..\..\..\gzlib.c" />
+ <ClCompile Include="..\..\..\gzread.c" />
+ <ClCompile Include="..\..\..\gzwrite.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\minizip\ioapi.c" />
+ <ClCompile Include="..\..\minizip\iowin32.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\minizip\unzip.c">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="..\..\minizip\zip.c">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="zlib.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="zlibvc.def" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\deflate.h" />
+ <ClInclude Include="..\..\..\infblock.h" />
+ <ClInclude Include="..\..\..\infcodes.h" />
+ <ClInclude Include="..\..\..\inffast.h" />
+ <ClInclude Include="..\..\..\inftrees.h" />
+ <ClInclude Include="..\..\..\infutil.h" />
+ <ClInclude Include="..\..\..\zconf.h" />
+ <ClInclude Include="..\..\..\zlib.h" />
+ <ClInclude Include="..\..\..\zutil.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc7/miniunz.vcproj b/compat/zlib/contrib/vstudio/vc7/miniunz.vcproj
deleted file mode 100644
index ad5117c..0000000
--- a/compat/zlib/contrib/vstudio/vc7/miniunz.vcproj
+++ /dev/null
@@ -1,126 +0,0 @@
-<?xml version="1.0" encoding = "Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.00"
- Name="miniunz"
- ProjectGUID="{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="5"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="4"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/miniunz.exe"
- LinkIncremental="2"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/miniunz.pdb"
- SubSystem="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="TRUE"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE"
- StringPooling="TRUE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/miniunz.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- </Configurations>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
- <File
- RelativePath="..\..\minizip\miniunz.c">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc">
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
- </Filter>
- <File
- RelativePath="ReleaseDll\zlibwapi.lib">
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc7/minizip.vcproj b/compat/zlib/contrib/vstudio/vc7/minizip.vcproj
deleted file mode 100644
index fb5b632..0000000
--- a/compat/zlib/contrib/vstudio/vc7/minizip.vcproj
+++ /dev/null
@@ -1,126 +0,0 @@
-<?xml version="1.0" encoding = "Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.00"
- Name="minizip"
- ProjectGUID="{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="5"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="4"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/minizip.exe"
- LinkIncremental="2"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/minizip.pdb"
- SubSystem="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="TRUE"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE"
- StringPooling="TRUE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/minizip.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- </Configurations>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
- <File
- RelativePath="..\..\minizip\minizip.c">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc">
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
- </Filter>
- <File
- RelativePath="ReleaseDll\zlibwapi.lib">
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc7/testzlib.vcproj b/compat/zlib/contrib/vstudio/vc7/testzlib.vcproj
deleted file mode 100644
index 97bc3e8..0000000
--- a/compat/zlib/contrib/vstudio/vc7/testzlib.vcproj
+++ /dev/null
@@ -1,126 +0,0 @@
-<?xml version="1.0" encoding = "Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.00"
- Name="testZlibDll"
- ProjectGUID="{AA6666AA-E09F-4135-9C0C-4FE50C3C654C}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\.."
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="5"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="4"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="2"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
- SubSystem="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="TRUE"
- AdditionalIncludeDirectories="..\..\.."
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE"
- StringPooling="TRUE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- </Configurations>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
- <File
- RelativePath="..\..\testzlib\testzlib.c">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc">
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
- </Filter>
- <File
- RelativePath="ReleaseDll\zlibwapi.lib">
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc7/zlibstat.vcproj b/compat/zlib/contrib/vstudio/vc7/zlibstat.vcproj
deleted file mode 100644
index 766d7a4..0000000
--- a/compat/zlib/contrib/vstudio/vc7/zlibstat.vcproj
+++ /dev/null
@@ -1,246 +0,0 @@
-<?xml version="1.0" encoding = "Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.00"
- Name="zlibstat"
- SccProjectName=""
- SccLocalPath="">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory=".\zlibstatDebug"
- IntermediateDirectory=".\zlibstatDebug"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI"
- ExceptionHandling="FALSE"
- RuntimeLibrary="5"
- PrecompiledHeaderFile=".\zlibstatDebug/zlibstat.pch"
- AssemblerListingLocation=".\zlibstatDebug/"
- ObjectFile=".\zlibstatDebug/"
- ProgramDataBaseFileName=".\zlibstatDebug/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="1"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="/NODEFAULTLIB "
- OutputFile=".\zlibstatDebug\zlibstat.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="ReleaseAxp|Win32"
- OutputDirectory=".\zlibsta0"
- IntermediateDirectory=".\zlibsta0"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- PrecompiledHeaderFile=".\zlibsta0/zlibstat.pch"
- AssemblerListingLocation=".\zlibsta0/"
- ObjectFile=".\zlibsta0/"
- ProgramDataBaseFileName=".\zlibsta0/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="/NODEFAULTLIB "
- OutputFile=".\zlibsta0\zlibstat.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory=".\zlibstat"
- IntermediateDirectory=".\zlibstat"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;ASMV;ASMINF"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- PrecompiledHeaderFile=".\zlibstat/zlibstat.pch"
- AssemblerListingLocation=".\zlibstat/"
- ObjectFile=".\zlibstat/"
- ProgramDataBaseFileName=".\zlibstat/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="..\..\masmx86\gvmat32.obj ..\..\masmx86\inffas32.obj /NODEFAULTLIB "
- OutputFile=".\zlibstat\zlibstat.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="ReleaseWithoutAsm|Win32"
- OutputDirectory="zlibstatWithoutAsm"
- IntermediateDirectory="zlibstatWithoutAsm"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- PrecompiledHeaderFile=".\zlibstat/zlibstat.pch"
- AssemblerListingLocation=".\zlibstatWithoutAsm/"
- ObjectFile=".\zlibstatWithoutAsm/"
- ProgramDataBaseFileName=".\zlibstatWithoutAsm/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions=" /NODEFAULTLIB "
- OutputFile=".\zlibstatWithoutAsm\zlibstat.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- </Configuration>
- </Configurations>
- <Files>
- <Filter
- Name="Source Files"
- Filter="">
- <File
- RelativePath="..\..\..\adler32.c">
- </File>
- <File
- RelativePath="..\..\..\compress.c">
- </File>
- <File
- RelativePath="..\..\..\crc32.c">
- </File>
- <File
- RelativePath="..\..\..\deflate.c">
- </File>
- <File
- RelativePath="..\..\masmx86\gvmat32c.c">
- </File>
- <File
- RelativePath="..\..\..\gzio.c">
- </File>
- <File
- RelativePath="..\..\..\infback.c">
- </File>
- <File
- RelativePath="..\..\..\inffast.c">
- </File>
- <File
- RelativePath="..\..\..\inflate.c">
- </File>
- <File
- RelativePath="..\..\..\inftrees.c">
- </File>
- <File
- RelativePath="..\..\minizip\ioapi.c">
- </File>
- <File
- RelativePath="..\..\..\trees.c">
- </File>
- <File
- RelativePath="..\..\..\uncompr.c">
- </File>
- <File
- RelativePath="..\..\minizip\unzip.c">
- </File>
- <File
- RelativePath="..\..\minizip\zip.c">
- </File>
- <File
- RelativePath=".\zlib.rc">
- </File>
- <File
- RelativePath=".\zlibvc.def">
- </File>
- <File
- RelativePath="..\..\..\zutil.c">
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc7/zlibvc.sln b/compat/zlib/contrib/vstudio/vc7/zlibvc.sln
deleted file mode 100644
index 927b42b..0000000
--- a/compat/zlib/contrib/vstudio/vc7/zlibvc.sln
+++ /dev/null
@@ -1,78 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 7.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testZlibDll", "testzlib.vcproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654C}"
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- ConfigName.0 = Debug
- ConfigName.1 = Release
- ConfigName.2 = ReleaseAxp
- ConfigName.3 = ReleaseWithoutAsm
- ConfigName.4 = ReleaseWithoutCrtdll
- EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug.ActiveCfg = Debug|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug.Build.0 = Debug|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release.ActiveCfg = Release|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release.Build.0 = Release|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseAxp.ActiveCfg = ReleaseAxp|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseAxp.Build.0 = ReleaseAxp|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm.ActiveCfg = ReleaseWithoutAsm|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm.Build.0 = ReleaseWithoutAsm|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutCrtdll.ActiveCfg = ReleaseAxp|Win32
- {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutCrtdll.Build.0 = ReleaseAxp|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug.ActiveCfg = Debug|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug.Build.0 = Debug|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release.ActiveCfg = Release|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release.Build.0 = Release|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseAxp.ActiveCfg = ReleaseAxp|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseAxp.Build.0 = ReleaseAxp|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm.ActiveCfg = ReleaseWithoutAsm|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm.Build.0 = ReleaseWithoutAsm|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutCrtdll.ActiveCfg = ReleaseWithoutCrtdll|Win32
- {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutCrtdll.Build.0 = ReleaseWithoutCrtdll|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug.ActiveCfg = Debug|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug.Build.0 = Debug|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release.ActiveCfg = Release|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release.Build.0 = Release|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseAxp.ActiveCfg = Release|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseAxp.Build.0 = Release|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm.ActiveCfg = Release|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm.Build.0 = Release|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutCrtdll.ActiveCfg = Release|Win32
- {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutCrtdll.Build.0 = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug.ActiveCfg = Debug|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug.Build.0 = Debug|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release.ActiveCfg = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release.Build.0 = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseAxp.ActiveCfg = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseAxp.Build.0 = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm.ActiveCfg = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm.Build.0 = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutCrtdll.ActiveCfg = Release|Win32
- {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutCrtdll.Build.0 = Release|Win32
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.Debug.ActiveCfg = Debug|Win32
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.Debug.Build.0 = Debug|Win32
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.Release.ActiveCfg = Release|Win32
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.Release.Build.0 = Release|Win32
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.ReleaseAxp.ActiveCfg = Release|Win32
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.ReleaseAxp.Build.0 = Release|Win32
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.ReleaseWithoutAsm.ActiveCfg = Release|Win32
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.ReleaseWithoutAsm.Build.0 = Release|Win32
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.ReleaseWithoutCrtdll.ActiveCfg = Release|Win32
- {AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.ReleaseWithoutCrtdll.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
diff --git a/compat/zlib/contrib/vstudio/vc7/zlibvc.vcproj b/compat/zlib/contrib/vstudio/vc7/zlibvc.vcproj
deleted file mode 100644
index 8533b49..0000000
--- a/compat/zlib/contrib/vstudio/vc7/zlibvc.vcproj
+++ /dev/null
@@ -1,445 +0,0 @@
-<?xml version="1.0" encoding = "Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.00"
- Name="zlibvc"
- SccProjectName=""
- SccLocalPath="">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory=".\DebugDll"
- IntermediateDirectory=".\DebugDll"
- ConfigurationType="2"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF"
- ExceptionHandling="FALSE"
- RuntimeLibrary="1"
- PrecompiledHeaderFile=".\DebugDll/zlibvc.pch"
- AssemblerListingLocation=".\DebugDll/"
- ObjectFile=".\DebugDll/"
- ProgramDataBaseFileName=".\DebugDll/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="4"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="..\..\masmx86\gvmat32.obj ..\..\masmx86\inffas32.obj"
- OutputFile=".\DebugDll\zlibwapi.dll"
- LinkIncremental="2"
- SuppressStartupBanner="TRUE"
- ModuleDefinitionFile=".\zlibvc.def"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile=".\DebugDll/zlibwapi.pdb"
- SubSystem="2"
- ImportLibrary=".\DebugDll/zlibwapi.lib"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
- MkTypLibCompatible="TRUE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\DebugDll/zlibvc.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="ReleaseWithoutAsm|Win32"
- OutputDirectory=".\zlibDllWithoutAsm"
- IntermediateDirectory=".\zlibDllWithoutAsm"
- ConfigurationType="2"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- WholeProgramOptimization="TRUE">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32,ZLIB_WINAPI"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="TRUE"
- PrecompiledHeaderFile=".\zlibDllWithoutAsm/zlibvc.pch"
- AssemblerOutput="2"
- AssemblerListingLocation=".\zlibDllWithoutAsm/"
- ObjectFile=".\zlibDllWithoutAsm/"
- ProgramDataBaseFileName=".\zlibDllWithoutAsm/"
- BrowseInformation="1"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="crtdll.lib"
- OutputFile=".\zlibDllWithoutAsm\zlibwapi.dll"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- IgnoreAllDefaultLibraries="TRUE"
- ModuleDefinitionFile=".\zlibvc.def"
- ProgramDatabaseFile=".\zlibDllWithoutAsm/zlibwapi.pdb"
- GenerateMapFile="TRUE"
- MapFileName=".\zlibDllWithoutAsm/zlibwapi.map"
- SubSystem="2"
- OptimizeForWindows98="1"
- ImportLibrary=".\zlibDllWithoutAsm/zlibwapi.lib"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="TRUE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\zlibDllWithoutAsm/zlibvc.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="ReleaseWithoutCrtdll|Win32"
- OutputDirectory=".\zlibDllWithoutCrtDll"
- IntermediateDirectory=".\zlibDllWithoutCrtDll"
- ConfigurationType="2"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- WholeProgramOptimization="TRUE">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="TRUE"
- PrecompiledHeaderFile=".\zlibDllWithoutCrtDll/zlibvc.pch"
- AssemblerOutput="2"
- AssemblerListingLocation=".\zlibDllWithoutCrtDll/"
- ObjectFile=".\zlibDllWithoutCrtDll/"
- ProgramDataBaseFileName=".\zlibDllWithoutCrtDll/"
- BrowseInformation="1"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="..\..\masmx86\gvmat32.obj ..\..\masmx86\inffas32.obj "
- OutputFile=".\zlibDllWithoutCrtDll\zlibwapi.dll"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- IgnoreAllDefaultLibraries="FALSE"
- ModuleDefinitionFile=".\zlibvc.def"
- ProgramDatabaseFile=".\zlibDllWithoutCrtDll/zlibwapi.pdb"
- GenerateMapFile="TRUE"
- MapFileName=".\zlibDllWithoutCrtDll/zlibwapi.map"
- SubSystem="2"
- OptimizeForWindows98="1"
- ImportLibrary=".\zlibDllWithoutCrtDll/zlibwapi.lib"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="TRUE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\zlibDllWithoutCrtDll/zlibvc.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="ReleaseAxp|Win32"
- OutputDirectory=".\zlibvc__"
- IntermediateDirectory=".\zlibvc__"
- ConfigurationType="2"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- WholeProgramOptimization="TRUE">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32,ZLIB_WINAPI"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="TRUE"
- PrecompiledHeaderFile=".\zlibvc__/zlibvc.pch"
- AssemblerOutput="2"
- AssemblerListingLocation=".\zlibvc__/"
- ObjectFile=".\zlibvc__/"
- ProgramDataBaseFileName=".\zlibvc__/"
- BrowseInformation="1"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="crtdll.lib"
- OutputFile="zlibvc__\zlibwapi.dll"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- IgnoreAllDefaultLibraries="TRUE"
- ModuleDefinitionFile=".\zlibvc.def"
- ProgramDatabaseFile=".\zlibvc__/zlibwapi.pdb"
- GenerateMapFile="TRUE"
- MapFileName=".\zlibvc__/zlibwapi.map"
- SubSystem="2"
- ImportLibrary=".\zlibvc__/zlibwapi.lib"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="TRUE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\zlibvc__/zlibvc.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory=".\ReleaseDll"
- IntermediateDirectory=".\ReleaseDll"
- ConfigurationType="2"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- WholeProgramOptimization="TRUE">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="TRUE"
- PrecompiledHeaderFile=".\ReleaseDll/zlibvc.pch"
- AssemblerOutput="2"
- AssemblerListingLocation=".\ReleaseDll/"
- ObjectFile=".\ReleaseDll/"
- ProgramDataBaseFileName=".\ReleaseDll/"
- BrowseInformation="1"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="..\..\masmx86\gvmat32.obj ..\..\masmx86\inffas32.obj crtdll.lib"
- OutputFile=".\ReleaseDll\zlibwapi.dll"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- IgnoreAllDefaultLibraries="TRUE"
- ModuleDefinitionFile=".\zlibvc.def"
- ProgramDatabaseFile=".\ReleaseDll/zlibwapi.pdb"
- GenerateMapFile="TRUE"
- MapFileName=".\ReleaseDll/zlibwapi.map"
- SubSystem="2"
- OptimizeForWindows98="1"
- ImportLibrary=".\ReleaseDll/zlibwapi.lib"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="TRUE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\Release/zlibvc.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1036"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- </Configurations>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90">
- <File
- RelativePath="..\..\..\adler32.c">
- </File>
- <File
- RelativePath="..\..\..\compress.c">
- </File>
- <File
- RelativePath="..\..\..\crc32.c">
- </File>
- <File
- RelativePath="..\..\..\deflate.c">
- </File>
- <File
- RelativePath="..\..\masmx86\gvmat32c.c">
- <FileConfiguration
- Name="ReleaseWithoutAsm|Win32"
- ExcludedFromBuild="TRUE">
- <Tool
- Name="VCCLCompilerTool"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\gzio.c">
- </File>
- <File
- RelativePath="..\..\..\infback.c">
- </File>
- <File
- RelativePath="..\..\..\inffast.c">
- </File>
- <File
- RelativePath="..\..\..\inflate.c">
- </File>
- <File
- RelativePath="..\..\..\inftrees.c">
- </File>
- <File
- RelativePath="..\..\minizip\ioapi.c">
- </File>
- <File
- RelativePath="..\..\minizip\iowin32.c">
- </File>
- <File
- RelativePath="..\..\..\trees.c">
- </File>
- <File
- RelativePath="..\..\..\uncompr.c">
- </File>
- <File
- RelativePath="..\..\minizip\unzip.c">
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions="ZLIB_INTERNAL"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\minizip\zip.c">
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions="ZLIB_INTERNAL"/>
- </FileConfiguration>
- </File>
- <File
- RelativePath=".\zlib.rc">
- </File>
- <File
- RelativePath=".\zlibvc.def">
- </File>
- <File
- RelativePath="..\..\..\zutil.c">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;fi;fd">
- <File
- RelativePath="..\..\..\deflate.h">
- </File>
- <File
- RelativePath="..\..\..\infblock.h">
- </File>
- <File
- RelativePath="..\..\..\infcodes.h">
- </File>
- <File
- RelativePath="..\..\..\inffast.h">
- </File>
- <File
- RelativePath="..\..\..\inftrees.h">
- </File>
- <File
- RelativePath="..\..\..\infutil.h">
- </File>
- <File
- RelativePath="..\..\..\zconf.h">
- </File>
- <File
- RelativePath="..\..\..\zlib.h">
- </File>
- <File
- RelativePath="..\..\..\zutil.h">
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc8/miniunz.vcproj b/compat/zlib/contrib/vstudio/vc8/miniunz.vcproj
deleted file mode 100644
index 4af53e8..0000000
--- a/compat/zlib/contrib/vstudio/vc8/miniunz.vcproj
+++ /dev/null
@@ -1,566 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="miniunz"
- ProjectGUID="{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- <Platform
- Name="x64"
- />
- <Platform
- Name="Itanium"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="x86\MiniUnzip$(ConfigurationName)"
- IntermediateDirectory="x86\MiniUnzip$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE"
- MinimalRebuild="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="1"
- BufferSecurityCheck="false"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="x86\ZlibDllDebug\zlibwapi.lib"
- OutputFile="$(OutDir)/miniunz.exe"
- LinkIncremental="2"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/miniunz.pdb"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|x64"
- OutputDirectory="x64\MiniUnzip$(ConfigurationName)"
- IntermediateDirectory="x64\MiniUnzip$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
- MinimalRebuild="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="3"
- BufferSecurityCheck="false"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="x64\ZlibDllDebug\zlibwapi.lib"
- OutputFile="$(OutDir)/miniunz.exe"
- LinkIncremental="2"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/miniunz.pdb"
- SubSystem="1"
- TargetMachine="17"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|Itanium"
- OutputDirectory="ia64\MiniUnzip$(ConfigurationName)"
- IntermediateDirectory="ia64\MiniUnzip$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="2"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
- MinimalRebuild="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="3"
- BufferSecurityCheck="false"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ia64\ZlibDllDebug\zlibwapi.lib"
- OutputFile="$(OutDir)/miniunz.exe"
- LinkIncremental="2"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/miniunz.pdb"
- SubSystem="1"
- TargetMachine="5"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="x86\MiniUnzip$(ConfigurationName)"
- IntermediateDirectory="x86\MiniUnzip$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="true"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE"
- StringPooling="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="0"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="x86\ZlibDllRelease\zlibwapi.lib"
- OutputFile="$(OutDir)/miniunz.exe"
- LinkIncremental="1"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|x64"
- OutputDirectory="x64\MiniUnzip$(ConfigurationName)"
- IntermediateDirectory="x64\MiniUnzip$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="true"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
- StringPooling="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="x64\ZlibDllRelease\zlibwapi.lib"
- OutputFile="$(OutDir)/miniunz.exe"
- LinkIncremental="1"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="17"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Itanium"
- OutputDirectory="ia64\MiniUnzip$(ConfigurationName)"
- IntermediateDirectory="ia64\MiniUnzip$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="2"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="true"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
- StringPooling="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ia64\ZlibDllRelease\zlibwapi.lib"
- OutputFile="$(OutDir)/miniunz.exe"
- LinkIncremental="1"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="5"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
- >
- <File
- RelativePath="..\..\minizip\miniunz.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc"
- >
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc8/minizip.vcproj b/compat/zlib/contrib/vstudio/vc8/minizip.vcproj
deleted file mode 100644
index 85f64c4..0000000
--- a/compat/zlib/contrib/vstudio/vc8/minizip.vcproj
+++ /dev/null
@@ -1,563 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="minizip"
- ProjectGUID="{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- <Platform
- Name="x64"
- />
- <Platform
- Name="Itanium"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="x86\MiniZip$(ConfigurationName)"
- IntermediateDirectory="x86\MiniZip$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE"
- MinimalRebuild="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="1"
- BufferSecurityCheck="false"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="x86\ZlibDllDebug\zlibwapi.lib"
- OutputFile="$(OutDir)/minizip.exe"
- LinkIncremental="2"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/minizip.pdb"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|x64"
- OutputDirectory="x64\$(ConfigurationName)"
- IntermediateDirectory="x64\$(ConfigurationName)"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
- MinimalRebuild="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="3"
- BufferSecurityCheck="false"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="x64\ZlibDllDebug\zlibwapi.lib"
- OutputFile="$(OutDir)/minizip.exe"
- LinkIncremental="2"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/minizip.pdb"
- SubSystem="1"
- TargetMachine="17"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|Itanium"
- OutputDirectory="ia64\$(ConfigurationName)"
- IntermediateDirectory="ia64\$(ConfigurationName)"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="2"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
- MinimalRebuild="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="3"
- BufferSecurityCheck="false"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ia64\ZlibDllDebug\zlibwapi.lib"
- OutputFile="$(OutDir)/minizip.exe"
- LinkIncremental="2"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/minizip.pdb"
- SubSystem="1"
- TargetMachine="5"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="x86\MiniZip$(ConfigurationName)"
- IntermediateDirectory="x86\MiniZip$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="true"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE"
- StringPooling="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="0"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="x86\ZlibDllRelease\zlibwapi.lib"
- OutputFile="$(OutDir)/minizip.exe"
- LinkIncremental="1"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|x64"
- OutputDirectory="x64\$(ConfigurationName)"
- IntermediateDirectory="x64\$(ConfigurationName)"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="true"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
- StringPooling="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="x64\ZlibDllRelease\zlibwapi.lib"
- OutputFile="$(OutDir)/minizip.exe"
- LinkIncremental="1"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="17"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Itanium"
- OutputDirectory="ia64\$(ConfigurationName)"
- IntermediateDirectory="ia64\$(ConfigurationName)"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="2"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="true"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
- StringPooling="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ia64\ZlibDllRelease\zlibwapi.lib"
- OutputFile="$(OutDir)/minizip.exe"
- LinkIncremental="1"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="5"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
- >
- <File
- RelativePath="..\..\minizip\minizip.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc"
- >
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc8/testzlib.vcproj b/compat/zlib/contrib/vstudio/vc8/testzlib.vcproj
deleted file mode 100644
index 68c3539..0000000
--- a/compat/zlib/contrib/vstudio/vc8/testzlib.vcproj
+++ /dev/null
@@ -1,948 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="testzlib"
- ProjectGUID="{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
- RootNamespace="testzlib"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- <Platform
- Name="x64"
- />
- <Platform
- Name="Itanium"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="x86\TestZlib$(ConfigurationName)"
- IntermediateDirectory="x86\TestZlib$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\.."
- PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE"
- MinimalRebuild="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="1"
- BufferSecurityCheck="false"
- UsePrecompiledHeader="0"
- AssemblerOutput="4"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="..\..\masmx86\gvmat32.obj ..\..\masmx86\inffas32.obj"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="2"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|x64"
- OutputDirectory="x64\TestZlib$(ConfigurationName)"
- IntermediateDirectory="x64\TestZlib$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\.."
- PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="0"
- RuntimeLibrary="3"
- BufferSecurityCheck="false"
- AssemblerListingLocation="$(IntDir)\"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj"
- GenerateManifest="false"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|Itanium"
- OutputDirectory="ia64\TestZlib$(ConfigurationName)"
- IntermediateDirectory="ia64\TestZlib$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="2"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\.."
- PreprocessorDefinitions="ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN64"
- MinimalRebuild="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="3"
- BufferSecurityCheck="false"
- UsePrecompiledHeader="0"
- AssemblerOutput="4"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="2"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
- SubSystem="1"
- TargetMachine="5"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="ReleaseWithoutAsm|Win32"
- OutputDirectory="x86\TestZlib$(ConfigurationName)"
- IntermediateDirectory="x86\TestZlib$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- CharacterSet="2"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="true"
- AdditionalIncludeDirectories="..\..\.."
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE"
- StringPooling="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="0"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="1"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="ReleaseWithoutAsm|x64"
- OutputDirectory="x64\TestZlib$(ConfigurationName)"
- IntermediateDirectory="x64\TestZlib$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\.."
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- AssemblerListingLocation="$(IntDir)\"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies=""
- GenerateManifest="false"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="ReleaseWithoutAsm|Itanium"
- OutputDirectory="ia64\TestZlib$(ConfigurationName)"
- IntermediateDirectory="ia64\TestZlib$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- CharacterSet="2"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="2"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="true"
- AdditionalIncludeDirectories="..\..\.."
- PreprocessorDefinitions="ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN64"
- StringPooling="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="1"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="5"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="x86\TestZlib$(ConfigurationName)"
- IntermediateDirectory="x86\TestZlib$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- CharacterSet="2"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="true"
- AdditionalIncludeDirectories="..\..\.."
- PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE"
- StringPooling="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="0"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="..\..\masmx86\gvmat32.obj ..\..\masmx86\inffas32.obj"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="1"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|x64"
- OutputDirectory="x64\TestZlib$(ConfigurationName)"
- IntermediateDirectory="x64\TestZlib$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\.."
- PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE"
- BasicRuntimeChecks="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- AssemblerListingLocation="$(IntDir)\"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj"
- GenerateManifest="false"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Itanium"
- OutputDirectory="ia64\TestZlib$(ConfigurationName)"
- IntermediateDirectory="ia64\TestZlib$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- CharacterSet="2"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="2"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="true"
- AdditionalIncludeDirectories="..\..\.."
- PreprocessorDefinitions="ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN64"
- StringPooling="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="1"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="5"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
- >
- <File
- RelativePath="..\..\..\adler32.c"
- >
- </File>
- <File
- RelativePath="..\..\..\compress.c"
- >
- </File>
- <File
- RelativePath="..\..\..\crc32.c"
- >
- </File>
- <File
- RelativePath="..\..\..\deflate.c"
- >
- </File>
- <File
- RelativePath="..\..\masmx86\gvmat32c.c"
- >
- <FileConfiguration
- Name="Debug|x64"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseWithoutAsm|x64"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseWithoutAsm|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win64 (AMD64)"
- ExcludedFromBuild="TRUE"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win64 (AMD64)"
- ExcludedFromBuild="TRUE"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseAsm|Win64 (AMD64)"
- ExcludedFromBuild="TRUE"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\infback.c"
- >
- </File>
- <File
- RelativePath="..\..\masmx64\inffas8664.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseWithoutAsm|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseWithoutAsm|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\inffast.c"
- >
- </File>
- <File
- RelativePath="..\..\..\inflate.c"
- >
- </File>
- <File
- RelativePath="..\..\..\inftrees.c"
- >
- </File>
- <File
- RelativePath="..\..\testzlib\testzlib.c"
- >
- </File>
- <File
- RelativePath="..\..\..\trees.c"
- >
- </File>
- <File
- RelativePath="..\..\..\uncompr.c"
- >
- </File>
- <File
- RelativePath="..\..\..\zutil.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc"
- >
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc8/testzlibdll.vcproj b/compat/zlib/contrib/vstudio/vc8/testzlibdll.vcproj
deleted file mode 100644
index f38ab5e..0000000
--- a/compat/zlib/contrib/vstudio/vc8/testzlibdll.vcproj
+++ /dev/null
@@ -1,567 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="TestZlibDll"
- ProjectGUID="{C52F9E7B-498A-42BE-8DB4-85A15694366A}"
- Keyword="Win32Proj"
- SignManifests="true"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- <Platform
- Name="x64"
- />
- <Platform
- Name="Itanium"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="x86\TestZlibDll$(ConfigurationName)"
- IntermediateDirectory="x86\TestZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE"
- MinimalRebuild="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="1"
- BufferSecurityCheck="false"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="x86\ZlibDllDebug\zlibwapi.lib"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="2"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|x64"
- OutputDirectory="x64\TestZlibDll$(ConfigurationName)"
- IntermediateDirectory="x64\TestZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
- MinimalRebuild="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="3"
- BufferSecurityCheck="false"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="x64\ZlibDllDebug\zlibwapi.lib"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="2"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
- SubSystem="1"
- TargetMachine="17"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|Itanium"
- OutputDirectory="ia64\TestZlibDll$(ConfigurationName)"
- IntermediateDirectory="ia64\TestZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="2"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
- MinimalRebuild="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="3"
- BufferSecurityCheck="false"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ia64\ZlibDllDebug\zlibwapi.lib"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="2"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
- SubSystem="1"
- TargetMachine="5"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="x86\TestZlibDll$(ConfigurationName)"
- IntermediateDirectory="x86\TestZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="true"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE"
- StringPooling="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="0"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="x86\ZlibDllRelease\zlibwapi.lib"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="1"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|x64"
- OutputDirectory="x64\TestZlibDll$(ConfigurationName)"
- IntermediateDirectory="x64\TestZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="true"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
- StringPooling="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="x64\ZlibDllRelease\zlibwapi.lib"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="1"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="17"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Itanium"
- OutputDirectory="ia64\TestZlibDll$(ConfigurationName)"
- IntermediateDirectory="ia64\TestZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="1"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="2"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- OmitFramePointers="true"
- AdditionalIncludeDirectories="..\..\..;..\..\minizip"
- PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
- StringPooling="true"
- BasicRuntimeChecks="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation="$(IntDir)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ia64\ZlibDllRelease\zlibwapi.lib"
- OutputFile="$(OutDir)/testzlib.exe"
- LinkIncremental="1"
- GenerateManifest="false"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- OptimizeForWindows98="1"
- TargetMachine="5"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
- >
- <File
- RelativePath="..\..\testzlib\testzlib.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc"
- >
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc8/zlib.rc b/compat/zlib/contrib/vstudio/vc8/zlib.rc
deleted file mode 100644
index 72cb8b4..0000000
--- a/compat/zlib/contrib/vstudio/vc8/zlib.rc
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <windows.h>
-
-#define IDR_VERSION1 1
-IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
- FILEVERSION 1,2,3,0
- PRODUCTVERSION 1,2,3,0
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS 0
- FILEOS VOS_DOS_WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE 0 // not used
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904E4"
- //language ID = U.S. English, char set = Windows, Multilingual
-
- BEGIN
- VALUE "FileDescription", "zlib data compression library\0"
- VALUE "FileVersion", "1.2.3.0\0"
- VALUE "InternalName", "zlib\0"
- VALUE "OriginalFilename", "zlib.dll\0"
- VALUE "ProductName", "ZLib.DLL\0"
- VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
- VALUE "LegalCopyright", "(C) 1995-2003 Jean-loup Gailly & Mark Adler\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x0409, 1252
- END
-END
diff --git a/compat/zlib/contrib/vstudio/vc8/zlibstat.vcproj b/compat/zlib/contrib/vstudio/vc8/zlibstat.vcproj
deleted file mode 100644
index fb97037..0000000
--- a/compat/zlib/contrib/vstudio/vc8/zlibstat.vcproj
+++ /dev/null
@@ -1,870 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="zlibstat"
- ProjectGUID="{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- <Platform
- Name="x64"
- />
- <Platform
- Name="Itanium"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="x86\ZlibStat$(ConfigurationName)"
- IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp"
- ConfigurationType="4"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE"
- ExceptionHandling="0"
- RuntimeLibrary="1"
- BufferSecurityCheck="false"
- PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="/MACHINE:X86 /NODEFAULTLIB"
- OutputFile="$(OutDir)\zlibstat.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|x64"
- OutputDirectory="x64\ZlibStat$(ConfigurationName)"
- IntermediateDirectory="x64\ZlibStat$(ConfigurationName)\Tmp"
- ConfigurationType="4"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN64"
- ExceptionHandling="0"
- RuntimeLibrary="3"
- BufferSecurityCheck="false"
- PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="/MACHINE:AMD64 /NODEFAULTLIB"
- OutputFile="$(OutDir)\zlibstat.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|Itanium"
- OutputDirectory="ia64\ZlibStat$(ConfigurationName)"
- IntermediateDirectory="ia64\ZlibStat$(ConfigurationName)\Tmp"
- ConfigurationType="4"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="2"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN64"
- ExceptionHandling="0"
- RuntimeLibrary="3"
- BufferSecurityCheck="false"
- PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="/MACHINE:IA64 /NODEFAULTLIB"
- OutputFile="$(OutDir)\zlibstat.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="x86\ZlibStat$(ConfigurationName)"
- IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp"
- ConfigurationType="4"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ASMV;ASMINF"
- StringPooling="true"
- ExceptionHandling="0"
- RuntimeLibrary="0"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="/MACHINE:X86 /NODEFAULTLIB"
- AdditionalDependencies="..\..\masmx86\gvmat32.obj ..\..\masmx86\inffas32.obj "
- OutputFile="$(OutDir)\zlibstat.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|x64"
- OutputDirectory="x64\ZlibStat$(ConfigurationName)"
- IntermediateDirectory="x64\ZlibStat$(ConfigurationName)\Tmp"
- ConfigurationType="4"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ASMV;ASMINF;WIN64"
- StringPooling="true"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="/MACHINE:AMD64 /NODEFAULTLIB"
- AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj "
- OutputFile="$(OutDir)\zlibstat.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Itanium"
- OutputDirectory="ia64\ZlibStat$(ConfigurationName)"
- IntermediateDirectory="ia64\ZlibStat$(ConfigurationName)\Tmp"
- ConfigurationType="4"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="2"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN64"
- StringPooling="true"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="/MACHINE:IA64 /NODEFAULTLIB"
- OutputFile="$(OutDir)\zlibstat.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="ReleaseWithoutAsm|Win32"
- OutputDirectory="x86\ZlibStat$(ConfigurationName)"
- IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp"
- ConfigurationType="4"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE"
- StringPooling="true"
- ExceptionHandling="0"
- RuntimeLibrary="0"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="/MACHINE:X86 /NODEFAULTLIB"
- OutputFile="$(OutDir)\zlibstat.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="ReleaseWithoutAsm|x64"
- OutputDirectory="x64\ZlibStat$(ConfigurationName)"
- IntermediateDirectory="x64\ZlibStat$(ConfigurationName)\Tmp"
- ConfigurationType="4"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN64"
- StringPooling="true"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="/MACHINE:AMD64 /NODEFAULTLIB"
- OutputFile="$(OutDir)\zlibstat.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="ReleaseWithoutAsm|Itanium"
- OutputDirectory="ia64\ZlibStat$(ConfigurationName)"
- IntermediateDirectory="ia64\ZlibStat$(ConfigurationName)\Tmp"
- ConfigurationType="4"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="2"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN64"
- StringPooling="true"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- AdditionalOptions="/MACHINE:IA64 /NODEFAULTLIB"
- OutputFile="$(OutDir)\zlibstat.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- >
- <File
- RelativePath="..\..\..\adler32.c"
- >
- </File>
- <File
- RelativePath="..\..\..\compress.c"
- >
- </File>
- <File
- RelativePath="..\..\..\crc32.c"
- >
- </File>
- <File
- RelativePath="..\..\..\deflate.c"
- >
- </File>
- <File
- RelativePath="..\..\masmx86\gvmat32c.c"
- >
- <FileConfiguration
- Name="Debug|x64"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseWithoutAsm|x64"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseWithoutAsm|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\gzio.c"
- >
- </File>
- <File
- RelativePath="..\..\..\infback.c"
- >
- </File>
- <File
- RelativePath="..\..\masmx64\inffas8664.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseWithoutAsm|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseWithoutAsm|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\inffast.c"
- >
- </File>
- <File
- RelativePath="..\..\..\inflate.c"
- >
- </File>
- <File
- RelativePath="..\..\..\inftrees.c"
- >
- </File>
- <File
- RelativePath="..\..\minizip\ioapi.c"
- >
- </File>
- <File
- RelativePath="..\..\..\trees.c"
- >
- </File>
- <File
- RelativePath="..\..\..\uncompr.c"
- >
- </File>
- <File
- RelativePath="..\..\minizip\unzip.c"
- >
- </File>
- <File
- RelativePath="..\..\minizip\zip.c"
- >
- </File>
- <File
- RelativePath=".\zlib.rc"
- >
- </File>
- <File
- RelativePath=".\zlibvc.def"
- >
- </File>
- <File
- RelativePath="..\..\..\zutil.c"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc8/zlibvc.def b/compat/zlib/contrib/vstudio/vc8/zlibvc.def
deleted file mode 100644
index a40e715..0000000
--- a/compat/zlib/contrib/vstudio/vc8/zlibvc.def
+++ /dev/null
@@ -1,92 +0,0 @@
-
-VERSION 1.23
-
-HEAPSIZE 1048576,8192
-
-EXPORTS
- adler32 @1
- compress @2
- crc32 @3
- deflate @4
- deflateCopy @5
- deflateEnd @6
- deflateInit2_ @7
- deflateInit_ @8
- deflateParams @9
- deflateReset @10
- deflateSetDictionary @11
- gzclose @12
- gzdopen @13
- gzerror @14
- gzflush @15
- gzopen @16
- gzread @17
- gzwrite @18
- inflate @19
- inflateEnd @20
- inflateInit2_ @21
- inflateInit_ @22
- inflateReset @23
- inflateSetDictionary @24
- inflateSync @25
- uncompress @26
- zlibVersion @27
- gzprintf @28
- gzputc @29
- gzgetc @30
- gzseek @31
- gzrewind @32
- gztell @33
- gzeof @34
- gzsetparams @35
- zError @36
- inflateSyncPoint @37
- get_crc_table @38
- compress2 @39
- gzputs @40
- gzgets @41
- inflateCopy @42
- inflateBackInit_ @43
- inflateBack @44
- inflateBackEnd @45
- compressBound @46
- deflateBound @47
- gzclearerr @48
- gzungetc @49
- zlibCompileFlags @50
- deflatePrime @51
-
- unzOpen @61
- unzClose @62
- unzGetGlobalInfo @63
- unzGetCurrentFileInfo @64
- unzGoToFirstFile @65
- unzGoToNextFile @66
- unzOpenCurrentFile @67
- unzReadCurrentFile @68
- unzOpenCurrentFile3 @69
- unztell @70
- unzeof @71
- unzCloseCurrentFile @72
- unzGetGlobalComment @73
- unzStringFileNameCompare @74
- unzLocateFile @75
- unzGetLocalExtrafield @76
- unzOpen2 @77
- unzOpenCurrentFile2 @78
- unzOpenCurrentFilePassword @79
-
- zipOpen @80
- zipOpenNewFileInZip @81
- zipWriteInFileInZip @82
- zipCloseFileInZip @83
- zipClose @84
- zipOpenNewFileInZip2 @86
- zipCloseFileInZipRaw @87
- zipOpen2 @88
- zipOpenNewFileInZip3 @89
-
- unzGetFilePos @100
- unzGoToFilePos @101
-
- fill_win32_filefunc @110
diff --git a/compat/zlib/contrib/vstudio/vc8/zlibvc.vcproj b/compat/zlib/contrib/vstudio/vc8/zlibvc.vcproj
deleted file mode 100644
index e717011..0000000
--- a/compat/zlib/contrib/vstudio/vc8/zlibvc.vcproj
+++ /dev/null
@@ -1,1219 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="zlibvc"
- ProjectGUID="{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- <Platform
- Name="x64"
- />
- <Platform
- Name="Itanium"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="x86\ZlibDll$(ConfigurationName)"
- IntermediateDirectory="x86\ZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="2"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="1"
- TypeLibraryName="$(OutDir)/zlibvc.tlb"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32,_CRT_SECURE_NO_DEPRECATE,ZLIB_WINAPI,ASMV,ASMINF"
- ExceptionHandling="0"
- RuntimeLibrary="1"
- BufferSecurityCheck="false"
- PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- BrowseInformation="0"
- WarningLevel="3"
- SuppressStartupBanner="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="..\..\masmx86\gvmat32.obj ..\..\masmx86\inffas32.obj"
- OutputFile="$(OutDir)\zlibwapi.dll"
- LinkIncremental="2"
- SuppressStartupBanner="true"
- GenerateManifest="false"
- ModuleDefinitionFile=".\zlibvc.def"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
- GenerateMapFile="true"
- MapFileName="$(OutDir)/zlibwapi.map"
- SubSystem="2"
- ImportLibrary="$(OutDir)/zlibwapi.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|x64"
- OutputDirectory="x64\ZlibDll$(ConfigurationName)"
- IntermediateDirectory="x64\ZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="2"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="3"
- TypeLibraryName="$(OutDir)/zlibvc.tlb"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32,_CRT_SECURE_NO_DEPRECATE,ZLIB_WINAPI,ASMV,ASMINF;WIN64"
- ExceptionHandling="0"
- RuntimeLibrary="3"
- BufferSecurityCheck="false"
- PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- BrowseInformation="0"
- WarningLevel="3"
- SuppressStartupBanner="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj "
- OutputFile="$(OutDir)\zlibwapi.dll"
- LinkIncremental="2"
- SuppressStartupBanner="true"
- GenerateManifest="false"
- ModuleDefinitionFile=".\zlibvc.def"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
- GenerateMapFile="true"
- MapFileName="$(OutDir)/zlibwapi.map"
- SubSystem="2"
- ImportLibrary="$(OutDir)/zlibwapi.lib"
- TargetMachine="17"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|Itanium"
- OutputDirectory="ia64\ZlibDll$(ConfigurationName)"
- IntermediateDirectory="ia64\ZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="2"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="2"
- TypeLibraryName="$(OutDir)/zlibvc.tlb"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;WIN64"
- ExceptionHandling="0"
- RuntimeLibrary="3"
- BufferSecurityCheck="false"
- PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- BrowseInformation="0"
- WarningLevel="3"
- SuppressStartupBanner="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)\zlibwapi.dll"
- LinkIncremental="2"
- SuppressStartupBanner="true"
- GenerateManifest="false"
- ModuleDefinitionFile=".\zlibvc.def"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
- GenerateMapFile="true"
- MapFileName="$(OutDir)/zlibwapi.map"
- SubSystem="2"
- ImportLibrary="$(OutDir)/zlibwapi.lib"
- TargetMachine="5"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="ReleaseWithoutAsm|Win32"
- OutputDirectory="x86\ZlibDll$(ConfigurationName)"
- IntermediateDirectory="x86\ZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="2"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="1"
- TypeLibraryName="$(OutDir)/zlibvc.tlb"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32,_CRT_SECURE_NO_DEPRECATE,ZLIB_WINAPI"
- StringPooling="true"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
- AssemblerOutput="2"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- BrowseInformation="0"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- OutputFile="$(OutDir)\zlibwapi.dll"
- LinkIncremental="1"
- SuppressStartupBanner="true"
- GenerateManifest="false"
- IgnoreAllDefaultLibraries="false"
- ModuleDefinitionFile=".\zlibvc.def"
- ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
- GenerateMapFile="true"
- MapFileName="$(OutDir)/zlibwapi.map"
- SubSystem="2"
- OptimizeForWindows98="1"
- ImportLibrary="$(OutDir)/zlibwapi.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="ReleaseWithoutAsm|x64"
- OutputDirectory="x64\ZlibDll$(ConfigurationName)"
- IntermediateDirectory="x64\ZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="2"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="3"
- TypeLibraryName="$(OutDir)/zlibvc.tlb"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32,_CRT_SECURE_NO_DEPRECATE,ZLIB_WINAPI;WIN64"
- StringPooling="true"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
- AssemblerOutput="2"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- BrowseInformation="0"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)\zlibwapi.dll"
- LinkIncremental="1"
- SuppressStartupBanner="true"
- GenerateManifest="false"
- IgnoreAllDefaultLibraries="false"
- ModuleDefinitionFile=".\zlibvc.def"
- ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
- GenerateMapFile="true"
- MapFileName="$(OutDir)/zlibwapi.map"
- SubSystem="2"
- OptimizeForWindows98="1"
- ImportLibrary="$(OutDir)/zlibwapi.lib"
- TargetMachine="17"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="ReleaseWithoutAsm|Itanium"
- OutputDirectory="ia64\ZlibDll$(ConfigurationName)"
- IntermediateDirectory="ia64\ZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="2"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="2"
- TypeLibraryName="$(OutDir)/zlibvc.tlb"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32,_CRT_SECURE_NO_DEPRECATE,ZLIB_WINAPI;WIN64"
- StringPooling="true"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
- AssemblerOutput="2"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- BrowseInformation="0"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)\zlibwapi.dll"
- LinkIncremental="1"
- SuppressStartupBanner="true"
- GenerateManifest="false"
- IgnoreAllDefaultLibraries="false"
- ModuleDefinitionFile=".\zlibvc.def"
- ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
- GenerateMapFile="true"
- MapFileName="$(OutDir)/zlibwapi.map"
- SubSystem="2"
- OptimizeForWindows98="1"
- ImportLibrary="$(OutDir)/zlibwapi.lib"
- TargetMachine="5"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="x86\ZlibDll$(ConfigurationName)"
- IntermediateDirectory="x86\ZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="2"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="1"
- TypeLibraryName="$(OutDir)/zlibvc.tlb"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;ASMV;ASMINF"
- StringPooling="true"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
- AssemblerOutput="2"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- BrowseInformation="0"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="..\..\masmx86\gvmat32.obj ..\..\masmx86\inffas32.obj "
- OutputFile="$(OutDir)\zlibwapi.dll"
- LinkIncremental="1"
- SuppressStartupBanner="true"
- GenerateManifest="false"
- IgnoreAllDefaultLibraries="false"
- ModuleDefinitionFile=".\zlibvc.def"
- ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
- GenerateMapFile="true"
- MapFileName="$(OutDir)/zlibwapi.map"
- SubSystem="2"
- OptimizeForWindows98="1"
- ImportLibrary="$(OutDir)/zlibwapi.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|x64"
- OutputDirectory="x64\ZlibDll$(ConfigurationName)"
- IntermediateDirectory="x64\ZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="2"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="3"
- TypeLibraryName="$(OutDir)/zlibvc.tlb"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;ASMV;ASMINF;WIN64"
- StringPooling="true"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
- AssemblerOutput="2"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- BrowseInformation="0"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj "
- OutputFile="$(OutDir)\zlibwapi.dll"
- LinkIncremental="1"
- SuppressStartupBanner="true"
- GenerateManifest="false"
- IgnoreAllDefaultLibraries="false"
- ModuleDefinitionFile=".\zlibvc.def"
- ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
- GenerateMapFile="true"
- MapFileName="$(OutDir)/zlibwapi.map"
- SubSystem="2"
- OptimizeForWindows98="1"
- ImportLibrary="$(OutDir)/zlibwapi.lib"
- TargetMachine="17"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Itanium"
- OutputDirectory="ia64\ZlibDll$(ConfigurationName)"
- IntermediateDirectory="ia64\ZlibDll$(ConfigurationName)\Tmp"
- ConfigurationType="2"
- InheritedPropertySheets="UpgradeFromVC70.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="true"
- SuppressStartupBanner="true"
- TargetEnvironment="2"
- TypeLibraryName="$(OutDir)/zlibvc.tlb"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
- PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;WIN64"
- StringPooling="true"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- BufferSecurityCheck="false"
- EnableFunctionLevelLinking="true"
- PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
- AssemblerOutput="2"
- AssemblerListingLocation="$(IntDir)\"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="$(OutDir)\"
- BrowseInformation="0"
- WarningLevel="3"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1036"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)\zlibwapi.dll"
- LinkIncremental="1"
- SuppressStartupBanner="true"
- GenerateManifest="false"
- IgnoreAllDefaultLibraries="false"
- ModuleDefinitionFile=".\zlibvc.def"
- ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
- GenerateMapFile="true"
- MapFileName="$(OutDir)/zlibwapi.map"
- SubSystem="2"
- OptimizeForWindows98="1"
- ImportLibrary="$(OutDir)/zlibwapi.lib"
- TargetMachine="5"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
- >
- <File
- RelativePath="..\..\..\adler32.c"
- >
- </File>
- <File
- RelativePath="..\..\..\compress.c"
- >
- </File>
- <File
- RelativePath="..\..\..\crc32.c"
- >
- </File>
- <File
- RelativePath="..\..\..\deflate.c"
- >
- </File>
- <File
- RelativePath="..\..\masmx86\gvmat32c.c"
- >
- <FileConfiguration
- Name="Debug|x64"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseWithoutAsm|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseWithoutAsm|x64"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseWithoutAsm|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\gzio.c"
- >
- </File>
- <File
- RelativePath="..\..\..\infback.c"
- >
- </File>
- <File
- RelativePath="..\..\masmx64\inffas8664.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseWithoutAsm|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="ReleaseWithoutAsm|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Itanium"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\inffast.c"
- >
- </File>
- <File
- RelativePath="..\..\..\inflate.c"
- >
- </File>
- <File
- RelativePath="..\..\..\inftrees.c"
- >
- </File>
- <File
- RelativePath="..\..\minizip\ioapi.c"
- >
- </File>
- <File
- RelativePath="..\..\minizip\iowin32.c"
- >
- </File>
- <File
- RelativePath="..\..\..\trees.c"
- >
- </File>
- <File
- RelativePath="..\..\..\uncompr.c"
- >
- </File>
- <File
- RelativePath="..\..\minizip\unzip.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions="ZLIB_INTERNAL"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions="ZLIB_INTERNAL"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Itanium"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions="ZLIB_INTERNAL"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\minizip\zip.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions="ZLIB_INTERNAL"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions="ZLIB_INTERNAL"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Itanium"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions="ZLIB_INTERNAL"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath=".\zlib.rc"
- >
- </File>
- <File
- RelativePath=".\zlibvc.def"
- >
- </File>
- <File
- RelativePath="..\..\..\zutil.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;fi;fd"
- >
- <File
- RelativePath="..\..\..\deflate.h"
- >
- </File>
- <File
- RelativePath="..\..\..\infblock.h"
- >
- </File>
- <File
- RelativePath="..\..\..\infcodes.h"
- >
- </File>
- <File
- RelativePath="..\..\..\inffast.h"
- >
- </File>
- <File
- RelativePath="..\..\..\inftrees.h"
- >
- </File>
- <File
- RelativePath="..\..\..\infutil.h"
- >
- </File>
- <File
- RelativePath="..\..\..\zconf.h"
- >
- </File>
- <File
- RelativePath="..\..\..\zlib.h"
- >
- </File>
- <File
- RelativePath="..\..\..\zutil.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc9/zlib.rc b/compat/zlib/contrib/vstudio/vc9/zlib.rc
index f822450..73f6476 100644
--- a/compat/zlib/contrib/vstudio/vc9/zlib.rc
+++ b/compat/zlib/contrib/vstudio/vc9/zlib.rc
@@ -2,8 +2,8 @@
#define IDR_VERSION1 1
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
- FILEVERSION 1,2,5,0
- PRODUCTVERSION 1,2,5,0
+ FILEVERSION 1,2,8,0
+ PRODUCTVERSION 1,2,8,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS32
@@ -17,12 +17,12 @@ BEGIN
BEGIN
VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
- VALUE "FileVersion", "1.2.5\0"
+ VALUE "FileVersion", "1.2.8\0"
VALUE "InternalName", "zlib\0"
- VALUE "OriginalFilename", "zlib.dll\0"
+ VALUE "OriginalFilename", "zlibwapi.dll\0"
VALUE "ProductName", "ZLib.DLL\0"
VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
- VALUE "LegalCopyright", "(C) 1995-2010 Jean-loup Gailly & Mark Adler\0"
+ VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0"
END
END
BLOCK "VarFileInfo"
diff --git a/compat/zlib/contrib/vstudio/vc9/zlibvc.def b/compat/zlib/contrib/vstudio/vc9/zlibvc.def
index 0269ef7..6367046 100644
--- a/compat/zlib/contrib/vstudio/vc9/zlibvc.def
+++ b/compat/zlib/contrib/vstudio/vc9/zlibvc.def
@@ -1,7 +1,7 @@
LIBRARY
; zlib data compression and ZIP file I/O library
-VERSION 1.24
+VERSION 1.2.8
EXPORTS
adler32 @1
@@ -55,6 +55,7 @@ EXPORTS
gzungetc @49
zlibCompileFlags @50
deflatePrime @51
+ deflatePending @52
unzOpen @61
unzClose @62
@@ -128,3 +129,15 @@ EXPORTS
inflatePrime @158
inflateReset2 @159
inflateUndermine @160
+
+; zlib1 v1.2.6 added:
+ gzgetc_ @161
+ inflateResetKeep @163
+ deflateResetKeep @164
+
+; zlib1 v1.2.7 added:
+ gzopen_w @165
+
+; zlib1 v1.2.8 added:
+ inflateGetDictionary @166
+ gzvprintf @167
diff --git a/compat/zlib/crc32.c b/compat/zlib/crc32.c
index 5511cd5..979a719 100644
--- a/compat/zlib/crc32.c
+++ b/compat/zlib/crc32.c
@@ -1,5 +1,5 @@
/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2006, 2010 Mark Adler
+ * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
@@ -9,7 +9,7 @@
* factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
*/
-/* @(#) $Id: crc32.c,v 1.3 2010/04/20 14:50:10 nijtmans Exp $ */
+/* @(#) $Id$ */
/*
Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
@@ -17,6 +17,8 @@
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
first call get_crc_table() to initialize the tables before allowing more than
one thread to use crc32().
+
+ DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
*/
#ifdef MAKECRCH
@@ -30,31 +32,11 @@
#define local static
-/* Find a four-byte integer type for crc32_little() and crc32_big(). */
-#ifndef NOBYFOUR
-# ifdef STDC /* need ANSI C limits.h to determine sizes */
-# include <limits.h>
-# define BYFOUR
-# if (UINT_MAX == 0xffffffffUL)
- typedef unsigned int u4;
-# else
-# if (ULONG_MAX == 0xffffffffUL)
- typedef unsigned long u4;
-# else
-# if (USHRT_MAX == 0xffffffffUL)
- typedef unsigned short u4;
-# else
-# undef BYFOUR /* can't find a four-byte integer type! */
-# endif
-# endif
-# endif
-# endif /* STDC */
-#endif /* !NOBYFOUR */
-
/* Definitions for doing the crc four data bytes at a time. */
+#if !defined(NOBYFOUR) && defined(Z_U4)
+# define BYFOUR
+#endif
#ifdef BYFOUR
-# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
- (((w)&0xff00)<<8)+(((w)&0xff)<<24))
local unsigned long crc32_little OF((unsigned long,
const unsigned char FAR *, unsigned));
local unsigned long crc32_big OF((unsigned long,
@@ -68,16 +50,16 @@
local unsigned long gf2_matrix_times OF((unsigned long *mat,
unsigned long vec));
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
-local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2);
+local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
#ifdef DYNAMIC_CRC_TABLE
local volatile int crc_table_empty = 1;
-local unsigned long FAR crc_table[TBLS][256];
+local z_crc_t FAR crc_table[TBLS][256];
local void make_crc_table OF((void));
#ifdef MAKECRCH
- local void write_table OF((FILE *, const unsigned long FAR *));
+ local void write_table OF((FILE *, const z_crc_t FAR *));
#endif /* MAKECRCH */
/*
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
@@ -107,9 +89,9 @@ local void make_crc_table OF((void));
*/
local void make_crc_table()
{
- unsigned long c;
+ z_crc_t c;
int n, k;
- unsigned long poly; /* polynomial exclusive-or pattern */
+ z_crc_t poly; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */
static volatile int first = 1; /* flag to limit concurrent making */
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
@@ -121,13 +103,13 @@ local void make_crc_table()
first = 0;
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
- poly = 0UL;
- for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
- poly |= 1UL << (31 - p[n]);
+ poly = 0;
+ for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
+ poly |= (z_crc_t)1 << (31 - p[n]);
/* generate a crc for every 8-bit value */
for (n = 0; n < 256; n++) {
- c = (unsigned long)n;
+ c = (z_crc_t)n;
for (k = 0; k < 8; k++)
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
crc_table[0][n] = c;
@@ -138,11 +120,11 @@ local void make_crc_table()
and then the byte reversal of those as well as the first table */
for (n = 0; n < 256; n++) {
c = crc_table[0][n];
- crc_table[4][n] = REV(c);
+ crc_table[4][n] = ZSWAP32(c);
for (k = 1; k < 4; k++) {
c = crc_table[0][c & 0xff] ^ (c >> 8);
crc_table[k][n] = c;
- crc_table[k + 4][n] = REV(c);
+ crc_table[k + 4][n] = ZSWAP32(c);
}
}
#endif /* BYFOUR */
@@ -164,7 +146,7 @@ local void make_crc_table()
if (out == NULL) return;
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
- fprintf(out, "local const unsigned long FAR ");
+ fprintf(out, "local const z_crc_t FAR ");
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
write_table(out, crc_table[0]);
# ifdef BYFOUR
@@ -184,12 +166,13 @@ local void make_crc_table()
#ifdef MAKECRCH
local void write_table(out, table)
FILE *out;
- const unsigned long FAR *table;
+ const z_crc_t FAR *table;
{
int n;
for (n = 0; n < 256; n++)
- fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
+ fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
+ (unsigned long)(table[n]),
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
}
#endif /* MAKECRCH */
@@ -204,13 +187,13 @@ local void write_table(out, table)
/* =========================================================================
* This function can be used by asm versions of crc32()
*/
-const unsigned long FAR * ZEXPORT get_crc_table()
+const z_crc_t FAR * ZEXPORT get_crc_table()
{
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty)
make_crc_table();
#endif /* DYNAMIC_CRC_TABLE */
- return (const unsigned long FAR *)crc_table;
+ return (const z_crc_t FAR *)crc_table;
}
/* ========================================================================= */
@@ -232,7 +215,7 @@ unsigned long ZEXPORT crc32(crc, buf, len)
#ifdef BYFOUR
if (sizeof(void *) == sizeof(ptrdiff_t)) {
- u4 endian;
+ z_crc_t endian;
endian = 1;
if (*((unsigned char *)(&endian)))
@@ -266,17 +249,17 @@ local unsigned long crc32_little(crc, buf, len)
const unsigned char FAR *buf;
unsigned len;
{
- register u4 c;
- register const u4 FAR *buf4;
+ register z_crc_t c;
+ register const z_crc_t FAR *buf4;
- c = (u4)crc;
+ c = (z_crc_t)crc;
c = ~c;
while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
len--;
}
- buf4 = (const u4 FAR *)(const void FAR *)buf;
+ buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
while (len >= 32) {
DOLIT32;
len -= 32;
@@ -306,17 +289,17 @@ local unsigned long crc32_big(crc, buf, len)
const unsigned char FAR *buf;
unsigned len;
{
- register u4 c;
- register const u4 FAR *buf4;
+ register z_crc_t c;
+ register const z_crc_t FAR *buf4;
- c = REV((u4)crc);
+ c = ZSWAP32((z_crc_t)crc);
c = ~c;
while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
len--;
}
- buf4 = (const u4 FAR *)(const void FAR *)buf;
+ buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
buf4--;
while (len >= 32) {
DOBIG32;
@@ -333,7 +316,7 @@ local unsigned long crc32_big(crc, buf, len)
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
} while (--len);
c = ~c;
- return (unsigned long)(REV(c));
+ return (unsigned long)(ZSWAP32(c));
}
#endif /* BYFOUR */
diff --git a/compat/zlib/crc32.h b/compat/zlib/crc32.h
index 8053b61..9e0c778 100644
--- a/compat/zlib/crc32.h
+++ b/compat/zlib/crc32.h
@@ -2,7 +2,7 @@
* Generated automatically by crc32.c
*/
-local const unsigned long FAR crc_table[TBLS][256] =
+local const z_crc_t FAR crc_table[TBLS][256] =
{
{
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
diff --git a/compat/zlib/deflate.c b/compat/zlib/deflate.c
index fa892ad..6969577 100644
--- a/compat/zlib/deflate.c
+++ b/compat/zlib/deflate.c
@@ -1,5 +1,5 @@
/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+ * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -37,7 +37,7 @@
* REFERENCES
*
* Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- * Available in http://www.ietf.org/rfc/rfc1951.txt
+ * Available in http://tools.ietf.org/html/rfc1951
*
* A description of the Rabin and Karp algorithm is given in the book
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
@@ -47,12 +47,12 @@
*
*/
-/* @(#) $Id: deflate.c,v 1.3 2010/04/20 14:50:10 nijtmans Exp $ */
+/* @(#) $Id$ */
#include "deflate.h"
const char deflate_copyright[] =
- " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler ";
+ " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
@@ -155,6 +155,9 @@ local const config configuration_table[10] = {
struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
#endif
+/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
+#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0))
+
/* ===========================================================================
* Update a hash value with the given input byte
* IN assertion: all calls to to UPDATE_HASH are made with consecutive
@@ -235,10 +238,19 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
strm->msg = Z_NULL;
if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
strm->zalloc = zcalloc;
strm->opaque = (voidpf)0;
+#endif
}
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
#ifdef FASTEST
if (level != 0) level = 1;
@@ -293,7 +305,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
s->pending_buf == Z_NULL) {
s->status = FINISH_STATE;
- strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+ strm->msg = ERR_MSG(Z_MEM_ERROR);
deflateEnd (strm);
return Z_MEM_ERROR;
}
@@ -314,43 +326,70 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
uInt dictLength;
{
deflate_state *s;
- uInt length = dictLength;
- uInt n;
- IPos hash_head = 0;
+ uInt str, n;
+ int wrap;
+ unsigned avail;
+ z_const unsigned char *next;
- if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
- strm->state->wrap == 2 ||
- (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
return Z_STREAM_ERROR;
-
s = strm->state;
- if (s->wrap)
- strm->adler = adler32(strm->adler, dictionary, dictLength);
+ wrap = s->wrap;
+ if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
+ return Z_STREAM_ERROR;
- if (length < MIN_MATCH) return Z_OK;
- if (length > s->w_size) {
- length = s->w_size;
- dictionary += dictLength - length; /* use the tail of the dictionary */
+ /* when using zlib wrappers, compute Adler-32 for provided dictionary */
+ if (wrap == 1)
+ strm->adler = adler32(strm->adler, dictionary, dictLength);
+ s->wrap = 0; /* avoid computing Adler-32 in read_buf */
+
+ /* if dictionary would fill window, just replace the history */
+ if (dictLength >= s->w_size) {
+ if (wrap == 0) { /* already empty otherwise */
+ CLEAR_HASH(s);
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->insert = 0;
+ }
+ dictionary += dictLength - s->w_size; /* use the tail */
+ dictLength = s->w_size;
}
- zmemcpy(s->window, dictionary, length);
- s->strstart = length;
- s->block_start = (long)length;
- /* Insert all strings in the hash table (except for the last two bytes).
- * s->lookahead stays null, so s->ins_h will be recomputed at the next
- * call of fill_window.
- */
- s->ins_h = s->window[0];
- UPDATE_HASH(s, s->ins_h, s->window[1]);
- for (n = 0; n <= length - MIN_MATCH; n++) {
- INSERT_STRING(s, n, hash_head);
+ /* insert dictionary into window and hash */
+ avail = strm->avail_in;
+ next = strm->next_in;
+ strm->avail_in = dictLength;
+ strm->next_in = (z_const Bytef *)dictionary;
+ fill_window(s);
+ while (s->lookahead >= MIN_MATCH) {
+ str = s->strstart;
+ n = s->lookahead - (MIN_MATCH-1);
+ do {
+ UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+ s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+ s->head[s->ins_h] = (Pos)str;
+ str++;
+ } while (--n);
+ s->strstart = str;
+ s->lookahead = MIN_MATCH-1;
+ fill_window(s);
}
- if (hash_head) hash_head = 0; /* to make compiler happy */
+ s->strstart += s->lookahead;
+ s->block_start = (long)s->strstart;
+ s->insert = s->lookahead;
+ s->lookahead = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ strm->next_in = next;
+ strm->avail_in = avail;
+ s->wrap = wrap;
return Z_OK;
}
/* ========================================================================= */
-int ZEXPORT deflateReset (strm)
+int ZEXPORT deflateResetKeep (strm)
z_streamp strm;
{
deflate_state *s;
@@ -380,12 +419,23 @@ int ZEXPORT deflateReset (strm)
s->last_flush = Z_NO_FLUSH;
_tr_init(s);
- lm_init(s);
return Z_OK;
}
/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+ z_streamp strm;
+{
+ int ret;
+
+ ret = deflateResetKeep(strm);
+ if (ret == Z_OK)
+ lm_init(strm->state);
+ return ret;
+}
+
+/* ========================================================================= */
int ZEXPORT deflateSetHeader (strm, head)
z_streamp strm;
gz_headerp head;
@@ -397,14 +447,42 @@ int ZEXPORT deflateSetHeader (strm, head)
}
/* ========================================================================= */
+int ZEXPORT deflatePending (strm, pending, bits)
+ unsigned *pending;
+ int *bits;
+ z_streamp strm;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (pending != Z_NULL)
+ *pending = strm->state->pending;
+ if (bits != Z_NULL)
+ *bits = strm->state->bi_valid;
+ return Z_OK;
+}
+
+/* ========================================================================= */
int ZEXPORT deflatePrime (strm, bits, value)
z_streamp strm;
int bits;
int value;
{
+ deflate_state *s;
+ int put;
+
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- strm->state->bi_valid = bits;
- strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
+ s = strm->state;
+ if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
+ return Z_BUF_ERROR;
+ do {
+ put = Buf_size - s->bi_valid;
+ if (put > bits)
+ put = bits;
+ s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
+ s->bi_valid += put;
+ _tr_flush_bits(s);
+ value >>= put;
+ bits -= put;
+ } while (bits);
return Z_OK;
}
@@ -435,6 +513,8 @@ int ZEXPORT deflateParams(strm, level, strategy)
strm->total_in != 0) {
/* Flush the last buffer: */
err = deflate(strm, Z_BLOCK);
+ if (err == Z_BUF_ERROR && s->pending == 0)
+ err = Z_OK;
}
if (s->level != level) {
s->level = level;
@@ -562,19 +642,22 @@ local void putShortMSB (s, b)
local void flush_pending(strm)
z_streamp strm;
{
- unsigned len = strm->state->pending;
+ unsigned len;
+ deflate_state *s = strm->state;
+ _tr_flush_bits(s);
+ len = s->pending;
if (len > strm->avail_out) len = strm->avail_out;
if (len == 0) return;
- zmemcpy(strm->next_out, strm->state->pending_out, len);
+ zmemcpy(strm->next_out, s->pending_out, len);
strm->next_out += len;
- strm->state->pending_out += len;
+ s->pending_out += len;
strm->total_out += len;
strm->avail_out -= len;
- strm->state->pending -= len;
- if (strm->state->pending == 0) {
- strm->state->pending_out = strm->state->pending_buf;
+ s->pending -= len;
+ if (s->pending == 0) {
+ s->pending_out = s->pending_buf;
}
}
@@ -801,7 +884,7 @@ int ZEXPORT deflate (strm, flush)
* flushes. For repeated and useless calls with Z_FINISH, we keep
* returning Z_STREAM_END instead of Z_BUF_ERROR.
*/
- } else if (strm->avail_in == 0 && flush <= old_flush &&
+ } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
flush != Z_FINISH) {
ERR_RETURN(strm, Z_BUF_ERROR);
}
@@ -850,6 +933,7 @@ int ZEXPORT deflate (strm, flush)
if (s->lookahead == 0) {
s->strstart = 0;
s->block_start = 0L;
+ s->insert = 0;
}
}
}
@@ -945,12 +1029,12 @@ int ZEXPORT deflateCopy (dest, source)
ss = source->state;
- zmemcpy(dest, source, sizeof(z_stream));
+ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
if (ds == Z_NULL) return Z_MEM_ERROR;
dest->state = (struct internal_state FAR *) ds;
- zmemcpy(ds, ss, sizeof(deflate_state));
+ zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
ds->strm = dest;
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
@@ -966,8 +1050,8 @@ int ZEXPORT deflateCopy (dest, source)
}
/* following zmemcpy do not work for 16-bit MSDOS */
zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
- zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
- zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+ zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
+ zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
@@ -1001,15 +1085,15 @@ local int read_buf(strm, buf, size)
strm->avail_in -= len;
+ zmemcpy(buf, strm->next_in, len);
if (strm->state->wrap == 1) {
- strm->adler = adler32(strm->adler, strm->next_in, len);
+ strm->adler = adler32(strm->adler, buf, len);
}
#ifdef GZIP
else if (strm->state->wrap == 2) {
- strm->adler = crc32(strm->adler, strm->next_in, len);
+ strm->adler = crc32(strm->adler, buf, len);
}
#endif
- zmemcpy(buf, strm->next_in, len);
strm->next_in += len;
strm->total_in += len;
@@ -1036,6 +1120,7 @@ local void lm_init (s)
s->strstart = 0;
s->block_start = 0L;
s->lookahead = 0;
+ s->insert = 0;
s->match_length = s->prev_length = MIN_MATCH-1;
s->match_available = 0;
s->ins_h = 0;
@@ -1310,6 +1395,8 @@ local void fill_window(s)
unsigned more; /* Amount of free space at the end of the window. */
uInt wsize = s->w_size;
+ Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
+
do {
more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
@@ -1362,7 +1449,7 @@ local void fill_window(s)
#endif
more += wsize;
}
- if (s->strm->avail_in == 0) return;
+ if (s->strm->avail_in == 0) break;
/* If there was no sliding:
* strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
@@ -1381,12 +1468,24 @@ local void fill_window(s)
s->lookahead += n;
/* Initialize the hash value now that we have some input: */
- if (s->lookahead >= MIN_MATCH) {
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+ if (s->lookahead + s->insert >= MIN_MATCH) {
+ uInt str = s->strstart - s->insert;
+ s->ins_h = s->window[str];
+ UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
#if MIN_MATCH != 3
Call UPDATE_HASH() MIN_MATCH-3 more times
#endif
+ while (s->insert) {
+ UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+ s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+ s->head[s->ins_h] = (Pos)str;
+ str++;
+ s->insert--;
+ if (s->lookahead + s->insert < MIN_MATCH)
+ break;
+ }
}
/* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
* but this is not important since only literal bytes will be emitted.
@@ -1427,6 +1526,9 @@ local void fill_window(s)
s->high_water += init;
}
}
+
+ Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
+ "not enough room for search");
}
/* ===========================================================================
@@ -1506,8 +1608,14 @@ local block_state deflate_stored(s, flush)
FLUSH_BLOCK(s, 0);
}
}
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
+ s->insert = 0;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if ((long)s->strstart > s->block_start)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
}
/* ===========================================================================
@@ -1603,8 +1711,14 @@ local block_state deflate_fast(s, flush)
}
if (bflush) FLUSH_BLOCK(s, 0);
}
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
+ s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
}
#ifndef FASTEST
@@ -1728,8 +1842,14 @@ local block_state deflate_slow(s, flush)
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
s->match_available = 0;
}
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
+ s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
}
#endif /* FASTEST */
@@ -1749,11 +1869,11 @@ local block_state deflate_rle(s, flush)
for (;;) {
/* Make sure that we always have enough lookahead, except
* at the end of the input file. We need MAX_MATCH bytes
- * for the longest encodable run.
+ * for the longest run, plus one for the unrolled loop.
*/
- if (s->lookahead < MAX_MATCH) {
+ if (s->lookahead <= MAX_MATCH) {
fill_window(s);
- if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
+ if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
return need_more;
}
if (s->lookahead == 0) break; /* flush the current block */
@@ -1776,6 +1896,7 @@ local block_state deflate_rle(s, flush)
if (s->match_length > s->lookahead)
s->match_length = s->lookahead;
}
+ Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
}
/* Emit match if have run of MIN_MATCH or longer, else emit literal */
@@ -1796,8 +1917,14 @@ local block_state deflate_rle(s, flush)
}
if (bflush) FLUSH_BLOCK(s, 0);
}
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
+ s->insert = 0;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
}
/* ===========================================================================
@@ -1829,6 +1956,12 @@ local block_state deflate_huff(s, flush)
s->strstart++;
if (bflush) FLUSH_BLOCK(s, 0);
}
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
+ s->insert = 0;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
}
diff --git a/compat/zlib/deflate.h b/compat/zlib/deflate.h
index 9199d88..ce0299e 100644
--- a/compat/zlib/deflate.h
+++ b/compat/zlib/deflate.h
@@ -1,5 +1,5 @@
/* deflate.h -- internal compression state
- * Copyright (C) 1995-2010 Jean-loup Gailly
+ * Copyright (C) 1995-2012 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -8,7 +8,7 @@
subject to change. Applications should only use zlib.h.
*/
-/* @(#) $Id: deflate.h,v 1.3 2010/04/20 14:50:10 nijtmans Exp $ */
+/* @(#) $Id$ */
#ifndef DEFLATE_H
#define DEFLATE_H
@@ -48,6 +48,9 @@
#define MAX_BITS 15
/* All codes must not exceed MAX_BITS bits */
+#define Buf_size 16
+/* size of bit buffer in bi_buf */
+
#define INIT_STATE 42
#define EXTRA_STATE 69
#define NAME_STATE 73
@@ -101,7 +104,7 @@ typedef struct internal_state {
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
gz_headerp gzhead; /* gzip header information to write */
uInt gzindex; /* where in extra, name, or comment */
- Byte method; /* STORED (for zip only) or DEFLATED */
+ Byte method; /* can only be DEFLATED */
int last_flush; /* value of flush param for previous deflate call */
/* used by deflate.c: */
@@ -188,7 +191,7 @@ typedef struct internal_state {
int nice_match; /* Stop searching when current match exceeds this */
/* used by trees.c: */
- /* Didn't use ct_data typedef below to supress compiler warning */
+ /* Didn't use ct_data typedef below to suppress compiler warning */
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
@@ -244,7 +247,7 @@ typedef struct internal_state {
ulg opt_len; /* bit length of current block with optimal trees */
ulg static_len; /* bit length of current block with static trees */
uInt matches; /* number of string matches in current block */
- int last_eob_len; /* bit length of EOB code for last block */
+ uInt insert; /* bytes at end of window left to insert */
#ifdef DEBUG
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
@@ -294,6 +297,7 @@ void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
ulg stored_len, int last));
+void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
ulg stored_len, int last));
diff --git a/compat/zlib/doc/algorithm.txt b/compat/zlib/doc/algorithm.txt
index 34960bd..c97f495 100644
--- a/compat/zlib/doc/algorithm.txt
+++ b/compat/zlib/doc/algorithm.txt
@@ -206,4 +206,4 @@ Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
pp. 337-343.
``DEFLATE Compressed Data Format Specification'' available in
-http://www.ietf.org/rfc/rfc1951.txt
+http://tools.ietf.org/html/rfc1951
diff --git a/compat/zlib/examples/enough.c b/compat/zlib/examples/enough.c
index c40410b..b991144 100644
--- a/compat/zlib/examples/enough.c
+++ b/compat/zlib/examples/enough.c
@@ -1,7 +1,7 @@
/* enough.c -- determine the maximum size of inflate's Huffman code tables over
* all possible valid and complete Huffman codes, subject to a length limit.
- * Copyright (C) 2007, 2008 Mark Adler
- * Version 1.3 17 February 2008 Mark Adler
+ * Copyright (C) 2007, 2008, 2012 Mark Adler
+ * Version 1.4 18 August 2012 Mark Adler
*/
/* Version history:
@@ -14,6 +14,9 @@
1.3 17 Feb 2008 Add argument for initial root table size
Fix bug for initial root table size == max - 1
Use a macro to compute the history index
+ 1.4 18 Aug 2012 Avoid shifts more than bits in type (caused endless loop!)
+ Clean up comparisons of different types
+ Clean up code indentation
*/
/*
@@ -236,8 +239,8 @@ local big_t count(int syms, int len, int left)
for (use = least; use <= most; use++) {
got = count(syms - use, len + 1, (left - use) << 1);
sum += got;
- if (got == -1 || sum < got) /* overflow */
- return -1;
+ if (got == (big_t)0 - 1 || sum < got) /* overflow */
+ return (big_t)0 - 1;
}
/* verify that all recursive calls are productive */
@@ -458,6 +461,7 @@ int main(int argc, char **argv)
int n; /* number of symbols to code for this run */
big_t got; /* return value of count() */
big_t sum; /* accumulated number of codes over n */
+ code_t word; /* for counting bits in code_t */
/* set up globals for cleanup() */
code = NULL;
@@ -466,19 +470,19 @@ int main(int argc, char **argv)
/* get arguments -- default to the deflate literal/length code */
syms = 286;
- root = 9;
+ root = 9;
max = 15;
if (argc > 1) {
syms = atoi(argv[1]);
if (argc > 2) {
root = atoi(argv[2]);
- if (argc > 3)
- max = atoi(argv[3]);
- }
+ if (argc > 3)
+ max = atoi(argv[3]);
+ }
}
if (argc > 4 || syms < 2 || root < 1 || max < 1) {
fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n",
- stderr);
+ stderr);
return 1;
}
@@ -487,18 +491,17 @@ int main(int argc, char **argv)
max = syms - 1;
/* determine the number of bits in a code_t */
- n = 0;
- while (((code_t)1 << n) != 0)
- n++;
+ for (n = 0, word = 1; word; n++, word <<= 1)
+ ;
/* make sure that the calculation of most will not overflow */
- if (max > n || syms - 2 >= (((code_t)0 - 1) >> (max - 1))) {
+ if (max > n || (code_t)(syms - 2) >= (((code_t)0 - 1) >> (max - 1))) {
fputs("abort: code length too long for internal types\n", stderr);
return 1;
}
/* reject impossible code requests */
- if (syms - 1 > ((code_t)1 << max) - 1) {
+ if ((code_t)(syms - 1) > ((code_t)1 << max) - 1) {
fprintf(stderr, "%d symbols cannot be coded in %d bits\n",
syms, max);
return 1;
@@ -532,7 +535,7 @@ int main(int argc, char **argv)
for (n = 2; n <= syms; n++) {
got = count(n, 1, 2);
sum += got;
- if (got == -1 || sum < got) { /* overflow */
+ if (got == (big_t)0 - 1 || sum < got) { /* overflow */
fputs("abort: can't count that high!\n", stderr);
cleanup();
return 1;
@@ -556,9 +559,9 @@ int main(int argc, char **argv)
}
/* find and show maximum inflate table usage */
- if (root > max) /* reduce root to max length */
- root = max;
- if (syms < ((code_t)1 << (root + 1)))
+ if (root > max) /* reduce root to max length */
+ root = max;
+ if ((code_t)syms < ((code_t)1 << (root + 1)))
enough(syms);
else
puts("cannot handle minimum code lengths > root");
diff --git a/compat/zlib/examples/gun.c b/compat/zlib/examples/gun.c
index 72b0882..89e484f 100644
--- a/compat/zlib/examples/gun.c
+++ b/compat/zlib/examples/gun.c
@@ -1,7 +1,7 @@
/* gun.c -- simple gunzip to give an example of the use of inflateBack()
- * Copyright (C) 2003, 2005, 2008, 2010 Mark Adler
+ * Copyright (C) 2003, 2005, 2008, 2010, 2012 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
- Version 1.6 17 January 2010 Mark Adler */
+ Version 1.7 12 August 2012 Mark Adler */
/* Version history:
1.0 16 Feb 2003 First version for testing of inflateBack()
@@ -18,6 +18,7 @@
1.4 8 Dec 2006 LZW decompression speed improvements
1.5 9 Feb 2008 Avoid warning in latest version of gcc
1.6 17 Jan 2010 Avoid signed/unsigned comparison warnings
+ 1.7 12 Aug 2012 Update for z_const usage in zlib 1.2.8
*/
/*
@@ -85,7 +86,7 @@ struct ind {
/* Load input buffer, assumed to be empty, and return bytes loaded and a
pointer to them. read() is called until the buffer is full, or until it
returns end-of-file or error. Return 0 on error. */
-local unsigned in(void *in_desc, unsigned char **buf)
+local unsigned in(void *in_desc, z_const unsigned char **buf)
{
int ret;
unsigned len;
@@ -196,7 +197,7 @@ unsigned char match[65280 + 2]; /* buffer for reversed match or gzip
file, read error, or write error (a write error indicated by strm->next_in
not equal to Z_NULL), or Z_DATA_ERROR for invalid input.
*/
-local int lunpipe(unsigned have, unsigned char *next, struct ind *indp,
+local int lunpipe(unsigned have, z_const unsigned char *next, struct ind *indp,
int outfile, z_stream *strm)
{
int last; /* last byte read by NEXT(), or -1 if EOF */
@@ -383,7 +384,7 @@ local int gunpipe(z_stream *strm, int infile, int outfile)
{
int ret, first, last;
unsigned have, flags, len;
- unsigned char *next = NULL;
+ z_const unsigned char *next = NULL;
struct ind ind, *indp;
struct outd outd;
diff --git a/compat/zlib/examples/gzappend.c b/compat/zlib/examples/gzappend.c
index e9e878e..662dec3 100644
--- a/compat/zlib/examples/gzappend.c
+++ b/compat/zlib/examples/gzappend.c
@@ -1,7 +1,7 @@
/* gzappend -- command to append to a gzip file
- Copyright (C) 2003 Mark Adler, all rights reserved
- version 1.1, 4 Nov 2003
+ Copyright (C) 2003, 2012 Mark Adler, all rights reserved
+ version 1.2, 11 Oct 2012
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
@@ -39,6 +39,8 @@
* - Keep gzip file clean on appended file read errors
* - Use in-place rotate instead of auxiliary buffer
* (Why you ask? Because it was fun to write!)
+ * 1.2 11 Oct 2012 - Fix for proper z_const usage
+ * - Check for input buffer malloc failure
*/
/*
@@ -170,7 +172,7 @@ typedef struct {
int size; /* 1 << size is bytes in buf */
unsigned left; /* bytes available at next */
unsigned char *buf; /* buffer */
- unsigned char *next; /* next byte in buffer */
+ z_const unsigned char *next; /* next byte in buffer */
char *name; /* file name for error messages */
} file;
@@ -399,14 +401,14 @@ local void gztack(char *name, int gd, z_stream *strm, int last)
}
/* allocate buffers */
- in = fd == -1 ? NULL : malloc(CHUNK);
+ in = malloc(CHUNK);
out = malloc(CHUNK);
- if (out == NULL) bye("out of memory", "");
+ if (in == NULL || out == NULL) bye("out of memory", "");
/* compress input file and append to gzip file */
do {
/* get more input */
- len = fd == -1 ? 0 : read(fd, in, CHUNK);
+ len = read(fd, in, CHUNK);
if (len == -1) {
fprintf(stderr,
"gzappend warning: error reading %s, skipping rest ...\n",
@@ -453,7 +455,7 @@ local void gztack(char *name, int gd, z_stream *strm, int last)
/* clean up and return */
free(out);
- if (in != NULL) free(in);
+ free(in);
if (fd > 0) close(fd);
}
@@ -467,11 +469,13 @@ int main(int argc, char **argv)
z_stream strm;
/* ignore command name */
- argv++;
+ argc--; argv++;
/* provide usage if no arguments */
if (*argv == NULL) {
- printf("gzappend 1.1 (4 Nov 2003) Copyright (C) 2003 Mark Adler\n");
+ printf(
+ "gzappend 1.2 (11 Oct 2012) Copyright (C) 2003, 2012 Mark Adler\n"
+ );
printf(
"usage: gzappend [-level] file.gz [ addthis [ andthis ... ]]\n");
return 0;
diff --git a/compat/zlib/examples/gzjoin.c b/compat/zlib/examples/gzjoin.c
index 129347c..89e8098 100644
--- a/compat/zlib/examples/gzjoin.c
+++ b/compat/zlib/examples/gzjoin.c
@@ -1,7 +1,7 @@
/* gzjoin -- command to join gzip files into one gzip file
- Copyright (C) 2004 Mark Adler, all rights reserved
- version 1.0, 11 Dec 2004
+ Copyright (C) 2004, 2005, 2012 Mark Adler, all rights reserved
+ version 1.2, 14 Aug 2012
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
@@ -27,6 +27,7 @@
*
* 1.0 11 Dec 2004 - First version
* 1.1 12 Jun 2005 - Changed ssize_t to long for portability
+ * 1.2 14 Aug 2012 - Clean up for z_const usage
*/
/*
@@ -308,7 +309,7 @@ local void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot,
/* inflate and copy compressed data, clear last-block bit if requested */
len = 0;
zpull(&strm, in);
- start = strm.next_in;
+ start = in->next;
last = start[0] & 1;
if (last && clr)
start[0] &= ~1;
@@ -351,7 +352,7 @@ local void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot,
pos = 0x100 >> pos;
last = strm.next_in[-1] & pos;
if (last && clr)
- strm.next_in[-1] &= ~pos;
+ in->buf[strm.next_in - in->buf - 1] &= ~pos;
}
else {
/* next last-block bit is in next unused byte */
@@ -364,14 +365,14 @@ local void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot,
}
last = strm.next_in[0] & 1;
if (last && clr)
- strm.next_in[0] &= ~1;
+ in->buf[strm.next_in - in->buf] &= ~1;
}
}
}
/* update buffer with unused input */
in->left = strm.avail_in;
- in->next = strm.next_in;
+ in->next = in->buf + (strm.next_in - in->buf);
/* copy used input, write empty blocks to get to byte boundary */
pos = strm.data_type & 7;
diff --git a/compat/zlib/examples/gzlog.c b/compat/zlib/examples/gzlog.c
index d70aaca..922f878 100644
--- a/compat/zlib/examples/gzlog.c
+++ b/compat/zlib/examples/gzlog.c
@@ -1,8 +1,8 @@
/*
* gzlog.c
- * Copyright (C) 2004, 2008 Mark Adler, all rights reserved
+ * Copyright (C) 2004, 2008, 2012 Mark Adler, all rights reserved
* For conditions of distribution and use, see copyright notice in gzlog.h
- * version 2.0, 25 Apr 2008
+ * version 2.2, 14 Aug 2012
*/
/*
@@ -750,7 +750,8 @@ local int log_recover(struct log *log, int op)
strcpy(log->end, ".add");
if (stat(log->path, &st) == 0 && st.st_size) {
len = (size_t)(st.st_size);
- if (len != st.st_size || (data = malloc(st.st_size)) == NULL) {
+ if ((off_t)len != st.st_size ||
+ (data = malloc(st.st_size)) == NULL) {
log_log(log, op, "allocation failure");
return -2;
}
@@ -758,7 +759,7 @@ local int log_recover(struct log *log, int op)
log_log(log, op, ".add file read failure");
return -1;
}
- ret = read(fd, data, len) != len;
+ ret = (size_t)read(fd, data, len) != len;
close(fd);
if (ret) {
log_log(log, op, ".add file read failure");
@@ -913,7 +914,7 @@ int gzlog_compress(gzlog *logd)
struct log *log = logd;
/* check arguments */
- if (log == NULL || strcmp(log->id, LOGID) || len < 0)
+ if (log == NULL || strcmp(log->id, LOGID))
return -3;
/* see if we lost the lock -- if so get it again and reload the extra
@@ -952,7 +953,7 @@ int gzlog_compress(gzlog *logd)
fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd < 0)
break;
- ret = write(fd, data, len) != len;
+ ret = (size_t)write(fd, data, len) != len;
if (ret | close(fd))
break;
log_touch(log);
@@ -963,7 +964,7 @@ int gzlog_compress(gzlog *logd)
if (fd < 0)
break;
next = DICT > len ? len : DICT;
- ret = write(fd, (char *)data + len - next, next) != next;
+ ret = (size_t)write(fd, (char *)data + len - next, next) != next;
if (ret | close(fd))
break;
log_touch(log);
@@ -997,9 +998,9 @@ int gzlog_write(gzlog *logd, void *data, size_t len)
struct log *log = logd;
/* check arguments */
- if (log == NULL || strcmp(log->id, LOGID) || len < 0)
+ if (log == NULL || strcmp(log->id, LOGID))
return -3;
- if (data == NULL || len == 0)
+ if (data == NULL || len <= 0)
return 0;
/* see if we lost the lock -- if so get it again and reload the extra
@@ -1013,7 +1014,7 @@ int gzlog_write(gzlog *logd, void *data, size_t len)
fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd < 0)
return -1;
- ret = write(fd, data, len) != len;
+ ret = (size_t)write(fd, data, len) != len;
if (ret | close(fd))
return -1;
log_touch(log);
diff --git a/compat/zlib/examples/gzlog.h b/compat/zlib/examples/gzlog.h
index c461426..86f0cec 100644
--- a/compat/zlib/examples/gzlog.h
+++ b/compat/zlib/examples/gzlog.h
@@ -1,6 +1,6 @@
/* gzlog.h
- Copyright (C) 2004, 2008 Mark Adler, all rights reserved
- version 2.0, 25 Apr 2008
+ Copyright (C) 2004, 2008, 2012 Mark Adler, all rights reserved
+ version 2.2, 14 Aug 2012
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
@@ -27,6 +27,8 @@
Interface changed slightly in that now path is a prefix
Compression now occurs as needed during gzlog_write()
gzlog_write() now always leaves the log file as valid gzip
+ 2.1 8 Jul 2012 Fix argument checks in gzlog_compress() and gzlog_write()
+ 2.2 14 Aug 2012 Clean up signed comparisons
*/
/*
diff --git a/compat/zlib/examples/zran.c b/compat/zlib/examples/zran.c
index 617a130..278f9ad 100644
--- a/compat/zlib/examples/zran.c
+++ b/compat/zlib/examples/zran.c
@@ -1,7 +1,12 @@
/* zran.c -- example of zlib/gzip stream indexing and random access
- * Copyright (C) 2005 Mark Adler
+ * Copyright (C) 2005, 2012 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
- Version 1.0 29 May 2005 Mark Adler */
+ Version 1.1 29 Sep 2012 Mark Adler */
+
+/* Version History:
+ 1.0 29 May 2005 First version
+ 1.1 29 Sep 2012 Fix memory reallocation error
+ */
/* Illustrate the use of Z_BLOCK, inflatePrime(), and inflateSetDictionary()
for random access of a compressed file. A file containing a zlib or gzip
@@ -221,7 +226,7 @@ local int build_index(FILE *in, off_t span, struct access **built)
/* clean up and return index (release unused entries in list) */
(void)inflateEnd(&strm);
- index = realloc(index, sizeof(struct point) * index->have);
+ index->list = realloc(index->list, sizeof(struct point) * index->have);
index->size = index->have;
*built = index;
return index->size;
diff --git a/compat/zlib/gzguts.h b/compat/zlib/gzguts.h
index 0f8fb79..d87659d 100644
--- a/compat/zlib/gzguts.h
+++ b/compat/zlib/gzguts.h
@@ -1,5 +1,5 @@
/* gzguts.h -- zlib internal header definitions for gz* operations
- * Copyright (C) 2004, 2005, 2010 Mark Adler
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -12,7 +12,7 @@
# endif
#endif
-#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ)
+#ifdef HAVE_HIDDEN
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
#else
# define ZLIB_INTERNAL
@@ -27,13 +27,80 @@
#endif
#include <fcntl.h>
+#ifdef _WIN32
+# include <stddef.h>
+#endif
+
+#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
+# include <io.h>
+#endif
+
+#ifdef WINAPI_FAMILY
+# define open _open
+# define read _read
+# define write _write
+# define close _close
+#endif
+
#ifdef NO_DEFLATE /* for compatibility with old definition */
# define NO_GZCOMPRESS
#endif
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#if defined(__CYGWIN__)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#ifndef HAVE_VSNPRINTF
+# ifdef MSDOS
+/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+ but for now we just assume it doesn't. */
+# define NO_vsnprintf
+# endif
+# ifdef __TURBOC__
+# define NO_vsnprintf
+# endif
+# ifdef WIN32
+/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+# if !defined(vsnprintf) && !defined(NO_vsnprintf)
+# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
+# define vsnprintf _vsnprintf
+# endif
+# endif
+# endif
+# ifdef __SASC
+# define NO_vsnprintf
+# endif
+# ifdef VMS
+# define NO_vsnprintf
+# endif
+# ifdef __OS400__
+# define NO_vsnprintf
+# endif
+# ifdef __MVS__
+# define NO_vsnprintf
+# endif
+#endif
+
+/* unlike snprintf (which is required in C99, yet still not supported by
+ Microsoft more than a decade later!), _snprintf does not guarantee null
+ termination of the result -- however this is only used in gzlib.c where
+ the result is assured to fit in the space provided */
#ifdef _MSC_VER
-# include <io.h>
-# define vsnprintf _vsnprintf
+# define snprintf _snprintf
#endif
#ifndef local
@@ -52,7 +119,7 @@
# include <windows.h>
# define zstrerror() gz_strwinerror((DWORD)GetLastError())
#else
-# ifdef STDC
+# ifndef NO_STRERROR
# include <errno.h>
# define zstrerror() strerror(errno)
# else
@@ -68,7 +135,15 @@
ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
#endif
-/* default i/o buffer size -- double this for output when reading */
+/* default memLevel */
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+
+/* default i/o buffer size -- double this for output when reading (this and
+ twice this must be able to fit in an unsigned type) */
#define GZBUFSIZE 8192
/* gzip modes, also provide a little integrity check on the passed structure */
@@ -84,23 +159,25 @@
/* internal gzip file state data structure */
typedef struct {
+ /* exposed contents for gzgetc() macro */
+ struct gzFile_s x; /* "x" for exposed */
+ /* x.have: number of bytes available at x.next */
+ /* x.next: next output data to deliver or write */
+ /* x.pos: current position in uncompressed data */
/* used for both reading and writing */
int mode; /* see gzip modes above */
int fd; /* file descriptor */
char *path; /* path or fd for error messages */
- z_off64_t pos; /* current position in uncompressed data */
unsigned size; /* buffer size, zero if not allocated yet */
unsigned want; /* requested buffer size, default is GZBUFSIZE */
unsigned char *in; /* input buffer */
unsigned char *out; /* output buffer (double-sized when reading) */
- unsigned char *next; /* next output data to deliver or write */
+ int direct; /* 0 if processing gzip, 1 if transparent */
/* just for reading */
- unsigned have; /* amount of output data unused at next */
- int eof; /* true if end of input file reached */
- z_off64_t start; /* where the gzip data started, for rewinding */
- z_off64_t raw; /* where the raw data started, for seeking */
int how; /* 0: get header, 1: copy, 2: decompress */
- int direct; /* true if last read direct, false if gzip */
+ z_off64_t start; /* where the gzip data started, for rewinding */
+ int eof; /* true if end of input file reached */
+ int past; /* true if read requested past end */
/* just for writing */
int level; /* compression level */
int strategy; /* compression strategy */
diff --git a/compat/zlib/gzlib.c b/compat/zlib/gzlib.c
index 603e60e..fae202e 100644
--- a/compat/zlib/gzlib.c
+++ b/compat/zlib/gzlib.c
@@ -1,19 +1,23 @@
/* gzlib.c -- zlib functions common to reading and writing gzip files
- * Copyright (C) 2004, 2010 Mark Adler
+ * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "gzguts.h"
+#if defined(_WIN32) && !defined(__BORLANDC__)
+# define LSEEK _lseeki64
+#else
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
# define LSEEK lseek64
#else
# define LSEEK lseek
#endif
+#endif
/* Local functions */
local void gz_reset OF((gz_statep));
-local gzFile gz_open OF((const char *, int, const char *));
+local gzFile gz_open OF((const void *, int, const char *));
#if defined UNDER_CE
@@ -71,28 +75,40 @@ char ZLIB_INTERNAL *gz_strwinerror (error)
local void gz_reset(state)
gz_statep state;
{
+ state->x.have = 0; /* no output data available */
if (state->mode == GZ_READ) { /* for reading ... */
- state->have = 0; /* no output data available */
state->eof = 0; /* not at end of file */
+ state->past = 0; /* have not read past end yet */
state->how = LOOK; /* look for gzip header */
- state->direct = 1; /* default for empty file */
}
state->seek = 0; /* no seek request pending */
gz_error(state, Z_OK, NULL); /* clear error */
- state->pos = 0; /* no uncompressed data yet */
+ state->x.pos = 0; /* no uncompressed data yet */
state->strm.avail_in = 0; /* no input data yet */
}
/* Open a gzip file either by name or file descriptor. */
local gzFile gz_open(path, fd, mode)
- const char *path;
+ const void *path;
int fd;
const char *mode;
{
gz_statep state;
+ size_t len;
+ int oflag;
+#ifdef O_CLOEXEC
+ int cloexec = 0;
+#endif
+#ifdef O_EXCL
+ int exclusive = 0;
+#endif
+
+ /* check input */
+ if (path == NULL)
+ return NULL;
/* allocate gzFile structure to return */
- state = malloc(sizeof(gz_state));
+ state = (gz_statep)malloc(sizeof(gz_state));
if (state == NULL)
return NULL;
state->size = 0; /* no buffers allocated yet */
@@ -103,6 +119,7 @@ local gzFile gz_open(path, fd, mode)
state->mode = GZ_NONE;
state->level = Z_DEFAULT_COMPRESSION;
state->strategy = Z_DEFAULT_STRATEGY;
+ state->direct = 0;
while (*mode) {
if (*mode >= '0' && *mode <= '9')
state->level = *mode - '0';
@@ -124,6 +141,16 @@ local gzFile gz_open(path, fd, mode)
return NULL;
case 'b': /* ignore -- will request binary anyway */
break;
+#ifdef O_CLOEXEC
+ case 'e':
+ cloexec = 1;
+ break;
+#endif
+#ifdef O_EXCL
+ case 'x':
+ exclusive = 1;
+ break;
+#endif
case 'f':
state->strategy = Z_FILTERED;
break;
@@ -135,6 +162,10 @@ local gzFile gz_open(path, fd, mode)
break;
case 'F':
state->strategy = Z_FIXED;
+ break;
+ case 'T':
+ state->direct = 1;
+ break;
default: /* could consider as an error, but just ignore */
;
}
@@ -147,30 +178,71 @@ local gzFile gz_open(path, fd, mode)
return NULL;
}
+ /* can't force transparent read */
+ if (state->mode == GZ_READ) {
+ if (state->direct) {
+ free(state);
+ return NULL;
+ }
+ state->direct = 1; /* for empty file */
+ }
+
/* save the path name for error messages */
- state->path = malloc(strlen(path) + 1);
+#ifdef _WIN32
+ if (fd == -2) {
+ len = wcstombs(NULL, path, 0);
+ if (len == (size_t)-1)
+ len = 0;
+ }
+ else
+#endif
+ len = strlen((const char *)path);
+ state->path = (char *)malloc(len + 1);
if (state->path == NULL) {
free(state);
return NULL;
}
- strcpy(state->path, path);
+#ifdef _WIN32
+ if (fd == -2)
+ if (len)
+ wcstombs(state->path, path, len + 1);
+ else
+ *(state->path) = 0;
+ else
+#endif
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(state->path, len + 1, "%s", (const char *)path);
+#else
+ strcpy(state->path, path);
+#endif
- /* open the file with the appropriate mode (or just use fd) */
- state->fd = fd != -1 ? fd :
- open(path,
+ /* compute the flags for open() */
+ oflag =
#ifdef O_LARGEFILE
- O_LARGEFILE |
+ O_LARGEFILE |
#endif
#ifdef O_BINARY
- O_BINARY |
+ O_BINARY |
+#endif
+#ifdef O_CLOEXEC
+ (cloexec ? O_CLOEXEC : 0) |
+#endif
+ (state->mode == GZ_READ ?
+ O_RDONLY :
+ (O_WRONLY | O_CREAT |
+#ifdef O_EXCL
+ (exclusive ? O_EXCL : 0) |
+#endif
+ (state->mode == GZ_WRITE ?
+ O_TRUNC :
+ O_APPEND)));
+
+ /* open the file with the appropriate flags (or just use fd) */
+ state->fd = fd > -1 ? fd : (
+#ifdef _WIN32
+ fd == -2 ? _wopen(path, oflag, 0666) :
#endif
- (state->mode == GZ_READ ?
- O_RDONLY :
- (O_WRONLY | O_CREAT | (
- state->mode == GZ_WRITE ?
- O_TRUNC :
- O_APPEND))),
- 0666);
+ open((const char *)path, oflag, 0666));
if (state->fd == -1) {
free(state->path);
free(state);
@@ -216,15 +288,29 @@ gzFile ZEXPORT gzdopen(fd, mode)
char *path; /* identifier for error messages */
gzFile gz;
- if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL)
+ if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
return NULL;
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */
+#else
sprintf(path, "<fd:%d>", fd); /* for debugging */
+#endif
gz = gz_open(path, fd, mode);
free(path);
return gz;
}
/* -- see zlib.h -- */
+#ifdef _WIN32
+gzFile ZEXPORT gzopen_w(path, mode)
+ const wchar_t *path;
+ const char *mode;
+{
+ return gz_open(path, -2, mode);
+}
+#endif
+
+/* -- see zlib.h -- */
int ZEXPORT gzbuffer(file, size)
gzFile file;
unsigned size;
@@ -243,8 +329,8 @@ int ZEXPORT gzbuffer(file, size)
return -1;
/* check and set requested size */
- if (size == 0)
- return -1;
+ if (size < 2)
+ size = 2; /* need two bytes to check magic header */
state->want = size;
return 0;
}
@@ -261,7 +347,8 @@ int ZEXPORT gzrewind(file)
state = (gz_statep)file;
/* check that we're reading and that there's no error */
- if (state->mode != GZ_READ || state->err != Z_OK)
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
return -1;
/* back up and start over */
@@ -289,7 +376,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence)
return -1;
/* check that there's no error */
- if (state->err != Z_OK)
+ if (state->err != Z_OK && state->err != Z_BUF_ERROR)
return -1;
/* can only seek from start or relative to current position */
@@ -298,31 +385,32 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence)
/* normalize offset to a SEEK_CUR specification */
if (whence == SEEK_SET)
- offset -= state->pos;
+ offset -= state->x.pos;
else if (state->seek)
offset += state->skip;
state->seek = 0;
/* if within raw area while reading, just go there */
if (state->mode == GZ_READ && state->how == COPY &&
- state->pos + offset >= state->raw) {
- ret = LSEEK(state->fd, offset - state->have, SEEK_CUR);
+ state->x.pos + offset >= 0) {
+ ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
if (ret == -1)
return -1;
- state->have = 0;
+ state->x.have = 0;
state->eof = 0;
+ state->past = 0;
state->seek = 0;
gz_error(state, Z_OK, NULL);
state->strm.avail_in = 0;
- state->pos += offset;
- return state->pos;
+ state->x.pos += offset;
+ return state->x.pos;
}
/* calculate skip amount, rewinding if needed for back seek when reading */
if (offset < 0) {
if (state->mode != GZ_READ) /* writing -- can't go backwards */
return -1;
- offset += state->pos;
+ offset += state->x.pos;
if (offset < 0) /* before start of file! */
return -1;
if (gzrewind(file) == -1) /* rewind, then skip to offset */
@@ -331,11 +419,11 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence)
/* if reading, skip what's in output buffer (one less gzgetc() check) */
if (state->mode == GZ_READ) {
- n = GT_OFF(state->have) || (z_off64_t)state->have > offset ?
- (unsigned)offset : state->have;
- state->have -= n;
- state->next += n;
- state->pos += n;
+ n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
+ (unsigned)offset : state->x.have;
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
offset -= n;
}
@@ -344,7 +432,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence)
state->seek = 1;
state->skip = offset;
}
- return state->pos + offset;
+ return state->x.pos + offset;
}
/* -- see zlib.h -- */
@@ -373,7 +461,7 @@ z_off64_t ZEXPORT gztell64(file)
return -1;
/* return position */
- return state->pos + (state->seek ? state->skip : 0);
+ return state->x.pos + (state->seek ? state->skip : 0);
}
/* -- see zlib.h -- */
@@ -433,8 +521,7 @@ int ZEXPORT gzeof(file)
return 0;
/* return end-of-file state */
- return state->mode == GZ_READ ?
- (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0;
+ return state->mode == GZ_READ ? state->past : 0;
}
/* -- see zlib.h -- */
@@ -454,7 +541,8 @@ const char * ZEXPORT gzerror(file, errnum)
/* return error information */
if (errnum != NULL)
*errnum = state->err;
- return state->msg == NULL ? "" : state->msg;
+ return state->err == Z_MEM_ERROR ? "out of memory" :
+ (state->msg == NULL ? "" : state->msg);
}
/* -- see zlib.h -- */
@@ -471,8 +559,10 @@ void ZEXPORT gzclearerr(file)
return;
/* clear error and end-of-file */
- if (state->mode == GZ_READ)
+ if (state->mode == GZ_READ) {
state->eof = 0;
+ state->past = 0;
+ }
gz_error(state, Z_OK, NULL);
}
@@ -494,26 +584,33 @@ void ZLIB_INTERNAL gz_error(state, err, msg)
state->msg = NULL;
}
+ /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
+ if (err != Z_OK && err != Z_BUF_ERROR)
+ state->x.have = 0;
+
/* set error code, and if no message, then done */
state->err = err;
if (msg == NULL)
return;
- /* for an out of memory error, save as static string */
- if (err == Z_MEM_ERROR) {
- state->msg = (char *)msg;
+ /* for an out of memory error, return literal string when requested */
+ if (err == Z_MEM_ERROR)
return;
- }
/* construct error message with path */
- if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) {
+ if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
+ NULL) {
state->err = Z_MEM_ERROR;
- state->msg = (char *)"out of memory";
return;
}
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
+ "%s%s%s", state->path, ": ", msg);
+#else
strcpy(state->msg, state->path);
strcat(state->msg, ": ");
strcat(state->msg, msg);
+#endif
return;
}
diff --git a/compat/zlib/gzread.c b/compat/zlib/gzread.c
index 548201a..bf4538e 100644
--- a/compat/zlib/gzread.c
+++ b/compat/zlib/gzread.c
@@ -1,5 +1,5 @@
/* gzread.c -- zlib functions for reading gzip files
- * Copyright (C) 2004, 2005, 2010 Mark Adler
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -8,10 +8,9 @@
/* Local functions */
local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
local int gz_avail OF((gz_statep));
-local int gz_next4 OF((gz_statep, unsigned long *));
-local int gz_head OF((gz_statep));
+local int gz_look OF((gz_statep));
local int gz_decomp OF((gz_statep));
-local int gz_make OF((gz_statep));
+local int gz_fetch OF((gz_statep));
local int gz_skip OF((gz_statep, z_off64_t));
/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
@@ -46,73 +45,54 @@ local int gz_load(state, buf, len, have)
error, 0 otherwise. Note that the eof flag is set when the end of the input
file is reached, even though there may be unused data in the buffer. Once
that data has been used, no more attempts will be made to read the file.
- gz_avail() assumes that strm->avail_in == 0. */
+ If strm->avail_in != 0, then the current data is moved to the beginning of
+ the input buffer, and then the remainder of the buffer is loaded with the
+ available data from the input file. */
local int gz_avail(state)
gz_statep state;
{
+ unsigned got;
z_streamp strm = &(state->strm);
- if (state->err != Z_OK)
+ if (state->err != Z_OK && state->err != Z_BUF_ERROR)
return -1;
if (state->eof == 0) {
- if (gz_load(state, state->in, state->size,
- (unsigned *)&(strm->avail_in)) == -1)
+ if (strm->avail_in) { /* copy what's there to the start */
+ unsigned char *p = state->in;
+ unsigned const char *q = strm->next_in;
+ unsigned n = strm->avail_in;
+ do {
+ *p++ = *q++;
+ } while (--n);
+ }
+ if (gz_load(state, state->in + strm->avail_in,
+ state->size - strm->avail_in, &got) == -1)
return -1;
+ strm->avail_in += got;
strm->next_in = state->in;
}
return 0;
}
-/* Get next byte from input, or -1 if end or error. */
-#define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \
- (strm->avail_in == 0 ? -1 : \
- (strm->avail_in--, *(strm->next_in)++)))
-
-/* Get a four-byte little-endian integer and return 0 on success and the value
- in *ret. Otherwise -1 is returned and *ret is not modified. */
-local int gz_next4(state, ret)
- gz_statep state;
- unsigned long *ret;
-{
- int ch;
- unsigned long val;
- z_streamp strm = &(state->strm);
-
- val = NEXT();
- val += (unsigned)NEXT() << 8;
- val += (unsigned long)NEXT() << 16;
- ch = NEXT();
- if (ch == -1)
- return -1;
- val += (unsigned long)ch << 24;
- *ret = val;
- return 0;
-}
-
-/* Look for gzip header, set up for inflate or copy. state->have must be zero.
+/* Look for gzip header, set up for inflate or copy. state->x.have must be 0.
If this is the first time in, allocate required memory. state->how will be
left unchanged if there is no more input data available, will be set to COPY
if there is no gzip header and direct copying will be performed, or it will
- be set to GZIP for decompression, and the gzip header will be skipped so
- that the next available input data is the raw deflate stream. If direct
- copying, then leftover input data from the input buffer will be copied to
- the output buffer. In that case, all further file reads will be directly to
- either the output buffer or a user buffer. If decompressing, the inflate
- state and the check value will be initialized. gz_head() will return 0 on
- success or -1 on failure. Failures may include read errors or gzip header
- errors. */
-local int gz_head(state)
+ be set to GZIP for decompression. If direct copying, then leftover input
+ data from the input buffer will be copied to the output buffer. In that
+ case, all further file reads will be directly to either the output buffer or
+ a user buffer. If decompressing, the inflate state will be initialized.
+ gz_look() will return 0 on success or -1 on failure. */
+local int gz_look(state)
gz_statep state;
{
z_streamp strm = &(state->strm);
- int flags;
- unsigned len;
/* allocate read buffers and inflate memory */
if (state->size == 0) {
/* allocate buffers */
- state->in = malloc(state->want);
- state->out = malloc(state->want << 1);
+ state->in = (unsigned char *)malloc(state->want);
+ state->out = (unsigned char *)malloc(state->want << 1);
if (state->in == NULL || state->out == NULL) {
if (state->out != NULL)
free(state->out);
@@ -129,7 +109,7 @@ local int gz_head(state)
state->strm.opaque = Z_NULL;
state->strm.avail_in = 0;
state->strm.next_in = Z_NULL;
- if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */
+ if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */
free(state->out);
free(state->in);
state->size = 0;
@@ -138,83 +118,45 @@ local int gz_head(state)
}
}
- /* get some data in the input buffer */
- if (strm->avail_in == 0) {
+ /* get at least the magic bytes in the input buffer */
+ if (strm->avail_in < 2) {
if (gz_avail(state) == -1)
return -1;
if (strm->avail_in == 0)
return 0;
}
- /* look for the gzip magic header bytes 31 and 139 */
- if (strm->next_in[0] == 31) {
- strm->avail_in--;
- strm->next_in++;
- if (strm->avail_in == 0 && gz_avail(state) == -1)
- return -1;
- if (strm->avail_in && strm->next_in[0] == 139) {
- /* we have a gzip header, woo hoo! */
- strm->avail_in--;
- strm->next_in++;
-
- /* skip rest of header */
- if (NEXT() != 8) { /* compression method */
- gz_error(state, Z_DATA_ERROR, "unknown compression method");
- return -1;
- }
- flags = NEXT();
- if (flags & 0xe0) { /* reserved flag bits */
- gz_error(state, Z_DATA_ERROR, "unknown header flags set");
- return -1;
- }
- NEXT(); /* modification time */
- NEXT();
- NEXT();
- NEXT();
- NEXT(); /* extra flags */
- NEXT(); /* operating system */
- if (flags & 4) { /* extra field */
- len = (unsigned)NEXT();
- len += (unsigned)NEXT() << 8;
- while (len--)
- if (NEXT() < 0)
- break;
- }
- if (flags & 8) /* file name */
- while (NEXT() > 0)
- ;
- if (flags & 16) /* comment */
- while (NEXT() > 0)
- ;
- if (flags & 2) { /* header crc */
- NEXT();
- NEXT();
- }
- /* an unexpected end of file is not checked for here -- it will be
- noticed on the first request for uncompressed data */
-
- /* set up for decompression */
- inflateReset(strm);
- strm->adler = crc32(0L, Z_NULL, 0);
- state->how = GZIP;
- state->direct = 0;
- return 0;
- }
- else {
- /* not a gzip file -- save first byte (31) and fall to raw i/o */
- state->out[0] = 31;
- state->have = 1;
- }
+ /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
+ a logical dilemma here when considering the case of a partially written
+ gzip file, to wit, if a single 31 byte is written, then we cannot tell
+ whether this is a single-byte file, or just a partially written gzip
+ file -- for here we assume that if a gzip file is being written, then
+ the header will be written in a single operation, so that reading a
+ single byte is sufficient indication that it is not a gzip file) */
+ if (strm->avail_in > 1 &&
+ strm->next_in[0] == 31 && strm->next_in[1] == 139) {
+ inflateReset(strm);
+ state->how = GZIP;
+ state->direct = 0;
+ return 0;
+ }
+
+ /* no gzip header -- if we were decoding gzip before, then this is trailing
+ garbage. Ignore the trailing garbage and finish. */
+ if (state->direct == 0) {
+ strm->avail_in = 0;
+ state->eof = 1;
+ state->x.have = 0;
+ return 0;
}
- /* doing raw i/o, save start of raw data for seeking, copy any leftover
- input to output -- this assumes that the output buffer is larger than
- the input buffer, which also assures space for gzungetc() */
- state->raw = state->pos;
- state->next = state->out;
+ /* doing raw i/o, copy any leftover input to output -- this assumes that
+ the output buffer is larger than the input buffer, which also assures
+ space for gzungetc() */
+ state->x.next = state->out;
if (strm->avail_in) {
- memcpy(state->next + state->have, strm->next_in, strm->avail_in);
- state->have += strm->avail_in;
+ memcpy(state->x.next, strm->next_in, strm->avail_in);
+ state->x.have = strm->avail_in;
strm->avail_in = 0;
}
state->how = COPY;
@@ -223,19 +165,15 @@ local int gz_head(state)
}
/* Decompress from input to the provided next_out and avail_out in the state.
- If the end of the compressed data is reached, then verify the gzip trailer
- check value and length (modulo 2^32). state->have and state->next are set
- to point to the just decompressed data, and the crc is updated. If the
- trailer is verified, state->how is reset to LOOK to look for the next gzip
- stream or raw data, once state->have is depleted. Returns 0 on success, -1
- on failure. Failures may include invalid compressed data or a failed gzip
- trailer verification. */
+ On return, state->x.have and state->x.next point to the just decompressed
+ data. If the gzip stream completes, state->how is reset to LOOK to look for
+ the next gzip stream or raw data, once state->x.have is depleted. Returns 0
+ on success, -1 on failure. */
local int gz_decomp(state)
gz_statep state;
{
- int ret;
+ int ret = Z_OK;
unsigned had;
- unsigned long crc, len;
z_streamp strm = &(state->strm);
/* fill output buffer up to end of deflate stream */
@@ -245,15 +183,15 @@ local int gz_decomp(state)
if (strm->avail_in == 0 && gz_avail(state) == -1)
return -1;
if (strm->avail_in == 0) {
- gz_error(state, Z_DATA_ERROR, "unexpected end of file");
- return -1;
+ gz_error(state, Z_BUF_ERROR, "unexpected end of file");
+ break;
}
/* decompress and handle errors */
ret = inflate(strm, Z_NO_FLUSH);
if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
gz_error(state, Z_STREAM_ERROR,
- "internal error: inflate stream corrupt");
+ "internal error: inflate stream corrupt");
return -1;
}
if (ret == Z_MEM_ERROR) {
@@ -262,67 +200,55 @@ local int gz_decomp(state)
}
if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
gz_error(state, Z_DATA_ERROR,
- strm->msg == NULL ? "compressed data error" : strm->msg);
+ strm->msg == NULL ? "compressed data error" : strm->msg);
return -1;
}
} while (strm->avail_out && ret != Z_STREAM_END);
- /* update available output and crc check value */
- state->have = had - strm->avail_out;
- state->next = strm->next_out - state->have;
- strm->adler = crc32(strm->adler, state->next, state->have);
+ /* update available output */
+ state->x.have = had - strm->avail_out;
+ state->x.next = strm->next_out - state->x.have;
- /* check gzip trailer if at end of deflate stream */
- if (ret == Z_STREAM_END) {
- if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) {
- gz_error(state, Z_DATA_ERROR, "unexpected end of file");
- return -1;
- }
- if (crc != strm->adler) {
- gz_error(state, Z_DATA_ERROR, "incorrect data check");
- return -1;
- }
- if (len != (strm->total_out & 0xffffffffL)) {
- gz_error(state, Z_DATA_ERROR, "incorrect length check");
- return -1;
- }
- state->how = LOOK; /* ready for next stream, once have is 0 (leave
- state->direct unchanged to remember how) */
- }
+ /* if the gzip stream completed successfully, look for another */
+ if (ret == Z_STREAM_END)
+ state->how = LOOK;
/* good decompression */
return 0;
}
-/* Make data and put in the output buffer. Assumes that state->have == 0.
+/* Fetch data and put it in the output buffer. Assumes state->x.have is 0.
Data is either copied from the input file or decompressed from the input
file depending on state->how. If state->how is LOOK, then a gzip header is
- looked for (and skipped if found) to determine wither to copy or decompress.
- Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY
- or GZIP unless the end of the input file has been reached and all data has
- been processed. */
-local int gz_make(state)
+ looked for to determine whether to copy or decompress. Returns -1 on error,
+ otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the
+ end of the input file has been reached and all data has been processed. */
+local int gz_fetch(state)
gz_statep state;
{
z_streamp strm = &(state->strm);
- if (state->how == LOOK) { /* look for gzip header */
- if (gz_head(state) == -1)
- return -1;
- if (state->have) /* got some data from gz_head() */
+ do {
+ switch(state->how) {
+ case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */
+ if (gz_look(state) == -1)
+ return -1;
+ if (state->how == LOOK)
+ return 0;
+ break;
+ case COPY: /* -> COPY */
+ if (gz_load(state, state->out, state->size << 1, &(state->x.have))
+ == -1)
+ return -1;
+ state->x.next = state->out;
return 0;
- }
- if (state->how == COPY) { /* straight copy */
- if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1)
- return -1;
- state->next = state->out;
- }
- else if (state->how == GZIP) { /* decompress */
- strm->avail_out = state->size << 1;
- strm->next_out = state->out;
- if (gz_decomp(state) == -1)
- return -1;
- }
+ case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */
+ strm->avail_out = state->size << 1;
+ strm->next_out = state->out;
+ if (gz_decomp(state) == -1)
+ return -1;
+ }
+ } while (state->x.have == 0 && (!state->eof || strm->avail_in));
return 0;
}
@@ -336,12 +262,12 @@ local int gz_skip(state, len)
/* skip over len bytes or reach end-of-file, whichever comes first */
while (len)
/* skip over whatever is in output buffer */
- if (state->have) {
- n = GT_OFF(state->have) || (z_off64_t)state->have > len ?
- (unsigned)len : state->have;
- state->have -= n;
- state->next += n;
- state->pos += n;
+ if (state->x.have) {
+ n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
+ (unsigned)len : state->x.have;
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
len -= n;
}
@@ -352,7 +278,7 @@ local int gz_skip(state, len)
/* need more data to skip -- load up output buffer */
else {
/* get more output, looking for header if required */
- if (gz_make(state) == -1)
+ if (gz_fetch(state) == -1)
return -1;
}
return 0;
@@ -374,14 +300,15 @@ int ZEXPORT gzread(file, buf, len)
state = (gz_statep)file;
strm = &(state->strm);
- /* check that we're reading and that there's no error */
- if (state->mode != GZ_READ || state->err != Z_OK)
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
return -1;
/* since an int is returned, make sure len fits in one, otherwise return
with an error (this avoids the flaw in the interface) */
if ((int)len < 0) {
- gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
+ gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
return -1;
}
@@ -400,49 +327,51 @@ int ZEXPORT gzread(file, buf, len)
got = 0;
do {
/* first just try copying data from the output buffer */
- if (state->have) {
- n = state->have > len ? len : state->have;
- memcpy(buf, state->next, n);
- state->next += n;
- state->have -= n;
+ if (state->x.have) {
+ n = state->x.have > len ? len : state->x.have;
+ memcpy(buf, state->x.next, n);
+ state->x.next += n;
+ state->x.have -= n;
}
/* output buffer empty -- return if we're at the end of the input */
- else if (state->eof && strm->avail_in == 0)
+ else if (state->eof && strm->avail_in == 0) {
+ state->past = 1; /* tried to read past end */
break;
+ }
/* need output data -- for small len or new stream load up our output
buffer */
else if (state->how == LOOK || len < (state->size << 1)) {
/* get more output, looking for header if required */
- if (gz_make(state) == -1)
+ if (gz_fetch(state) == -1)
return -1;
- continue; /* no progress yet -- go back to memcpy() above */
+ continue; /* no progress yet -- go back to copy above */
/* the copy above assures that we will leave with space in the
output buffer, allowing at least one gzungetc() to succeed */
}
/* large len -- read directly into user buffer */
else if (state->how == COPY) { /* read directly */
- if (gz_load(state, buf, len, &n) == -1)
+ if (gz_load(state, (unsigned char *)buf, len, &n) == -1)
return -1;
}
/* large len -- decompress directly into user buffer */
else { /* state->how == GZIP */
strm->avail_out = len;
- strm->next_out = buf;
+ strm->next_out = (unsigned char *)buf;
if (gz_decomp(state) == -1)
return -1;
- n = state->have;
- state->have = 0;
+ n = state->x.have;
+ state->x.have = 0;
}
/* update progress */
len -= n;
buf = (char *)buf + n;
got += n;
- state->pos += n;
+ state->x.pos += n;
} while (len);
/* return number of bytes read into user buffer (will fit in int) */
@@ -450,6 +379,11 @@ int ZEXPORT gzread(file, buf, len)
}
/* -- see zlib.h -- */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+#else
+# undef gzgetc
+#endif
int ZEXPORT gzgetc(file)
gzFile file;
{
@@ -462,15 +396,16 @@ int ZEXPORT gzgetc(file)
return -1;
state = (gz_statep)file;
- /* check that we're reading and that there's no error */
- if (state->mode != GZ_READ || state->err != Z_OK)
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
return -1;
/* try output buffer (no need to check for skip request) */
- if (state->have) {
- state->have--;
- state->pos++;
- return *(state->next)++;
+ if (state->x.have) {
+ state->x.have--;
+ state->x.pos++;
+ return *(state->x.next)++;
}
/* nothing there -- try gzread() */
@@ -478,6 +413,12 @@ int ZEXPORT gzgetc(file)
return ret < 1 ? -1 : buf[0];
}
+int ZEXPORT gzgetc_(file)
+gzFile file;
+{
+ return gzgetc(file);
+}
+
/* -- see zlib.h -- */
int ZEXPORT gzungetc(c, file)
int c;
@@ -490,8 +431,9 @@ int ZEXPORT gzungetc(c, file)
return -1;
state = (gz_statep)file;
- /* check that we're reading and that there's no error */
- if (state->mode != GZ_READ || state->err != Z_OK)
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
return -1;
/* process a skip request */
@@ -506,32 +448,34 @@ int ZEXPORT gzungetc(c, file)
return -1;
/* if output buffer empty, put byte at end (allows more pushing) */
- if (state->have == 0) {
- state->have = 1;
- state->next = state->out + (state->size << 1) - 1;
- state->next[0] = c;
- state->pos--;
+ if (state->x.have == 0) {
+ state->x.have = 1;
+ state->x.next = state->out + (state->size << 1) - 1;
+ state->x.next[0] = c;
+ state->x.pos--;
+ state->past = 0;
return c;
}
/* if no room, give up (must have already done a gzungetc()) */
- if (state->have == (state->size << 1)) {
- gz_error(state, Z_BUF_ERROR, "out of room to push characters");
+ if (state->x.have == (state->size << 1)) {
+ gz_error(state, Z_DATA_ERROR, "out of room to push characters");
return -1;
}
/* slide output data if needed and insert byte before existing data */
- if (state->next == state->out) {
- unsigned char *src = state->out + state->have;
+ if (state->x.next == state->out) {
+ unsigned char *src = state->out + state->x.have;
unsigned char *dest = state->out + (state->size << 1);
while (src > state->out)
*--dest = *--src;
- state->next = dest;
+ state->x.next = dest;
}
- state->have++;
- state->next--;
- state->next[0] = c;
- state->pos--;
+ state->x.have++;
+ state->x.next--;
+ state->x.next[0] = c;
+ state->x.pos--;
+ state->past = 0;
return c;
}
@@ -551,8 +495,9 @@ char * ZEXPORT gzgets(file, buf, len)
return NULL;
state = (gz_statep)file;
- /* check that we're reading and that there's no error */
- if (state->mode != GZ_READ || state->err != Z_OK)
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
return NULL;
/* process a skip request */
@@ -569,32 +514,31 @@ char * ZEXPORT gzgets(file, buf, len)
left = (unsigned)len - 1;
if (left) do {
/* assure that something is in the output buffer */
- if (state->have == 0) {
- if (gz_make(state) == -1)
- return NULL; /* error */
- if (state->have == 0) { /* end of file */
- if (buf == str) /* got bupkus */
- return NULL;
- break; /* got something -- return it */
- }
+ if (state->x.have == 0 && gz_fetch(state) == -1)
+ return NULL; /* error */
+ if (state->x.have == 0) { /* end of file */
+ state->past = 1; /* read past end */
+ break; /* return what we have */
}
/* look for end-of-line in current output buffer */
- n = state->have > left ? left : state->have;
- eol = memchr(state->next, '\n', n);
+ n = state->x.have > left ? left : state->x.have;
+ eol = (unsigned char *)memchr(state->x.next, '\n', n);
if (eol != NULL)
- n = (unsigned)(eol - state->next) + 1;
+ n = (unsigned)(eol - state->x.next) + 1;
/* copy through end-of-line, or remainder if not found */
- memcpy(buf, state->next, n);
- state->have -= n;
- state->next += n;
- state->pos += n;
+ memcpy(buf, state->x.next, n);
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
left -= n;
buf += n;
} while (left && eol == NULL);
- /* found end-of-line or out of space -- terminate string and return it */
+ /* return terminated string, or if nothing, end of file */
+ if (buf == str)
+ return NULL;
buf[0] = 0;
return str;
}
@@ -610,16 +554,12 @@ int ZEXPORT gzdirect(file)
return 0;
state = (gz_statep)file;
- /* check that we're reading */
- if (state->mode != GZ_READ)
- return 0;
-
/* if the state is not known, but we can find out, then do so (this is
mainly for right after a gzopen() or gzdopen()) */
- if (state->how == LOOK && state->have == 0)
- (void)gz_head(state);
+ if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
+ (void)gz_look(state);
- /* return 1 if reading direct, 0 if decompressing a gzip stream */
+ /* return 1 if transparent, 0 if processing a gzip stream */
return state->direct;
}
@@ -627,7 +567,7 @@ int ZEXPORT gzdirect(file)
int ZEXPORT gzclose_r(file)
gzFile file;
{
- int ret;
+ int ret, err;
gz_statep state;
/* get internal structure */
@@ -645,9 +585,10 @@ int ZEXPORT gzclose_r(file)
free(state->out);
free(state->in);
}
+ err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
gz_error(state, Z_OK, NULL);
free(state->path);
ret = close(state->fd);
free(state);
- return ret ? Z_ERRNO : Z_OK;
+ return ret ? Z_ERRNO : err;
}
diff --git a/compat/zlib/gzwrite.c b/compat/zlib/gzwrite.c
index e8defc6..aa767fb 100644
--- a/compat/zlib/gzwrite.c
+++ b/compat/zlib/gzwrite.c
@@ -1,5 +1,5 @@
/* gzwrite.c -- zlib functions for writing gzip files
- * Copyright (C) 2004, 2005, 2010 Mark Adler
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -18,44 +18,55 @@ local int gz_init(state)
int ret;
z_streamp strm = &(state->strm);
- /* allocate input and output buffers */
- state->in = malloc(state->want);
- state->out = malloc(state->want);
- if (state->in == NULL || state->out == NULL) {
- if (state->out != NULL)
- free(state->out);
- if (state->in != NULL)
- free(state->in);
+ /* allocate input buffer */
+ state->in = (unsigned char *)malloc(state->want);
+ if (state->in == NULL) {
gz_error(state, Z_MEM_ERROR, "out of memory");
return -1;
}
- /* allocate deflate memory, set up for gzip compression */
- strm->zalloc = Z_NULL;
- strm->zfree = Z_NULL;
- strm->opaque = Z_NULL;
- ret = deflateInit2(strm, state->level, Z_DEFLATED,
- 15 + 16, 8, state->strategy);
- if (ret != Z_OK) {
- free(state->in);
- gz_error(state, Z_MEM_ERROR, "out of memory");
- return -1;
+ /* only need output buffer and deflate state if compressing */
+ if (!state->direct) {
+ /* allocate output buffer */
+ state->out = (unsigned char *)malloc(state->want);
+ if (state->out == NULL) {
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+
+ /* allocate deflate memory, set up for gzip compression */
+ strm->zalloc = Z_NULL;
+ strm->zfree = Z_NULL;
+ strm->opaque = Z_NULL;
+ ret = deflateInit2(strm, state->level, Z_DEFLATED,
+ MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
+ if (ret != Z_OK) {
+ free(state->out);
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
}
/* mark state as initialized */
state->size = state->want;
- /* initialize write buffer */
- strm->avail_out = state->size;
- strm->next_out = state->out;
- state->next = strm->next_out;
+ /* initialize write buffer if compressing */
+ if (!state->direct) {
+ strm->avail_out = state->size;
+ strm->next_out = state->out;
+ state->x.next = strm->next_out;
+ }
return 0;
}
/* Compress whatever is at avail_in and next_in and write to the output file.
Return -1 if there is an error writing to the output file, otherwise 0.
flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
- then the deflate() state is reset to start a new gzip stream. */
+ then the deflate() state is reset to start a new gzip stream. If gz->direct
+ is true, then simply write to the output file without compressing, and
+ ignore flush. */
local int gz_comp(state, flush)
gz_statep state;
int flush;
@@ -68,6 +79,17 @@ local int gz_comp(state, flush)
if (state->size == 0 && gz_init(state) == -1)
return -1;
+ /* write directly if requested */
+ if (state->direct) {
+ got = write(state->fd, strm->next_in, strm->avail_in);
+ if (got < 0 || (unsigned)got != strm->avail_in) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ strm->avail_in = 0;
+ return 0;
+ }
+
/* run deflate() on provided input until it produces no more output */
ret = Z_OK;
do {
@@ -75,8 +97,8 @@ local int gz_comp(state, flush)
doing Z_FINISH then don't write until we get to Z_STREAM_END */
if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
(flush != Z_FINISH || ret == Z_STREAM_END))) {
- have = (unsigned)(strm->next_out - state->next);
- if (have && ((got = write(state->fd, state->next, have)) < 0 ||
+ have = (unsigned)(strm->next_out - state->x.next);
+ if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
(unsigned)got != have)) {
gz_error(state, Z_ERRNO, zstrerror());
return -1;
@@ -85,7 +107,7 @@ local int gz_comp(state, flush)
strm->avail_out = state->size;
strm->next_out = state->out;
}
- state->next = strm->next_out;
+ state->x.next = strm->next_out;
}
/* compress */
@@ -131,7 +153,7 @@ local int gz_zero(state, len)
}
strm->avail_in = n;
strm->next_in = state->in;
- state->pos += n;
+ state->x.pos += n;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return -1;
len -= n;
@@ -146,7 +168,6 @@ int ZEXPORT gzwrite(file, buf, len)
unsigned len;
{
unsigned put = len;
- unsigned n;
gz_statep state;
z_streamp strm;
@@ -163,7 +184,7 @@ int ZEXPORT gzwrite(file, buf, len)
/* since an int is returned, make sure len fits in one, otherwise return
with an error (this avoids the flaw in the interface) */
if ((int)len < 0) {
- gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
+ gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
return 0;
}
@@ -186,16 +207,19 @@ int ZEXPORT gzwrite(file, buf, len)
if (len < state->size) {
/* copy to input buffer, compress when full */
do {
+ unsigned have, copy;
+
if (strm->avail_in == 0)
strm->next_in = state->in;
- n = state->size - strm->avail_in;
- if (n > len)
- n = len;
- memcpy(strm->next_in + strm->avail_in, buf, n);
- strm->avail_in += n;
- state->pos += n;
- buf = (char *)buf + n;
- len -= n;
+ have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
+ copy = state->size - have;
+ if (copy > len)
+ copy = len;
+ memcpy(state->in + have, buf, copy);
+ strm->avail_in += copy;
+ state->x.pos += copy;
+ buf = (const char *)buf + copy;
+ len -= copy;
if (len && gz_comp(state, Z_NO_FLUSH) == -1)
return 0;
} while (len);
@@ -207,8 +231,8 @@ int ZEXPORT gzwrite(file, buf, len)
/* directly compress user buffer to file */
strm->avail_in = len;
- strm->next_in = (voidp)buf;
- state->pos += len;
+ strm->next_in = (z_const Bytef *)buf;
+ state->x.pos += len;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return 0;
}
@@ -222,6 +246,7 @@ int ZEXPORT gzputc(file, c)
gzFile file;
int c;
{
+ unsigned have;
unsigned char buf[1];
gz_statep state;
z_streamp strm;
@@ -245,19 +270,23 @@ int ZEXPORT gzputc(file, c)
/* try writing to input buffer for speed (state->size == 0 if buffer not
initialized) */
- if (strm->avail_in < state->size) {
+ if (state->size) {
if (strm->avail_in == 0)
strm->next_in = state->in;
- strm->next_in[strm->avail_in++] = c;
- state->pos++;
- return c;
+ have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
+ if (have < state->size) {
+ state->in[have] = c;
+ strm->avail_in++;
+ state->x.pos++;
+ return c & 0xff;
+ }
}
/* no room in buffer or not initialized, use gz_write() */
buf[0] = c;
if (gzwrite(file, buf, 1) != 1)
return -1;
- return c;
+ return c & 0xff;
}
/* -- see zlib.h -- */
@@ -274,16 +303,15 @@ int ZEXPORT gzputs(file, str)
return ret == 0 && len != 0 ? -1 : ret;
}
-#ifdef STDC
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
#include <stdarg.h>
/* -- see zlib.h -- */
-int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
+int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
{
int size, len;
gz_statep state;
z_streamp strm;
- va_list va;
/* get internal structure */
if (file == NULL)
@@ -313,25 +341,20 @@ int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
/* do the printf() into the input buffer, put length in len */
size = (int)(state->size);
state->in[size - 1] = 0;
- va_start(va, format);
#ifdef NO_vsnprintf
# ifdef HAS_vsprintf_void
- (void)vsprintf(state->in, format, va);
- va_end(va);
+ (void)vsprintf((char *)(state->in), format, va);
for (len = 0; len < size; len++)
if (state->in[len] == 0) break;
# else
- len = vsprintf(state->in, format, va);
- va_end(va);
+ len = vsprintf((char *)(state->in), format, va);
# endif
#else
# ifdef HAS_vsnprintf_void
- (void)vsnprintf(state->in, size, format, va);
- va_end(va);
- len = strlen(state->in);
+ (void)vsnprintf((char *)(state->in), size, format, va);
+ len = strlen((char *)(state->in));
# else
len = vsnprintf((char *)(state->in), size, format, va);
- va_end(va);
# endif
#endif
@@ -342,11 +365,22 @@ int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
/* update buffer and position, defer compression until needed */
strm->avail_in = (unsigned)len;
strm->next_in = state->in;
- state->pos += len;
+ state->x.pos += len;
return len;
}
-#else /* !STDC */
+int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
+{
+ va_list va;
+ int ret;
+
+ va_start(va, format);
+ ret = gzvprintf(file, format, va);
+ va_end(va);
+ return ret;
+}
+
+#else /* !STDC && !Z_HAVE_STDARG_H */
/* -- see zlib.h -- */
int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
@@ -366,6 +400,10 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
state = (gz_statep)file;
strm = &(state->strm);
+ /* check that can really pass pointer in ints */
+ if (sizeof(int) != sizeof(void *))
+ return 0;
+
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
return 0;
@@ -390,22 +428,23 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
state->in[size - 1] = 0;
#ifdef NO_snprintf
# ifdef HAS_sprintf_void
- sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
for (len = 0; len < size; len++)
if (state->in[len] == 0) break;
# else
- len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
# endif
#else
# ifdef HAS_snprintf_void
- snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
- len = strlen(state->in);
+ len = strlen((char *)(state->in));
# else
- len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
+ a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
+ a19, a20);
# endif
#endif
@@ -416,7 +455,7 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
/* update buffer and position, defer compression until needed */
strm->avail_in = (unsigned)len;
strm->next_in = state->in;
- state->pos += len;
+ state->x.pos += len;
return len;
}
@@ -500,7 +539,7 @@ int ZEXPORT gzsetparams(file, level, strategy)
int ZEXPORT gzclose_w(file)
gzFile file;
{
- int ret = 0;
+ int ret = Z_OK;
gz_statep state;
/* get internal structure */
@@ -515,17 +554,24 @@ int ZEXPORT gzclose_w(file)
/* check for seek request */
if (state->seek) {
state->seek = 0;
- ret += gz_zero(state, state->skip);
+ if (gz_zero(state, state->skip) == -1)
+ ret = state->err;
}
/* flush, free memory, and close file */
- ret += gz_comp(state, Z_FINISH);
- (void)deflateEnd(&(state->strm));
- free(state->out);
- free(state->in);
+ if (gz_comp(state, Z_FINISH) == -1)
+ ret = state->err;
+ if (state->size) {
+ if (!state->direct) {
+ (void)deflateEnd(&(state->strm));
+ free(state->out);
+ }
+ free(state->in);
+ }
gz_error(state, Z_OK, NULL);
free(state->path);
- ret += close(state->fd);
+ if (close(state->fd) == -1)
+ ret = Z_ERRNO;
free(state);
- return ret ? Z_ERRNO : Z_OK;
+ return ret;
}
diff --git a/compat/zlib/infback.c b/compat/zlib/infback.c
index af3a8c9..f3833c2 100644
--- a/compat/zlib/infback.c
+++ b/compat/zlib/infback.c
@@ -1,5 +1,5 @@
/* infback.c -- inflate using a call-back interface
- * Copyright (C) 1995-2009 Mark Adler
+ * Copyright (C) 1995-2011 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -42,10 +42,19 @@ int stream_size;
return Z_STREAM_ERROR;
strm->msg = Z_NULL; /* in case we return an error */
if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
strm->zalloc = zcalloc;
strm->opaque = (voidpf)0;
+#endif
}
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
state = (struct inflate_state FAR *)ZALLOC(strm, 1,
sizeof(struct inflate_state));
if (state == Z_NULL) return Z_MEM_ERROR;
@@ -246,7 +255,7 @@ out_func out;
void FAR *out_desc;
{
struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
+ z_const unsigned char FAR *next; /* next input */
unsigned char FAR *put; /* next output */
unsigned have, left; /* available input and output */
unsigned long hold; /* bit buffer */
@@ -394,7 +403,6 @@ void FAR *out_desc;
PULLBYTE();
}
if (here.val < 16) {
- NEEDBITS(here.bits);
DROPBITS(here.bits);
state->lens[state->have++] = here.val;
}
diff --git a/compat/zlib/inffast.c b/compat/zlib/inffast.c
index 2f1d60b..bda59ce 100644
--- a/compat/zlib/inffast.c
+++ b/compat/zlib/inffast.c
@@ -1,5 +1,5 @@
/* inffast.c -- fast decoding
- * Copyright (C) 1995-2008, 2010 Mark Adler
+ * Copyright (C) 1995-2008, 2010, 2013 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -69,8 +69,8 @@ z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */
{
struct inflate_state FAR *state;
- unsigned char FAR *in; /* local strm->next_in */
- unsigned char FAR *last; /* while in < last, enough input available */
+ z_const unsigned char FAR *in; /* local strm->next_in */
+ z_const unsigned char FAR *last; /* have enough input while in < last */
unsigned char FAR *out; /* local strm->next_out */
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
unsigned char FAR *end; /* while out < end, enough space available */
diff --git a/compat/zlib/inffixed.h b/compat/zlib/inffixed.h
index 75ed4b5..d628327 100644
--- a/compat/zlib/inffixed.h
+++ b/compat/zlib/inffixed.h
@@ -2,9 +2,9 @@
* Generated automatically by makefixed().
*/
- /* WARNING: this file should *not* be used by applications. It
- is part of the implementation of the compression library and
- is subject to change. Applications should only use zlib.h.
+ /* WARNING: this file should *not* be used by applications.
+ It is part of the implementation of this library and is
+ subject to change. Applications should only use zlib.h.
*/
static const code lenfix[512] = {
diff --git a/compat/zlib/inflate.c b/compat/zlib/inflate.c
index a8431ab..870f89b 100644
--- a/compat/zlib/inflate.c
+++ b/compat/zlib/inflate.c
@@ -1,5 +1,5 @@
/* inflate.c -- zlib decompression
- * Copyright (C) 1995-2010 Mark Adler
+ * Copyright (C) 1995-2012 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -93,14 +93,15 @@
/* function prototypes */
local void fixedtables OF((struct inflate_state FAR *state));
-local int updatewindow OF((z_streamp strm, unsigned out));
+local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
+ unsigned copy));
#ifdef BUILDFIXED
void makefixed OF((void));
#endif
-local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
+local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
unsigned len));
-int ZEXPORT inflateReset(strm)
+int ZEXPORT inflateResetKeep(strm)
z_streamp strm;
{
struct inflate_state FAR *state;
@@ -109,15 +110,13 @@ z_streamp strm;
state = (struct inflate_state FAR *)strm->state;
strm->total_in = strm->total_out = state->total = 0;
strm->msg = Z_NULL;
- strm->adler = 1; /* to support ill-conceived Java test suite */
+ if (state->wrap) /* to support ill-conceived Java test suite */
+ strm->adler = state->wrap & 1;
state->mode = HEAD;
state->last = 0;
state->havedict = 0;
state->dmax = 32768U;
state->head = Z_NULL;
- state->wsize = 0;
- state->whave = 0;
- state->wnext = 0;
state->hold = 0;
state->bits = 0;
state->lencode = state->distcode = state->next = state->codes;
@@ -127,6 +126,19 @@ z_streamp strm;
return Z_OK;
}
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ state->wsize = 0;
+ state->whave = 0;
+ state->wnext = 0;
+ return inflateResetKeep(strm);
+}
+
int ZEXPORT inflateReset2(strm, windowBits)
z_streamp strm;
int windowBits;
@@ -180,10 +192,19 @@ int stream_size;
if (strm == Z_NULL) return Z_STREAM_ERROR;
strm->msg = Z_NULL; /* in case we return an error */
if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
strm->zalloc = zcalloc;
strm->opaque = (voidpf)0;
+#endif
}
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
state = (struct inflate_state FAR *)
ZALLOC(strm, 1, sizeof(struct inflate_state));
if (state == Z_NULL) return Z_MEM_ERROR;
@@ -321,8 +342,8 @@ void makefixed()
low = 0;
for (;;) {
if ((low % 7) == 0) printf("\n ");
- printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
- state.lencode[low].val);
+ printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
+ state.lencode[low].bits, state.lencode[low].val);
if (++low == size) break;
putchar(',');
}
@@ -355,12 +376,13 @@ void makefixed()
output will fall in the output data, making match copies simpler and faster.
The advantage may be dependent on the size of the processor's data caches.
*/
-local int updatewindow(strm, out)
+local int updatewindow(strm, end, copy)
z_streamp strm;
-unsigned out;
+const Bytef *end;
+unsigned copy;
{
struct inflate_state FAR *state;
- unsigned copy, dist;
+ unsigned dist;
state = (struct inflate_state FAR *)strm->state;
@@ -380,19 +402,18 @@ unsigned out;
}
/* copy state->wsize or less output bytes into the circular window */
- copy = out - strm->avail_out;
if (copy >= state->wsize) {
- zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
+ zmemcpy(state->window, end - state->wsize, state->wsize);
state->wnext = 0;
state->whave = state->wsize;
}
else {
dist = state->wsize - state->wnext;
if (dist > copy) dist = copy;
- zmemcpy(state->window + state->wnext, strm->next_out - copy, dist);
+ zmemcpy(state->window + state->wnext, end - copy, dist);
copy -= dist;
if (copy) {
- zmemcpy(state->window, strm->next_out - copy, copy);
+ zmemcpy(state->window, end - copy, copy);
state->wnext = copy;
state->whave = state->wsize;
}
@@ -499,11 +520,6 @@ unsigned out;
bits -= bits & 7; \
} while (0)
-/* Reverse the bytes in a 32-bit value */
-#define REVERSE(q) \
- ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
- (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
-
/*
inflate() uses a state machine to process as much input data and generate as
much output data as possible before returning. The state machine is
@@ -591,7 +607,7 @@ z_streamp strm;
int flush;
{
struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
+ z_const unsigned char FAR *next; /* next input */
unsigned char FAR *put; /* next output */
unsigned have, left; /* available input and output */
unsigned long hold; /* bit buffer */
@@ -797,7 +813,7 @@ int flush;
#endif
case DICTID:
NEEDBITS(32);
- strm->adler = state->check = REVERSE(hold);
+ strm->adler = state->check = ZSWAP32(hold);
INITBITS();
state->mode = DICT;
case DICT:
@@ -905,7 +921,7 @@ int flush;
while (state->have < 19)
state->lens[order[state->have++]] = 0;
state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
+ state->lencode = (const code FAR *)(state->next);
state->lenbits = 7;
ret = inflate_table(CODES, state->lens, 19, &(state->next),
&(state->lenbits), state->work);
@@ -925,7 +941,6 @@ int flush;
PULLBYTE();
}
if (here.val < 16) {
- NEEDBITS(here.bits);
DROPBITS(here.bits);
state->lens[state->have++] = here.val;
}
@@ -980,7 +995,7 @@ int flush;
values here (9 and 6) without reading the comments in inftrees.h
concerning the ENOUGH constants, which depend on those values */
state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
+ state->lencode = (const code FAR *)(state->next);
state->lenbits = 9;
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
&(state->lenbits), state->work);
@@ -989,7 +1004,7 @@ int flush;
state->mode = BAD;
break;
}
- state->distcode = (code const FAR *)(state->next);
+ state->distcode = (const code FAR *)(state->next);
state->distbits = 6;
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
&(state->next), &(state->distbits), state->work);
@@ -1170,7 +1185,7 @@ int flush;
#ifdef GUNZIP
state->flags ? hold :
#endif
- REVERSE(hold)) != state->check) {
+ ZSWAP32(hold)) != state->check) {
strm->msg = (char *)"incorrect data check";
state->mode = BAD;
break;
@@ -1214,8 +1229,9 @@ int flush;
*/
inf_leave:
RESTORE();
- if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
- if (updatewindow(strm, out)) {
+ if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
+ (state->mode < CHECK || flush != Z_FINISH)))
+ if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
state->mode = MEM;
return Z_MEM_ERROR;
}
@@ -1249,13 +1265,37 @@ z_streamp strm;
return Z_OK;
}
+int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+Bytef *dictionary;
+uInt *dictLength;
+{
+ struct inflate_state FAR *state;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* copy dictionary */
+ if (state->whave && dictionary != Z_NULL) {
+ zmemcpy(dictionary, state->window + state->wnext,
+ state->whave - state->wnext);
+ zmemcpy(dictionary + state->whave - state->wnext,
+ state->window, state->wnext);
+ }
+ if (dictLength != Z_NULL)
+ *dictLength = state->whave;
+ return Z_OK;
+}
+
int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
z_streamp strm;
const Bytef *dictionary;
uInt dictLength;
{
struct inflate_state FAR *state;
- unsigned long id;
+ unsigned long dictid;
+ int ret;
/* check state */
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
@@ -1263,29 +1303,21 @@ uInt dictLength;
if (state->wrap != 0 && state->mode != DICT)
return Z_STREAM_ERROR;
- /* check for correct dictionary id */
+ /* check for correct dictionary identifier */
if (state->mode == DICT) {
- id = adler32(0L, Z_NULL, 0);
- id = adler32(id, dictionary, dictLength);
- if (id != state->check)
+ dictid = adler32(0L, Z_NULL, 0);
+ dictid = adler32(dictid, dictionary, dictLength);
+ if (dictid != state->check)
return Z_DATA_ERROR;
}
- /* copy dictionary to window */
- if (updatewindow(strm, strm->avail_out)) {
+ /* copy dictionary to window using updatewindow(), which will amend the
+ existing dictionary if appropriate */
+ ret = updatewindow(strm, dictionary + dictLength, dictLength);
+ if (ret) {
state->mode = MEM;
return Z_MEM_ERROR;
}
- if (dictLength > state->wsize) {
- zmemcpy(state->window, dictionary + dictLength - state->wsize,
- state->wsize);
- state->whave = state->wsize;
- }
- else {
- zmemcpy(state->window + state->wsize - dictLength, dictionary,
- dictLength);
- state->whave = dictLength;
- }
state->havedict = 1;
Tracev((stderr, "inflate: dictionary set\n"));
return Z_OK;
@@ -1321,7 +1353,7 @@ gz_headerp head;
*/
local unsigned syncsearch(have, buf, len)
unsigned FAR *have;
-unsigned char FAR *buf;
+const unsigned char FAR *buf;
unsigned len;
{
unsigned got;
@@ -1433,8 +1465,8 @@ z_streamp source;
}
/* copy state */
- zmemcpy(dest, source, sizeof(z_stream));
- zmemcpy(copy, state, sizeof(struct inflate_state));
+ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+ zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
if (state->lencode >= state->codes &&
state->lencode <= state->codes + ENOUGH - 1) {
copy->lencode = copy->codes + (state->lencode - state->codes);
diff --git a/compat/zlib/inftrees.c b/compat/zlib/inftrees.c
index 11e9c52..44d89cf 100644
--- a/compat/zlib/inftrees.c
+++ b/compat/zlib/inftrees.c
@@ -1,5 +1,5 @@
/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2010 Mark Adler
+ * Copyright (C) 1995-2013 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -9,7 +9,7 @@
#define MAXBITS 15
const char inflate_copyright[] =
- " inflate 1.2.5 Copyright 1995-2010 Mark Adler ";
+ " inflate 1.2.8 Copyright 1995-2013 Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
@@ -62,7 +62,7 @@ unsigned short FAR *work;
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
- 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195};
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
@@ -208,8 +208,8 @@ unsigned short FAR *work;
mask = used - 1; /* mask for comparing low */
/* check available table space */
- if ((type == LENS && used >= ENOUGH_LENS) ||
- (type == DISTS && used >= ENOUGH_DISTS))
+ if ((type == LENS && used > ENOUGH_LENS) ||
+ (type == DISTS && used > ENOUGH_DISTS))
return 1;
/* process all codes and make table entries */
@@ -277,8 +277,8 @@ unsigned short FAR *work;
/* check for enough space */
used += 1U << curr;
- if ((type == LENS && used >= ENOUGH_LENS) ||
- (type == DISTS && used >= ENOUGH_DISTS))
+ if ((type == LENS && used > ENOUGH_LENS) ||
+ (type == DISTS && used > ENOUGH_DISTS))
return 1;
/* point entry in root table to sub-table */
@@ -289,38 +289,14 @@ unsigned short FAR *work;
}
}
- /*
- Fill in rest of table for incomplete codes. This loop is similar to the
- loop above in incrementing huff for table indices. It is assumed that
- len is equal to curr + drop, so there is no loop needed to increment
- through high index bits. When the current sub-table is filled, the loop
- drops back to the root table to fill in any remaining entries there.
- */
- here.op = (unsigned char)64; /* invalid code marker */
- here.bits = (unsigned char)(len - drop);
- here.val = (unsigned short)0;
- while (huff != 0) {
- /* when done with sub-table, drop back to root table */
- if (drop != 0 && (huff & mask) != low) {
- drop = 0;
- len = root;
- next = *table;
- here.bits = (unsigned char)len;
- }
-
- /* put invalid code marker in table */
- next[huff >> drop] = here;
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
+ /* fill in remaining table entry if code is incomplete (guaranteed to have
+ at most one remaining entry, since if the code is incomplete, the
+ maximum code length that was allowed to get this far is one bit) */
+ if (huff != 0) {
+ here.op = (unsigned char)64; /* invalid code marker */
+ here.bits = (unsigned char)(len - drop);
+ here.val = (unsigned short)0;
+ next[huff] = here;
}
/* set return parameters */
diff --git a/compat/zlib/make_vms.com b/compat/zlib/make_vms.com
index 6576490..65e9d0c 100644
--- a/compat/zlib/make_vms.com
+++ b/compat/zlib/make_vms.com
@@ -3,7 +3,7 @@ $! Martin P.J. Zinser
$!
$! In case of problems with the install you might contact me at
$! zinser@zinser.no-ip.info(preferred) or
-$! zinser@sysdev.deutsche-boerse.com (work)
+$! martin.zinser@eurexchange.com (work)
$!
$! Make procedure history for Zlib
$!
@@ -14,9 +14,16 @@ $! 0.02 20061008 Adapt to new Makefile.in
$! 0.03 20091224 Add support for large file check
$! 0.04 20100110 Add new gzclose, gzlib, gzread, gzwrite
$! 0.05 20100221 Exchange zlibdefs.h by zconf.h.in
+$! 0.06 20120111 Fix missing amiss_err, update zconf_h.in, fix new exmples
+$! subdir path, update module search in makefile.in
+$! 0.07 20120115 Triggered by work done by Alexey Chupahin completly redesigned
+$! shared image creation
+$! 0.08 20120219 Make it work on VAX again, pre-load missing symbols to shared
+$! image
+$! 0.09 20120305 SMS. P1 sets builder ("MMK", "MMS", " " (built-in)).
+$! "" -> automatic, preference: MMK, MMS, built-in.
$!
$ on error then goto err_exit
-$ set proc/parse=ext
$!
$ true = 1
$ false = 0
@@ -32,31 +39,43 @@ $ s_case = False
$!
$! Setup variables holding "config" information
$!
-$ Make = ""
+$ Make = "''p1'"
$ name = "Zlib"
$ version = "?.?.?"
$ v_string = "ZLIB_VERSION"
$ v_file = "zlib.h"
-$ ccopt = ""
+$ ccopt = "/include = []"
$ lopts = ""
$ dnsrl = ""
-$ aconf_in_file = "zconf.h.in#zconf.h_in"
+$ aconf_in_file = "zconf.h.in#zconf.h_in#zconf_h.in"
$ conf_check_string = ""
$ linkonly = false
$ optfile = name + ".opt"
+$ mapfile = name + ".map"
$ libdefs = ""
+$ vax = f$getsyi("HW_MODEL").lt.1024
$ axp = f$getsyi("HW_MODEL").ge.1024 .and. f$getsyi("HW_MODEL").lt.4096
+$ ia64 = f$getsyi("HW_MODEL").ge.4096
$!
-$ whoami = f$parse(f$enviornment("Procedure"),,,,"NO_CONCEAL")
+$! 2012-03-05 SMS.
+$! Why is this needed? And if it is needed, why not simply ".not. vax"?
+$!
+$!!! if axp .or. ia64 then set proc/parse=extended
+$!
+$ whoami = f$parse(f$environment("Procedure"),,,,"NO_CONCEAL")
$ mydef = F$parse(whoami,,,"DEVICE")
$ mydir = f$parse(whoami,,,"DIRECTORY") - "]["
$ myproc = f$parse(whoami,,,"Name") + f$parse(whoami,,,"type")
$!
$! Check for MMK/MMS
$!
-$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS"
-$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK"
-$!
+$ if (Make .eqs. "")
+$ then
+$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS"
+$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK"
+$ else
+$ Make = f$edit( Make, "trim")
+$ endif
$!
$ gosub find_version
$!
@@ -69,6 +88,7 @@ $! Look for the compiler used
$!
$ gosub check_compiler
$ close topt
+$ close optf
$!
$ if its_decc
$ then
@@ -83,6 +103,15 @@ $ ccopt = "/decc" + ccopt
$ define sys decc$library_include:
$ endif
$ endif
+$!
+$! 2012-03-05 SMS.
+$! Why /NAMES = AS_IS? Why not simply ".not. vax"? And why not on VAX?
+$!
+$ if axp .or. ia64
+$ then
+$ ccopt = ccopt + "/name=as_is/opt=(inline=speed)"
+$ s_case = true
+$ endif
$ endif
$ if its_vaxc .or. its_gnuc
$ then
@@ -122,15 +151,20 @@ $ gosub check_config
$ endif
$ goto aconf_loop
$ACONF_EXIT:
+$ write aconf ""
+$ write aconf "/* VMS specifics added by make_vms.com: */"
$ write aconf "#define VMS 1"
$ write aconf "#include <unistd.h>"
$ write aconf "#include <unixio.h>"
$ write aconf "#ifdef _LARGEFILE"
-$ write aconf "#define off64_t __off64_t"
-$ write aconf "#define fopen64 fopen"
-$ write aconf "#define fseeko64 fseeko"
-$ write aconf "#define lseek64 lseek"
-$ write aconf "#define ftello64 ftell"
+$ write aconf "# define off64_t __off64_t"
+$ write aconf "# define fopen64 fopen"
+$ write aconf "# define fseeko64 fseeko"
+$ write aconf "# define lseek64 lseek"
+$ write aconf "# define ftello64 ftell"
+$ write aconf "#endif"
+$ write aconf "#if !defined( __VAX) && (__CRTL_VER >= 70312000)"
+$ write aconf "# define HAVE_VSNPRINTF"
$ write aconf "#endif"
$ close aconf_in
$ close aconf
@@ -139,8 +173,9 @@ $! Build the thing plain or with mms
$!
$ write sys$output "Compiling Zlib sources ..."
$ if make.eqs.""
-$ then
-$ dele example.obj;*,minigzip.obj;*
+$ then
+$ if (f$search( "example.obj;*") .nes. "") then delete example.obj;*
+$ if (f$search( "minigzip.obj;*") .nes. "") then delete minigzip.obj;*
$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" -
adler32.c zlib.h zconf.h
$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" -
@@ -174,41 +209,34 @@ $ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" -
$ write sys$output "Building Zlib ..."
$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ
$ write sys$output "Building example..."
-$ CALL MAKE example.OBJ "CC ''CCOPT' example" -
- example.c zlib.h zconf.h
+$ CALL MAKE example.OBJ "CC ''CCOPT' [.test]example" -
+ [.test]example.c zlib.h zconf.h
$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb
-$ if f$search("x11vms:xvmsutils.olb") .nes. ""
-$ then
-$ write sys$output "Building minigzip..."
-$ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" -
- minigzip.c zlib.h zconf.h
-$ call make minigzip.exe -
- "LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" -
- minigzip.obj libz.olb
-$ endif
-$ else
+$ write sys$output "Building minigzip..."
+$ CALL MAKE minigzip.OBJ "CC ''CCOPT' [.test]minigzip" -
+ [.test]minigzip.c zlib.h zconf.h
+$ call make minigzip.exe -
+ "LINK minigzip,libz.olb/lib" -
+ minigzip.obj libz.olb
+$ else
$ gosub crea_mms
$ write sys$output "Make ''name' ''version' with ''Make' "
$ 'make'
-$ endif
+$ endif
$!
-$! Alpha gets a shareable image
+$! Create shareable image
$!
-$ If axp
-$ Then
-$ gosub crea_olist
-$ write sys$output "Creating libzshr.exe"
-$ call anal_obj_axp modules.opt _link.opt
-$ if s_case
-$ then
-$ open/append optf modules.opt
-$ write optf "case_sensitive=YES"
-$ close optf
-$ endif
-$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,_link.opt/opt
-$ endif
+$ gosub crea_olist
+$ write sys$output "Creating libzshr.exe"
+$ call map_2_shopt 'mapfile' 'optfile'
+$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,'optfile'/opt
$ write sys$output "Zlib build completed"
+$ delete/nolog tmp.opt;*
$ exit
+$AMISS_ERR:
+$ write sys$output "No source for config.hin found."
+$ write sys$output "Tried any of ''aconf_in_file'"
+$ goto err_exit
$CC_ERR:
$ write sys$output "C compiler required to build ''name'"
$ goto err_exit
@@ -216,7 +244,6 @@ $ERR_EXIT:
$ set message/facil/ident/sever/text
$ close/nolog optf
$ close/nolog topt
-$ close/nolog conf_hin
$ close/nolog aconf_in
$ close/nolog aconf
$ close/nolog out
@@ -397,7 +424,7 @@ $ copy sys$input: out
$ deck
# descrip.mms: MMS description file for building zlib on VMS
# written by Martin P.J. Zinser
-# <zinser@zinser.no-ip.info or zinser@sysdev.deutsche-boerse.com>
+# <zinser@zinser.no-ip.info or martin.zinser@eurexchange.com>
OBJS = adler32.obj, compress.obj, crc32.obj, gzclose.obj, gzlib.obj\
gzread.obj, gzwrite.obj, uncompr.obj, infback.obj\
@@ -407,10 +434,9 @@ OBJS = adler32.obj, compress.obj, crc32.obj, gzclose.obj, gzlib.obj\
$ eod
$ write out "CFLAGS=", ccopt
$ write out "LOPTS=", lopts
+$ write out "all : example.exe minigzip.exe libz.olb"
$ copy sys$input: out
$ deck
-
-all : example.exe minigzip.exe libz.olb
@ write sys$output " Example applications available"
libz.olb : libz.olb($(OBJS))
@@ -420,7 +446,7 @@ example.exe : example.obj libz.olb
link $(LOPTS) example,libz.olb/lib
minigzip.exe : minigzip.obj libz.olb
- link $(LOPTS) minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib
+ link $(LOPTS) minigzip,libz.olb/lib
clean :
delete *.obj;*,libz.olb;*,*.opt;*,*.exe;*
@@ -431,7 +457,7 @@ adler32.obj : adler32.c zutil.h zlib.h zconf.h
compress.obj : compress.c zlib.h zconf.h
crc32.obj : crc32.c zutil.h zlib.h zconf.h
deflate.obj : deflate.c deflate.h zutil.h zlib.h zconf.h
-example.obj : example.c zlib.h zconf.h
+example.obj : [.test]example.c zlib.h zconf.h
gzclose.obj : gzclose.c zutil.h zlib.h zconf.h
gzlib.obj : gzlib.c zutil.h zlib.h zconf.h
gzread.obj : gzread.c zutil.h zlib.h zconf.h
@@ -439,7 +465,7 @@ gzwrite.obj : gzwrite.c zutil.h zlib.h zconf.h
inffast.obj : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h
inflate.obj : inflate.c zutil.h zlib.h zconf.h
inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h
-minigzip.obj : minigzip.c zlib.h zconf.h
+minigzip.obj : [.test]minigzip.c zlib.h zconf.h
trees.obj : trees.c deflate.h zutil.h zlib.h zconf.h
uncompr.obj : uncompr.c zlib.h zconf.h
zutil.obj : zutil.c zutil.h zlib.h zconf.h
@@ -455,13 +481,18 @@ $!
$CREA_OLIST:
$ open/read min makefile.in
$ open/write mod modules.opt
-$ src_check = "OBJC ="
+$ src_check_list = "OBJZ =#OBJG ="
$MRLOOP:
$ read/end=mrdone min rec
-$ if (f$extract(0,6,rec) .nes. src_check) then goto mrloop
+$ i = 0
+$SRC_CHECK_LOOP:
+$ src_check = f$element(i, "#", src_check_list)
+$ i = i+1
+$ if src_check .eqs. "#" then goto mrloop
+$ if (f$extract(0,6,rec) .nes. src_check) then goto src_check_loop
$ rec = rec - src_check
$ gosub extra_filnam
-$ if (f$element(1,"\",rec) .eqs. "\") then goto mrdone
+$ if (f$element(1,"\",rec) .eqs. "\") then goto mrloop
$MRSLOOP:
$ read/end=mrdone min rec
$ gosub extra_filnam
@@ -672,133 +703,165 @@ $ endif
$ return
$!------------------------------------------------------------------------------
$!
-$! Analyze Object files for OpenVMS AXP to extract Procedure and Data
-$! information to build a symbol vector for a shareable image
-$! All the "brains" of this logic was suggested by Hartmut Becker
-$! (Hartmut.Becker@compaq.com). All the bugs were introduced by me
-$! (zinser@zinser.no-ip.info), so if you do have problem reports please do not
-$! bother Hartmut/HP, but get in touch with me
+$! Write configuration to both permanent and temporary config file
$!
$! Version history
-$! 0.01 20040406 Skip over shareable images in option file
-$! 0.02 20041109 Fix option file for shareable images with case_sensitive=YES
-$! 0.03 20050107 Skip over Identification labels in option file
-$! 0.04 20060117 Add uppercase alias to code compiled with /name=as_is
+$! 0.01 20031029 First version to receive a number
+$!
+$WRITE_CONFIG: SUBROUTINE
+$ write aconf 'p1'
+$ open/append confh 'th'
+$ write confh 'p1'
+$ close confh
+$ENDSUBROUTINE
+$!------------------------------------------------------------------------------
+$!
+$! Analyze the project map file and create the symbol vector for a shareable
+$! image from it
+$!
+$! Version history
+$! 0.01 20120128 First version
+$! 0.02 20120226 Add pre-load logic
+$!
+$ MAP_2_SHOPT: Subroutine
$!
-$ ANAL_OBJ_AXP: Subroutine
-$ V = 'F$Verify(0)
$ SAY := "WRITE_ SYS$OUTPUT"
-$
+$!
$ IF F$SEARCH("''P1'") .EQS. ""
$ THEN
-$ SAY "ANAL_OBJ_AXP-E-NOSUCHFILE: Error, inputfile ''p1' not available"
-$ goto exit_aa
+$ SAY "MAP_2_SHOPT-E-NOSUCHFILE: Error, inputfile ''p1' not available"
+$ goto exit_m2s
$ ENDIF
$ IF "''P2'" .EQS. ""
$ THEN
-$ SAY "ANAL_OBJ_AXP: Error, no output file provided"
-$ goto exit_aa
+$ SAY "MAP_2_SHOPT: Error, no output file provided"
+$ goto exit_m2s
$ ENDIF
-$
-$ open/read in 'p1
-$ create a.tmp
-$ open/append atmp a.tmp
-$ loop:
-$ read/end=end_loop in line
-$ if f$locate("/SHARE",f$edit(line,"upcase")) .lt. f$length(line)
-$ then
-$ write sys$output "ANAL_SKP_SHR-i-skipshare, ''line'"
-$ goto loop
-$ endif
-$ if f$locate("IDENTIFICATION=",f$edit(line,"upcase")) .lt. f$length(line)
-$ then
-$ write sys$output "ANAL_OBJ_AXP-i-ident: Identification ", -
- f$element(1,"=",line)
-$ goto loop
-$ endif
-$ f= f$search(line)
-$ if f .eqs. ""
-$ then
-$ write sys$output "ANAL_OBJ_AXP-w-nosuchfile, ''line'"
-$ goto loop
-$ endif
-$ define/user sys$output nl:
-$ define/user sys$error nl:
-$ anal/obj/gsd 'f /out=x.tmp
-$ open/read xtmp x.tmp
-$ XLOOP:
-$ read/end=end_xloop xtmp xline
-$ xline = f$edit(xline,"compress")
-$ write atmp xline
-$ goto xloop
-$ END_XLOOP:
-$ close xtmp
-$ goto loop
-$ end_loop:
-$ close in
-$ close atmp
-$ if f$search("a.tmp") .eqs. "" -
- then $ exit
-$ ! all global definitions
-$ search a.tmp "symbol:","EGSY$V_DEF 1","EGSY$V_NORM 1"/out=b.tmp
-$ ! all procedures
-$ search b.tmp "EGSY$V_NORM 1"/wind=(0,1) /out=c.tmp
-$ search c.tmp "symbol:"/out=d.tmp
-$ define/user sys$output nl:
-$ edito/edt/command=sys$input d.tmp
-sub/symbol: "/symbol_vector=(/whole
-sub/"/=PROCEDURE)/whole
-exit
-$ ! all data
-$ search b.tmp "EGSY$V_DEF 1"/wind=(0,1) /out=e.tmp
-$ search e.tmp "symbol:"/out=f.tmp
-$ define/user sys$output nl:
-$ edito/edt/command=sys$input f.tmp
-sub/symbol: "/symbol_vector=(/whole
-sub/"/=DATA)/whole
-exit
-$ sort/nodupl d.tmp,f.tmp g.tmp
-$ open/read raw_vector g.tmp
-$ open/write case_vector 'p2'
-$ RAWLOOP:
-$ read/end=end_rawloop raw_vector raw_element
-$ write case_vector raw_element
-$ if f$locate("=PROCEDURE)",raw_element) .lt. f$length(raw_element)
-$ then
-$ name = f$element(1,"=",raw_element) - "("
-$ if f$edit(name,"UPCASE") .nes. name then -
- write case_vector f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)", -
- f$edit(name,"UPCASE"), name)
-$ endif
-$ if f$locate("=DATA)",raw_element) .lt. f$length(raw_element)
+$!
+$ module1 = "deflate#deflateEnd#deflateInit_#deflateParams#deflateSetDictionary"
+$ module2 = "gzclose#gzerror#gzgetc#gzgets#gzopen#gzprintf#gzputc#gzputs#gzread"
+$ module3 = "gzseek#gztell#inflate#inflateEnd#inflateInit_#inflateSetDictionary"
+$ module4 = "inflateSync#uncompress#zlibVersion#compress"
+$ open/read map 'p1
+$ if axp .or. ia64
$ then
-$ name = f$element(1,"=",raw_element) - "("
-$ if f$edit(name,"UPCASE") .nes. name then -
- write case_vector f$fao(" symbol_vector=(!AS/!AS=DATA)", -
- f$edit(name,"UPCASE"), name)
+$ open/write aopt a.opt
+$ open/write bopt b.opt
+$ write aopt " CASE_SENSITIVE=YES"
+$ write bopt "SYMBOL_VECTOR= (-"
+$ mod_sym_num = 1
+$ MOD_SYM_LOOP:
+$ if f$type(module'mod_sym_num') .nes. ""
+$ then
+$ mod_in = 0
+$ MOD_SYM_IN:
+$ shared_proc = f$element(mod_in, "#", module'mod_sym_num')
+$ if shared_proc .nes. "#"
+$ then
+$ write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",-
+ f$edit(shared_proc,"upcase"),shared_proc)
+$ write bopt f$fao("!AS=PROCEDURE,-",shared_proc)
+$ mod_in = mod_in + 1
+$ goto mod_sym_in
+$ endif
+$ mod_sym_num = mod_sym_num + 1
+$ goto mod_sym_loop
+$ endif
+$MAP_LOOP:
+$ read/end=map_end map line
+$ if (f$locate("{",line).lt. f$length(line)) .or. -
+ (f$locate("global:", line) .lt. f$length(line))
+$ then
+$ proc = true
+$ goto map_loop
+$ endif
+$ if f$locate("}",line).lt. f$length(line) then proc = false
+$ if f$locate("local:", line) .lt. f$length(line) then proc = false
+$ if proc
+$ then
+$ shared_proc = f$edit(line,"collapse")
+$ chop_semi = f$locate(";", shared_proc)
+$ if chop_semi .lt. f$length(shared_proc) then -
+ shared_proc = f$extract(0, chop_semi, shared_proc)
+$ write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",-
+ f$edit(shared_proc,"upcase"),shared_proc)
+$ write bopt f$fao("!AS=PROCEDURE,-",shared_proc)
+$ endif
+$ goto map_loop
+$MAP_END:
+$ close/nolog aopt
+$ close/nolog bopt
+$ open/append libopt 'p2'
+$ open/read aopt a.opt
+$ open/read bopt b.opt
+$ALOOP:
+$ read/end=aloop_end aopt line
+$ write libopt line
+$ goto aloop
+$ALOOP_END:
+$ close/nolog aopt
+$ sv = ""
+$BLOOP:
+$ read/end=bloop_end bopt svn
+$ if (svn.nes."")
+$ then
+$ if (sv.nes."") then write libopt sv
+$ sv = svn
+$ endif
+$ goto bloop
+$BLOOP_END:
+$ write libopt f$extract(0,f$length(sv)-2,sv), "-"
+$ write libopt ")"
+$ close/nolog bopt
+$ delete/nolog/noconf a.opt;*,b.opt;*
+$ else
+$ if vax
+$ then
+$ open/append libopt 'p2'
+$ mod_sym_num = 1
+$ VMOD_SYM_LOOP:
+$ if f$type(module'mod_sym_num') .nes. ""
+$ then
+$ mod_in = 0
+$ VMOD_SYM_IN:
+$ shared_proc = f$element(mod_in, "#", module'mod_sym_num')
+$ if shared_proc .nes. "#"
+$ then
+$ write libopt f$fao("UNIVERSAL=!AS",-
+ f$edit(shared_proc,"upcase"))
+$ mod_in = mod_in + 1
+$ goto vmod_sym_in
+$ endif
+$ mod_sym_num = mod_sym_num + 1
+$ goto vmod_sym_loop
+$ endif
+$VMAP_LOOP:
+$ read/end=vmap_end map line
+$ if (f$locate("{",line).lt. f$length(line)) .or. -
+ (f$locate("global:", line) .lt. f$length(line))
+$ then
+$ proc = true
+$ goto vmap_loop
+$ endif
+$ if f$locate("}",line).lt. f$length(line) then proc = false
+$ if f$locate("local:", line) .lt. f$length(line) then proc = false
+$ if proc
+$ then
+$ shared_proc = f$edit(line,"collapse")
+$ chop_semi = f$locate(";", shared_proc)
+$ if chop_semi .lt. f$length(shared_proc) then -
+ shared_proc = f$extract(0, chop_semi, shared_proc)
+$ write libopt f$fao("UNIVERSAL=!AS",-
+ f$edit(shared_proc,"upcase"))
+$ endif
+$ goto vmap_loop
+$VMAP_END:
+$ else
+$ write sys$output "Unknown Architecture (Not VAX, AXP, or IA64)"
+$ write sys$output "No options file created"
+$ endif
$ endif
-$ goto rawloop
-$ END_RAWLOOP:
-$ close raw_vector
-$ close case_vector
-$ delete a.tmp;*,b.tmp;*,c.tmp;*,d.tmp;*,e.tmp;*,f.tmp;*,g.tmp;*
-$ if f$search("x.tmp") .nes. "" -
- then $ delete x.tmp;*
-$!
-$ EXIT_AA:
-$ if V then set verify
+$ EXIT_M2S:
+$ close/nolog map
+$ close/nolog libopt
$ endsubroutine
-$!------------------------------------------------------------------------------
-$!
-$! Write configuration to both permanent and temporary config file
-$!
-$! Version history
-$! 0.01 20031029 First version to receive a number
-$!
-$WRITE_CONFIG: SUBROUTINE
-$ write aconf 'p1'
-$ open/append confh 'th'
-$ write confh 'p1'
-$ close confh
-$ENDSUBROUTINE
-$!------------------------------------------------------------------------------
diff --git a/compat/zlib/msdos/Makefile.bor b/compat/zlib/msdos/Makefile.bor
index 0c1b99c..3d12a2c 100644
--- a/compat/zlib/msdos/Makefile.bor
+++ b/compat/zlib/msdos/Makefile.bor
@@ -86,9 +86,9 @@ uncompr.obj: uncompr.c zlib.h zconf.h
zutil.obj: zutil.c zutil.h zlib.h zconf.h
-example.obj: example.c zlib.h zconf.h
+example.obj: test/example.c zlib.h zconf.h
-minigzip.obj: minigzip.c zlib.h zconf.h
+minigzip.obj: test/minigzip.c zlib.h zconf.h
# the command line is cut to fit in the MS-DOS 128 byte limit:
diff --git a/compat/zlib/msdos/Makefile.msc b/compat/zlib/msdos/Makefile.msc
index cd2816f..ae83786 100644
--- a/compat/zlib/msdos/Makefile.msc
+++ b/compat/zlib/msdos/Makefile.msc
@@ -80,10 +80,10 @@ uncompr.obj: uncompr.c zlib.h zconf.h
zutil.obj: zutil.c zutil.h zlib.h zconf.h
-example.obj: example.c zlib.h zconf.h
+example.obj: test/example.c zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c
-minigzip.obj: minigzip.c zlib.h zconf.h
+minigzip.obj: test/minigzip.c zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c
diff --git a/compat/zlib/msdos/Makefile.tc b/compat/zlib/msdos/Makefile.tc
index bcd0d18..5aec82a 100644
--- a/compat/zlib/msdos/Makefile.tc
+++ b/compat/zlib/msdos/Makefile.tc
@@ -71,9 +71,9 @@ uncompr.obj: uncompr.c zlib.h zconf.h
zutil.obj: zutil.c zutil.h zlib.h zconf.h
-example.obj: example.c zlib.h zconf.h
+example.obj: test/example.c zlib.h zconf.h
-minigzip.obj: minigzip.c zlib.h zconf.h
+minigzip.obj: test/minigzip.c zlib.h zconf.h
# the command line is cut to fit in the MS-DOS 128 byte limit:
diff --git a/compat/zlib/win32/Makefile.emx b/compat/zlib/old/Makefile.emx
index 4d6ab0e..4d6ab0e 100644
--- a/compat/zlib/win32/Makefile.emx
+++ b/compat/zlib/old/Makefile.emx
diff --git a/compat/zlib/old/as400/compile.clp b/compat/zlib/old/as400/compile.clp
deleted file mode 100644
index 8554951..0000000
--- a/compat/zlib/old/as400/compile.clp
+++ /dev/null
@@ -1,123 +0,0 @@
-/******************************************************************************/
-/* */
-/* ZLIB */
-/* */
-/* Compile sources into modules and link them into a service program. */
-/* */
-/******************************************************************************/
-
- PGM
-
-/* Configuration adjustable parameters. */
-
- DCL VAR(&SRCLIB) TYPE(*CHAR) LEN(10) +
- VALUE('ZLIB') /* Source library. */
- DCL VAR(&SRCFILE) TYPE(*CHAR) LEN(10) +
- VALUE('SOURCES') /* Source member file. */
- DCL VAR(&CTLFILE) TYPE(*CHAR) LEN(10) +
- VALUE('TOOLS') /* Control member file. */
-
- DCL VAR(&MODLIB) TYPE(*CHAR) LEN(10) +
- VALUE('ZLIB') /* Module library. */
-
- DCL VAR(&SRVLIB) TYPE(*CHAR) LEN(10) +
- VALUE('LGPL') /* Service program library. */
-
- DCL VAR(&CFLAGS) TYPE(*CHAR) +
- VALUE('OPTIMIZE(40)') /* Compile options. */
-
-
-/* Working storage. */
-
- DCL VAR(&CMDLEN) TYPE(*DEC) LEN(15 5) VALUE(300) /* Command length. */
- DCL VAR(&CMD) TYPE(*CHAR) LEN(512)
-
-
-/* Compile sources into modules. */
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/ADLER32) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/COMPRESS) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/CRC32) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/DEFLATE) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/GZIO) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/INFBACK) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/INFFAST) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/INFLATE) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/INFTREES) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/TREES) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/UNCOMPR) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
- CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
- '/ZUTIL) SRCFILE(' *TCAT +
- &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
- ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
- CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
-
-
-/* Link modules into a service program. */
-
- CRTSRVPGM SRVPGM(&SRVLIB/ZLIB) +
- MODULE(&MODLIB/ADLER32 &MODLIB/COMPRESS +
- &MODLIB/CRC32 &MODLIB/DEFLATE +
- &MODLIB/GZIO &MODLIB/INFBACK +
- &MODLIB/INFFAST &MODLIB/INFLATE +
- &MODLIB/INFTREES &MODLIB/TREES +
- &MODLIB/UNCOMPR &MODLIB/ZUTIL) +
- SRCFILE(&SRCLIB/&CTLFILE) SRCMBR(BNDSRC) +
- TEXT('ZLIB 1.2.3') TGTRLS(V4R4M0)
-
- ENDPGM
diff --git a/compat/zlib/old/visualc6/README.txt b/compat/zlib/old/visualc6/README.txt
deleted file mode 100644
index d0296c2..0000000
--- a/compat/zlib/old/visualc6/README.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-Microsoft Developer Studio Project Files, Format Version 6.00 for zlib.
-
-Copyright (C) 2000-2004 Simon-Pierre Cadieux.
-Copyright (C) 2004 Cosmin Truta.
-For conditions of distribution and use, see copyright notice in zlib.h.
-
-
-This project builds the zlib binaries as follows:
-
-* Win32_DLL_Release\zlib1.dll DLL build
-* Win32_DLL_Debug\zlib1d.dll DLL build (debug version)
-* Win32_DLL_ASM_Release\zlib1.dll DLL build using ASM code
-* Win32_DLL_ASM_Debug\zlib1d.dll DLL build using ASM code (debug version)
-* Win32_LIB_Release\zlib.lib static build
-* Win32_LIB_Debug\zlibd.lib static build (debug version)
-* Win32_LIB_ASM_Release\zlib.lib static build using ASM code
-* Win32_LIB_ASM_Debug\zlibd.lib static build using ASM code (debug version)
-
-
-For more information regarding the DLL builds, please see the DLL FAQ
-in ..\..\win32\DLL_FAQ.txt.
-
-
-To build and test:
-
-1) On the main menu, select "File | Open Workspace".
- Open "zlib.dsw".
-
-2) Select "Build | Set Active Configuration".
- Choose the configuration you wish to build.
-
-3) Select "Build | Clean".
-
-4) Select "Build | Build ... (F7)". Ignore warning messages about
- not being able to find certain include files (e.g. alloc.h).
-
-5) If you built one of the sample programs (example or minigzip),
- select "Build | Execute ... (Ctrl+F5)".
-
-
-To use:
-
-1) Select "Project | Settings (Alt+F7)".
- Make note of the configuration names used in your project.
- Usually, these names are "Win32 Release" and "Win32 Debug".
-
-2) In the Workspace window, select the "FileView" tab.
- Right-click on the root item "Workspace '...'".
- Select "Insert Project into Workspace".
- Switch on the checkbox "Dependency of:", and select the name
- of your project. Open "zlib.dsp".
-
-3) Select "Build | Configurations".
- For each configuration of your project:
- 3.1) Choose the zlib configuration you wish to use.
- 3.2) Click on "Add".
- 3.3) Set the new zlib configuration name to the name used by
- the configuration from the current iteration.
-
-4) Select "Build | Set Active Configuration".
- Choose the configuration you wish to build.
-
-5) Select "Build | Build ... (F7)".
-
-6) If you built an executable program, select
- "Build | Execute ... (Ctrl+F5)".
-
-
-Note:
-
-To build the ASM-enabled code, you need Microsoft Assembler
-(ML.EXE). You can get it by downloading and installing the
-latest Processor Pack for Visual C++ 6.0.
diff --git a/compat/zlib/old/visualc6/example.dsp b/compat/zlib/old/visualc6/example.dsp
deleted file mode 100644
index d358052..0000000
--- a/compat/zlib/old/visualc6/example.dsp
+++ /dev/null
@@ -1,278 +0,0 @@
-# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=example - Win32 LIB Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "example.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 LIB Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "example - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "example - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE "example - Win32 DLL Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "example - Win32 DLL Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE "example - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "example - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE "example - Win32 LIB Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "example - Win32 LIB Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "example - Win32 DLL ASM Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "example___Win32_DLL_ASM_Release"
-# PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_DLL_ASM_Release"
-# PROP Intermediate_Dir "Win32_DLL_ASM_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "example - Win32 DLL ASM Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "example___Win32_DLL_ASM_Debug"
-# PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_DLL_ASM_Debug"
-# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "example - Win32 DLL Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "example___Win32_DLL_Release"
-# PROP BASE Intermediate_Dir "example___Win32_DLL_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_DLL_Release"
-# PROP Intermediate_Dir "Win32_DLL_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "example - Win32 DLL Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "example___Win32_DLL_Debug"
-# PROP BASE Intermediate_Dir "example___Win32_DLL_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_DLL_Debug"
-# PROP Intermediate_Dir "Win32_DLL_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "example - Win32 LIB ASM Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "example___Win32_LIB_ASM_Release"
-# PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_LIB_ASM_Release"
-# PROP Intermediate_Dir "Win32_LIB_ASM_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "example - Win32 LIB ASM Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "example___Win32_LIB_ASM_Debug"
-# PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_LIB_ASM_Debug"
-# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "example - Win32 LIB Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "example___Win32_LIB_Release"
-# PROP BASE Intermediate_Dir "example___Win32_LIB_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_LIB_Release"
-# PROP Intermediate_Dir "Win32_LIB_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "example - Win32 LIB Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "example___Win32_LIB_Debug"
-# PROP BASE Intermediate_Dir "example___Win32_LIB_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_LIB_Debug"
-# PROP Intermediate_Dir "Win32_LIB_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "example - Win32 DLL ASM Release"
-# Name "example - Win32 DLL ASM Debug"
-# Name "example - Win32 DLL Release"
-# Name "example - Win32 DLL Debug"
-# Name "example - Win32 LIB ASM Release"
-# Name "example - Win32 LIB ASM Debug"
-# Name "example - Win32 LIB Release"
-# Name "example - Win32 LIB Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\example.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\zconf.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\zlib.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/compat/zlib/old/visualc6/minigzip.dsp b/compat/zlib/old/visualc6/minigzip.dsp
deleted file mode 100644
index 7103468..0000000
--- a/compat/zlib/old/visualc6/minigzip.dsp
+++ /dev/null
@@ -1,278 +0,0 @@
-# Microsoft Developer Studio Project File - Name="minigzip" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=minigzip - Win32 LIB Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "minigzip.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "minigzip.mak" CFG="minigzip - Win32 LIB Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "minigzip - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "minigzip - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE "minigzip - Win32 DLL Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "minigzip - Win32 DLL Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE "minigzip - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "minigzip - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE "minigzip - Win32 LIB Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "minigzip - Win32 LIB Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "minigzip - Win32 DLL ASM Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Release"
-# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_DLL_ASM_Release"
-# PROP Intermediate_Dir "Win32_DLL_ASM_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "minigzip - Win32 DLL ASM Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Debug"
-# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_DLL_ASM_Debug"
-# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "minigzip - Win32 DLL Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "minigzip___Win32_DLL_Release"
-# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_DLL_Release"
-# PROP Intermediate_Dir "Win32_DLL_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "minigzip - Win32 DLL Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "minigzip___Win32_DLL_Debug"
-# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_DLL_Debug"
-# PROP Intermediate_Dir "Win32_DLL_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "minigzip - Win32 LIB ASM Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Release"
-# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_LIB_ASM_Release"
-# PROP Intermediate_Dir "Win32_LIB_ASM_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "minigzip - Win32 LIB ASM Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Debug"
-# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_LIB_ASM_Debug"
-# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "minigzip - Win32 LIB Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "minigzip___Win32_LIB_Release"
-# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_LIB_Release"
-# PROP Intermediate_Dir "Win32_LIB_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "minigzip - Win32 LIB Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "minigzip___Win32_LIB_Debug"
-# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_LIB_Debug"
-# PROP Intermediate_Dir "Win32_LIB_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "minigzip - Win32 DLL ASM Release"
-# Name "minigzip - Win32 DLL ASM Debug"
-# Name "minigzip - Win32 DLL Release"
-# Name "minigzip - Win32 DLL Debug"
-# Name "minigzip - Win32 LIB ASM Release"
-# Name "minigzip - Win32 LIB ASM Debug"
-# Name "minigzip - Win32 LIB Release"
-# Name "minigzip - Win32 LIB Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\minigzip.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\zconf.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\zlib.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/compat/zlib/old/visualc6/zlib.dsp b/compat/zlib/old/visualc6/zlib.dsp
deleted file mode 100644
index 00f54ea..0000000
--- a/compat/zlib/old/visualc6/zlib.dsp
+++ /dev/null
@@ -1,621 +0,0 @@
-# Microsoft Developer Studio Project File - Name="zlib" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=zlib - Win32 LIB Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "zlib.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "zlib.mak" CFG="zlib - Win32 LIB Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "zlib - Win32 DLL ASM Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zlib - Win32 DLL ASM Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zlib - Win32 DLL Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zlib - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zlib - Win32 LIB ASM Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "zlib - Win32 LIB ASM Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE "zlib - Win32 LIB Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "zlib - Win32 LIB Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-
-!IF "$(CFG)" == "zlib - Win32 DLL ASM Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Release"
-# PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_DLL_ASM_Release"
-# PROP Intermediate_Dir "Win32_DLL_ASM_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c
-# SUBTRACT CPP /YX /Yc /Yu
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_ASM_Release\zlib1.dll"
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Debug"
-# PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_DLL_ASM_Debug"
-# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FR /FD /GZ /c
-# SUBTRACT CPP /YX /Yc /Yu
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_ASM_Debug\zlib1d.dll" /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "zlib___Win32_DLL_Release"
-# PROP BASE Intermediate_Dir "zlib___Win32_DLL_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_DLL_Release"
-# PROP Intermediate_Dir "Win32_DLL_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX /Yc /Yu
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_Release\zlib1.dll"
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "zlib___Win32_DLL_Debug"
-# PROP BASE Intermediate_Dir "zlib___Win32_DLL_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_DLL_Debug"
-# PROP Intermediate_Dir "Win32_DLL_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX /Yc /Yu
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_Debug\zlib1d.dll" /pdbtype:sept
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Release"
-# PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_LIB_ASM_Release"
-# PROP Intermediate_Dir "Win32_LIB_ASM_Release"
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c
-# SUBTRACT CPP /YX /Yc /Yu
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Debug"
-# PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_LIB_ASM_Debug"
-# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FR /FD /GZ /c
-# SUBTRACT CPP /YX /Yc /Yu
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"Win32_LIB_ASM_Debug\zlibd.lib"
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "zlib___Win32_LIB_Release"
-# PROP BASE Intermediate_Dir "zlib___Win32_LIB_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Win32_LIB_Release"
-# PROP Intermediate_Dir "Win32_LIB_Release"
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c
-# SUBTRACT CPP /YX /Yc /Yu
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "zlib___Win32_LIB_Debug"
-# PROP BASE Intermediate_Dir "zlib___Win32_LIB_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Win32_LIB_Debug"
-# PROP Intermediate_Dir "Win32_LIB_Debug"
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
-# SUBTRACT BASE CPP /YX /Yc /Yu
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c
-# SUBTRACT CPP /YX /Yc /Yu
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"Win32_LIB_Debug\zlibd.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "zlib - Win32 DLL ASM Release"
-# Name "zlib - Win32 DLL ASM Debug"
-# Name "zlib - Win32 DLL Release"
-# Name "zlib - Win32 DLL Debug"
-# Name "zlib - Win32 LIB ASM Release"
-# Name "zlib - Win32 LIB ASM Debug"
-# Name "zlib - Win32 LIB Release"
-# Name "zlib - Win32 LIB Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\adler32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\compress.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\crc32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\deflate.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gzclose.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gzlib.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gzread.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gzwrite.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\infback.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\inffast.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\inflate.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\inftrees.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\trees.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\uncompr.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\win32\zlib.def
-
-!IF "$(CFG)" == "zlib - Win32 DLL ASM Release"
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Release"
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
-
-# PROP Exclude_From_Build 1
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\zutil.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\crc32.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\deflate.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\inffast.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\inffixed.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\inflate.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\inftrees.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\trees.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\zconf.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\zlib.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\zutil.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# Begin Source File
-
-SOURCE=..\..\win32\zlib1.rc
-# End Source File
-# End Group
-# Begin Group "Assembler Files (Unsupported)"
-
-# PROP Default_Filter "asm;obj;c;cpp;cxx;h;hpp;hxx"
-# Begin Source File
-
-SOURCE=..\..\contrib\masmx86\gvmat32.asm
-
-!IF "$(CFG)" == "zlib - Win32 DLL ASM Release"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_DLL_ASM_Release
-InputPath=..\..\contrib\masmx86\gvmat32.asm
-InputName=gvmat32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_DLL_ASM_Debug
-InputPath=..\..\contrib\masmx86\gvmat32.asm
-InputName=gvmat32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Release"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_LIB_ASM_Release
-InputPath=..\..\contrib\masmx86\gvmat32.asm
-InputName=gvmat32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_LIB_ASM_Debug
-InputPath=..\..\contrib\masmx86\gvmat32.asm
-InputName=gvmat32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
-
-# PROP Exclude_From_Build 1
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\contrib\masmx86\gvmat32c.c
-
-!IF "$(CFG)" == "zlib - Win32 DLL ASM Release"
-
-# ADD CPP /I "..\.."
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
-
-# ADD CPP /I "..\.."
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Release"
-
-# PROP Exclude_From_Build 1
-# ADD CPP /I "..\.."
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
-
-# PROP Exclude_From_Build 1
-# ADD CPP /I "..\.."
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
-
-# ADD CPP /I "..\.."
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
-
-# ADD CPP /I "..\.."
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
-
-# PROP Exclude_From_Build 1
-# ADD CPP /I "..\.."
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
-
-# PROP Exclude_From_Build 1
-# ADD CPP /I "..\.."
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\contrib\masmx86\inffas32.asm
-
-!IF "$(CFG)" == "zlib - Win32 DLL ASM Release"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_DLL_ASM_Release
-InputPath=..\..\contrib\masmx86\inffas32.asm
-InputName=inffas32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_DLL_ASM_Debug
-InputPath=..\..\contrib\masmx86\inffas32.asm
-InputName=inffas32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Release"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_LIB_ASM_Release
-InputPath=..\..\contrib\masmx86\inffas32.asm
-InputName=inffas32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
-
-# Begin Custom Build - Assembling...
-IntDir=.\Win32_LIB_ASM_Debug
-InputPath=..\..\contrib\masmx86\inffas32.asm
-InputName=inffas32
-
-"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
-
-# End Custom Build
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
-
-# PROP Exclude_From_Build 1
-
-!ENDIF
-
-# End Source File
-# End Group
-# Begin Source File
-
-SOURCE=.\README.txt
-# End Source File
-# End Target
-# End Project
diff --git a/compat/zlib/old/visualc6/zlib.dsw b/compat/zlib/old/visualc6/zlib.dsw
deleted file mode 100644
index 3a771fc..0000000
--- a/compat/zlib/old/visualc6/zlib.dsw
+++ /dev/null
@@ -1,59 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "example"=.\example.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name zlib
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "minigzip"=.\minigzip.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name zlib
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "zlib"=.\zlib.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/compat/zlib/qnx/package.qpg b/compat/zlib/qnx/package.qpg
index 2bc63b2..aebf6e3 100644
--- a/compat/zlib/qnx/package.qpg
+++ b/compat/zlib/qnx/package.qpg
@@ -25,10 +25,10 @@
<QPG:Files>
<QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/>
<QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/>
- <QPG:Add file="../libz.so.1.2.5" install="/opt/lib/" user="root:bin" permission="644"/>
- <QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.5"/>
- <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.5"/>
- <QPG:Add file="../libz.so.1.2.5" install="/opt/lib/" component="slib"/>
+ <QPG:Add file="../libz.so.1.2.8" install="/opt/lib/" user="root:bin" permission="644"/>
+ <QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.8"/>
+ <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.8"/>
+ <QPG:Add file="../libz.so.1.2.8" install="/opt/lib/" component="slib"/>
</QPG:Files>
<QPG:PackageFilter>
@@ -63,7 +63,7 @@
</QPM:ProductDescription>
<QPM:ReleaseDescription>
- <QPM:ReleaseVersion>1.2.5</QPM:ReleaseVersion>
+ <QPM:ReleaseVersion>1.2.8</QPM:ReleaseVersion>
<QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
<QPM:ReleaseStability>Stable</QPM:ReleaseStability>
<QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>
diff --git a/compat/zlib/example.c b/compat/zlib/test/example.c
index c6c2905..138a699 100644
--- a/compat/zlib/example.c
+++ b/compat/zlib/test/example.c
@@ -1,9 +1,9 @@
/* example.c -- usage example of the zlib compression library
- * Copyright (C) 1995-2006 Jean-loup Gailly.
+ * Copyright (C) 1995-2006, 2011 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-/* @(#) $Id: example.c,v 1.3 2010/04/20 14:50:10 nijtmans Exp $ */
+/* @(#) $Id$ */
#include "zlib.h"
#include <stdio.h>
@@ -26,7 +26,7 @@
} \
}
-const char hello[] = "hello, hello!";
+z_const char hello[] = "hello, hello!";
/* "hello world" would be more standard, but the repeated "hello"
* stresses the compression code better, sorry...
*/
@@ -34,10 +34,6 @@ const char hello[] = "hello, hello!";
const char dictionary[] = "hello";
uLong dictId; /* Adler32 value of the dictionary */
-void test_compress OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_gzio OF((const char *fname,
- Byte *uncompr, uLong uncomprLen));
void test_deflate OF((Byte *compr, uLong comprLen));
void test_inflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
@@ -53,6 +49,39 @@ void test_dict_inflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
int main OF((int argc, char *argv[]));
+
+#ifdef Z_SOLO
+
+void *myalloc OF((void *, unsigned, unsigned));
+void myfree OF((void *, void *));
+
+void *myalloc(q, n, m)
+ void *q;
+ unsigned n, m;
+{
+ q = Z_NULL;
+ return calloc(n, m);
+}
+
+void myfree(void *q, void *p)
+{
+ q = Z_NULL;
+ free(p);
+}
+
+static alloc_func zalloc = myalloc;
+static free_func zfree = myfree;
+
+#else /* !Z_SOLO */
+
+static alloc_func zalloc = (alloc_func)0;
+static free_func zfree = (free_func)0;
+
+void test_compress OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_gzio OF((const char *fname,
+ Byte *uncompr, uLong uncomprLen));
+
/* ===========================================================================
* Test compress() and uncompress()
*/
@@ -163,6 +192,8 @@ void test_gzio(fname, uncompr, uncomprLen)
#endif
}
+#endif /* Z_SOLO */
+
/* ===========================================================================
* Test deflate() with small buffers
*/
@@ -174,14 +205,14 @@ void test_deflate(compr, comprLen)
int err;
uLong len = (uLong)strlen(hello)+1;
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
- c_stream.next_in = (Bytef*)hello;
+ c_stream.next_in = (z_const unsigned char *)hello;
c_stream.next_out = compr;
while (c_stream.total_in != len && c_stream.total_out < comprLen) {
@@ -213,8 +244,8 @@ void test_inflate(compr, comprLen, uncompr, uncomprLen)
strcpy((char*)uncompr, "garbage");
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
d_stream.opaque = (voidpf)0;
d_stream.next_in = compr;
@@ -252,8 +283,8 @@ void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
z_stream c_stream; /* compression stream */
int err;
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_BEST_SPEED);
@@ -309,8 +340,8 @@ void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
strcpy((char*)uncompr, "garbage");
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
d_stream.opaque = (voidpf)0;
d_stream.next_in = compr;
@@ -349,14 +380,14 @@ void test_flush(compr, comprLen)
int err;
uInt len = (uInt)strlen(hello)+1;
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
- c_stream.next_in = (Bytef*)hello;
+ c_stream.next_in = (z_const unsigned char *)hello;
c_stream.next_out = compr;
c_stream.avail_in = 3;
c_stream.avail_out = (uInt)*comprLen;
@@ -388,8 +419,8 @@ void test_sync(compr, comprLen, uncompr, uncomprLen)
strcpy((char*)uncompr, "garbage");
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
d_stream.opaque = (voidpf)0;
d_stream.next_in = compr;
@@ -430,22 +461,22 @@ void test_dict_deflate(compr, comprLen)
z_stream c_stream; /* compression stream */
int err;
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
+ c_stream.zalloc = zalloc;
+ c_stream.zfree = zfree;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
CHECK_ERR(err, "deflateInit");
err = deflateSetDictionary(&c_stream,
- (const Bytef*)dictionary, sizeof(dictionary));
+ (const Bytef*)dictionary, (int)sizeof(dictionary));
CHECK_ERR(err, "deflateSetDictionary");
dictId = c_stream.adler;
c_stream.next_out = compr;
c_stream.avail_out = (uInt)comprLen;
- c_stream.next_in = (Bytef*)hello;
+ c_stream.next_in = (z_const unsigned char *)hello;
c_stream.avail_in = (uInt)strlen(hello)+1;
err = deflate(&c_stream, Z_FINISH);
@@ -469,8 +500,8 @@ void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
strcpy((char*)uncompr, "garbage");
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
+ d_stream.zalloc = zalloc;
+ d_stream.zfree = zfree;
d_stream.opaque = (voidpf)0;
d_stream.next_in = compr;
@@ -491,7 +522,7 @@ void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
exit(1);
}
err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
- sizeof(dictionary));
+ (int)sizeof(dictionary));
}
CHECK_ERR(err, "inflate with dict");
}
@@ -540,10 +571,15 @@ int main(argc, argv)
printf("out of memory\n");
exit(1);
}
+
+#ifdef Z_SOLO
+ argc = strlen(argv[0]);
+#else
test_compress(compr, comprLen, uncompr, uncomprLen);
test_gzio((argc > 1 ? argv[1] : TESTFILE),
uncompr, uncomprLen);
+#endif
test_deflate(compr, comprLen);
test_inflate(compr, comprLen, uncompr, uncomprLen);
diff --git a/compat/zlib/test/infcover.c b/compat/zlib/test/infcover.c
new file mode 100644
index 0000000..fe3d920
--- /dev/null
+++ b/compat/zlib/test/infcover.c
@@ -0,0 +1,671 @@
+/* infcover.c -- test zlib's inflate routines with full code coverage
+ * Copyright (C) 2011 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* to use, do: ./configure --cover && make cover */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "zlib.h"
+
+/* get definition of internal structure so we can mess with it (see pull()),
+ and so we can call inflate_trees() (see cover5()) */
+#define ZLIB_INTERNAL
+#include "inftrees.h"
+#include "inflate.h"
+
+#define local static
+
+/* -- memory tracking routines -- */
+
+/*
+ These memory tracking routines are provided to zlib and track all of zlib's
+ allocations and deallocations, check for LIFO operations, keep a current
+ and high water mark of total bytes requested, optionally set a limit on the
+ total memory that can be allocated, and when done check for memory leaks.
+
+ They are used as follows:
+
+ z_stream strm;
+ mem_setup(&strm) initializes the memory tracking and sets the
+ zalloc, zfree, and opaque members of strm to use
+ memory tracking for all zlib operations on strm
+ mem_limit(&strm, limit) sets a limit on the total bytes requested -- a
+ request that exceeds this limit will result in an
+ allocation failure (returns NULL) -- setting the
+ limit to zero means no limit, which is the default
+ after mem_setup()
+ mem_used(&strm, "msg") prints to stderr "msg" and the total bytes used
+ mem_high(&strm, "msg") prints to stderr "msg" and the high water mark
+ mem_done(&strm, "msg") ends memory tracking, releases all allocations
+ for the tracking as well as leaked zlib blocks, if
+ any. If there was anything unusual, such as leaked
+ blocks, non-FIFO frees, or frees of addresses not
+ allocated, then "msg" and information about the
+ problem is printed to stderr. If everything is
+ normal, nothing is printed. mem_done resets the
+ strm members to Z_NULL to use the default memory
+ allocation routines on the next zlib initialization
+ using strm.
+ */
+
+/* these items are strung together in a linked list, one for each allocation */
+struct mem_item {
+ void *ptr; /* pointer to allocated memory */
+ size_t size; /* requested size of allocation */
+ struct mem_item *next; /* pointer to next item in list, or NULL */
+};
+
+/* this structure is at the root of the linked list, and tracks statistics */
+struct mem_zone {
+ struct mem_item *first; /* pointer to first item in list, or NULL */
+ size_t total, highwater; /* total allocations, and largest total */
+ size_t limit; /* memory allocation limit, or 0 if no limit */
+ int notlifo, rogue; /* counts of non-LIFO frees and rogue frees */
+};
+
+/* memory allocation routine to pass to zlib */
+local void *mem_alloc(void *mem, unsigned count, unsigned size)
+{
+ void *ptr;
+ struct mem_item *item;
+ struct mem_zone *zone = mem;
+ size_t len = count * (size_t)size;
+
+ /* induced allocation failure */
+ if (zone == NULL || (zone->limit && zone->total + len > zone->limit))
+ return NULL;
+
+ /* perform allocation using the standard library, fill memory with a
+ non-zero value to make sure that the code isn't depending on zeros */
+ ptr = malloc(len);
+ if (ptr == NULL)
+ return NULL;
+ memset(ptr, 0xa5, len);
+
+ /* create a new item for the list */
+ item = malloc(sizeof(struct mem_item));
+ if (item == NULL) {
+ free(ptr);
+ return NULL;
+ }
+ item->ptr = ptr;
+ item->size = len;
+
+ /* insert item at the beginning of the list */
+ item->next = zone->first;
+ zone->first = item;
+
+ /* update the statistics */
+ zone->total += item->size;
+ if (zone->total > zone->highwater)
+ zone->highwater = zone->total;
+
+ /* return the allocated memory */
+ return ptr;
+}
+
+/* memory free routine to pass to zlib */
+local void mem_free(void *mem, void *ptr)
+{
+ struct mem_item *item, *next;
+ struct mem_zone *zone = mem;
+
+ /* if no zone, just do a free */
+ if (zone == NULL) {
+ free(ptr);
+ return;
+ }
+
+ /* point next to the item that matches ptr, or NULL if not found -- remove
+ the item from the linked list if found */
+ next = zone->first;
+ if (next) {
+ if (next->ptr == ptr)
+ zone->first = next->next; /* first one is it, remove from list */
+ else {
+ do { /* search the linked list */
+ item = next;
+ next = item->next;
+ } while (next != NULL && next->ptr != ptr);
+ if (next) { /* if found, remove from linked list */
+ item->next = next->next;
+ zone->notlifo++; /* not a LIFO free */
+ }
+
+ }
+ }
+
+ /* if found, update the statistics and free the item */
+ if (next) {
+ zone->total -= next->size;
+ free(next);
+ }
+
+ /* if not found, update the rogue count */
+ else
+ zone->rogue++;
+
+ /* in any case, do the requested free with the standard library function */
+ free(ptr);
+}
+
+/* set up a controlled memory allocation space for monitoring, set the stream
+ parameters to the controlled routines, with opaque pointing to the space */
+local void mem_setup(z_stream *strm)
+{
+ struct mem_zone *zone;
+
+ zone = malloc(sizeof(struct mem_zone));
+ assert(zone != NULL);
+ zone->first = NULL;
+ zone->total = 0;
+ zone->highwater = 0;
+ zone->limit = 0;
+ zone->notlifo = 0;
+ zone->rogue = 0;
+ strm->opaque = zone;
+ strm->zalloc = mem_alloc;
+ strm->zfree = mem_free;
+}
+
+/* set a limit on the total memory allocation, or 0 to remove the limit */
+local void mem_limit(z_stream *strm, size_t limit)
+{
+ struct mem_zone *zone = strm->opaque;
+
+ zone->limit = limit;
+}
+
+/* show the current total requested allocations in bytes */
+local void mem_used(z_stream *strm, char *prefix)
+{
+ struct mem_zone *zone = strm->opaque;
+
+ fprintf(stderr, "%s: %lu allocated\n", prefix, zone->total);
+}
+
+/* show the high water allocation in bytes */
+local void mem_high(z_stream *strm, char *prefix)
+{
+ struct mem_zone *zone = strm->opaque;
+
+ fprintf(stderr, "%s: %lu high water mark\n", prefix, zone->highwater);
+}
+
+/* release the memory allocation zone -- if there are any surprises, notify */
+local void mem_done(z_stream *strm, char *prefix)
+{
+ int count = 0;
+ struct mem_item *item, *next;
+ struct mem_zone *zone = strm->opaque;
+
+ /* show high water mark */
+ mem_high(strm, prefix);
+
+ /* free leftover allocations and item structures, if any */
+ item = zone->first;
+ while (item != NULL) {
+ free(item->ptr);
+ next = item->next;
+ free(item);
+ item = next;
+ count++;
+ }
+
+ /* issue alerts about anything unexpected */
+ if (count || zone->total)
+ fprintf(stderr, "** %s: %lu bytes in %d blocks not freed\n",
+ prefix, zone->total, count);
+ if (zone->notlifo)
+ fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo);
+ if (zone->rogue)
+ fprintf(stderr, "** %s: %d frees not recognized\n",
+ prefix, zone->rogue);
+
+ /* free the zone and delete from the stream */
+ free(zone);
+ strm->opaque = Z_NULL;
+ strm->zalloc = Z_NULL;
+ strm->zfree = Z_NULL;
+}
+
+/* -- inflate test routines -- */
+
+/* Decode a hexadecimal string, set *len to length, in[] to the bytes. This
+ decodes liberally, in that hex digits can be adjacent, in which case two in
+ a row writes a byte. Or they can delimited by any non-hex character, where
+ the delimiters are ignored except when a single hex digit is followed by a
+ delimiter in which case that single digit writes a byte. The returned
+ data is allocated and must eventually be freed. NULL is returned if out of
+ memory. If the length is not needed, then len can be NULL. */
+local unsigned char *h2b(const char *hex, unsigned *len)
+{
+ unsigned char *in;
+ unsigned next, val;
+
+ in = malloc((strlen(hex) + 1) >> 1);
+ if (in == NULL)
+ return NULL;
+ next = 0;
+ val = 1;
+ do {
+ if (*hex >= '0' && *hex <= '9')
+ val = (val << 4) + *hex - '0';
+ else if (*hex >= 'A' && *hex <= 'F')
+ val = (val << 4) + *hex - 'A' + 10;
+ else if (*hex >= 'a' && *hex <= 'f')
+ val = (val << 4) + *hex - 'a' + 10;
+ else if (val != 1 && val < 32) /* one digit followed by delimiter */
+ val += 240; /* make it look like two digits */
+ if (val > 255) { /* have two digits */
+ in[next++] = val & 0xff; /* save the decoded byte */
+ val = 1; /* start over */
+ }
+ } while (*hex++); /* go through the loop with the terminating null */
+ if (len != NULL)
+ *len = next;
+ in = reallocf(in, next);
+ return in;
+}
+
+/* generic inflate() run, where hex is the hexadecimal input data, what is the
+ text to include in an error message, step is how much input data to feed
+ inflate() on each call, or zero to feed it all, win is the window bits
+ parameter to inflateInit2(), len is the size of the output buffer, and err
+ is the error code expected from the first inflate() call (the second
+ inflate() call is expected to return Z_STREAM_END). If win is 47, then
+ header information is collected with inflateGetHeader(). If a zlib stream
+ is looking for a dictionary, then an empty dictionary is provided.
+ inflate() is run until all of the input data is consumed. */
+local void inf(char *hex, char *what, unsigned step, int win, unsigned len,
+ int err)
+{
+ int ret;
+ unsigned have;
+ unsigned char *in, *out;
+ z_stream strm, copy;
+ gz_header head;
+
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit2(&strm, win);
+ if (ret != Z_OK) {
+ mem_done(&strm, what);
+ return;
+ }
+ out = malloc(len); assert(out != NULL);
+ if (win == 47) {
+ head.extra = out;
+ head.extra_max = len;
+ head.name = out;
+ head.name_max = len;
+ head.comment = out;
+ head.comm_max = len;
+ ret = inflateGetHeader(&strm, &head); assert(ret == Z_OK);
+ }
+ in = h2b(hex, &have); assert(in != NULL);
+ if (step == 0 || step > have)
+ step = have;
+ strm.avail_in = step;
+ have -= step;
+ strm.next_in = in;
+ do {
+ strm.avail_out = len;
+ strm.next_out = out;
+ ret = inflate(&strm, Z_NO_FLUSH); assert(err == 9 || ret == err);
+ if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT)
+ break;
+ if (ret == Z_NEED_DICT) {
+ ret = inflateSetDictionary(&strm, in, 1);
+ assert(ret == Z_DATA_ERROR);
+ mem_limit(&strm, 1);
+ ret = inflateSetDictionary(&strm, out, 0);
+ assert(ret == Z_MEM_ERROR);
+ mem_limit(&strm, 0);
+ ((struct inflate_state *)strm.state)->mode = DICT;
+ ret = inflateSetDictionary(&strm, out, 0);
+ assert(ret == Z_OK);
+ ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_BUF_ERROR);
+ }
+ ret = inflateCopy(&copy, &strm); assert(ret == Z_OK);
+ ret = inflateEnd(&copy); assert(ret == Z_OK);
+ err = 9; /* don't care next time around */
+ have += strm.avail_in;
+ strm.avail_in = step > have ? have : step;
+ have -= strm.avail_in;
+ } while (strm.avail_in);
+ free(in);
+ free(out);
+ ret = inflateReset2(&strm, -8); assert(ret == Z_OK);
+ ret = inflateEnd(&strm); assert(ret == Z_OK);
+ mem_done(&strm, what);
+}
+
+/* cover all of the lines in inflate.c up to inflate() */
+local void cover_support(void)
+{
+ int ret;
+ z_stream strm;
+
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit(&strm); assert(ret == Z_OK);
+ mem_used(&strm, "inflate init");
+ ret = inflatePrime(&strm, 5, 31); assert(ret == Z_OK);
+ ret = inflatePrime(&strm, -1, 0); assert(ret == Z_OK);
+ ret = inflateSetDictionary(&strm, Z_NULL, 0);
+ assert(ret == Z_STREAM_ERROR);
+ ret = inflateEnd(&strm); assert(ret == Z_OK);
+ mem_done(&strm, "prime");
+
+ inf("63 0", "force window allocation", 0, -15, 1, Z_OK);
+ inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK);
+ inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK);
+ inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END);
+ inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR);
+
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream));
+ assert(ret == Z_VERSION_ERROR);
+ mem_done(&strm, "wrong version");
+
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit(&strm); assert(ret == Z_OK);
+ ret = inflateEnd(&strm); assert(ret == Z_OK);
+ fputs("inflate built-in memory routines\n", stderr);
+}
+
+/* cover all inflate() header and trailer cases and code after inflate() */
+local void cover_wrap(void)
+{
+ int ret;
+ z_stream strm, copy;
+ unsigned char dict[257];
+
+ ret = inflate(Z_NULL, 0); assert(ret == Z_STREAM_ERROR);
+ ret = inflateEnd(Z_NULL); assert(ret == Z_STREAM_ERROR);
+ ret = inflateCopy(Z_NULL, Z_NULL); assert(ret == Z_STREAM_ERROR);
+ fputs("inflate bad parameters\n", stderr);
+
+ inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR);
+ inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR);
+ inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR);
+ inf("8 99", "set window size from header", 0, 0, 0, Z_OK);
+ inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR);
+ inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END);
+ inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1,
+ Z_DATA_ERROR);
+ inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length",
+ 0, 47, 0, Z_STREAM_END);
+ inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR);
+ inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT);
+ inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK);
+
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit2(&strm, -8);
+ strm.avail_in = 2;
+ strm.next_in = (void *)"\x63";
+ strm.avail_out = 1;
+ strm.next_out = (void *)&ret;
+ mem_limit(&strm, 1);
+ ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
+ ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
+ mem_limit(&strm, 0);
+ memset(dict, 0, 257);
+ ret = inflateSetDictionary(&strm, dict, 257);
+ assert(ret == Z_OK);
+ mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256);
+ ret = inflatePrime(&strm, 16, 0); assert(ret == Z_OK);
+ strm.avail_in = 2;
+ strm.next_in = (void *)"\x80";
+ ret = inflateSync(&strm); assert(ret == Z_DATA_ERROR);
+ ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR);
+ strm.avail_in = 4;
+ strm.next_in = (void *)"\0\0\xff\xff";
+ ret = inflateSync(&strm); assert(ret == Z_OK);
+ (void)inflateSyncPoint(&strm);
+ ret = inflateCopy(&copy, &strm); assert(ret == Z_MEM_ERROR);
+ mem_limit(&strm, 0);
+ ret = inflateUndermine(&strm, 1); assert(ret == Z_DATA_ERROR);
+ (void)inflateMark(&strm);
+ ret = inflateEnd(&strm); assert(ret == Z_OK);
+ mem_done(&strm, "miscellaneous, force memory errors");
+}
+
+/* input and output functions for inflateBack() */
+local unsigned pull(void *desc, unsigned char **buf)
+{
+ static unsigned int next = 0;
+ static unsigned char dat[] = {0x63, 0, 2, 0};
+ struct inflate_state *state;
+
+ if (desc == Z_NULL) {
+ next = 0;
+ return 0; /* no input (already provided at next_in) */
+ }
+ state = (void *)((z_stream *)desc)->state;
+ if (state != Z_NULL)
+ state->mode = SYNC; /* force an otherwise impossible situation */
+ return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0;
+}
+
+local int push(void *desc, unsigned char *buf, unsigned len)
+{
+ buf += len;
+ return desc != Z_NULL; /* force error if desc not null */
+}
+
+/* cover inflateBack() up to common deflate data cases and after those */
+local void cover_back(void)
+{
+ int ret;
+ z_stream strm;
+ unsigned char win[32768];
+
+ ret = inflateBackInit_(Z_NULL, 0, win, 0, 0);
+ assert(ret == Z_VERSION_ERROR);
+ ret = inflateBackInit(Z_NULL, 0, win); assert(ret == Z_STREAM_ERROR);
+ ret = inflateBack(Z_NULL, Z_NULL, Z_NULL, Z_NULL, Z_NULL);
+ assert(ret == Z_STREAM_ERROR);
+ ret = inflateBackEnd(Z_NULL); assert(ret == Z_STREAM_ERROR);
+ fputs("inflateBack bad parameters\n", stderr);
+
+ mem_setup(&strm);
+ ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK);
+ strm.avail_in = 2;
+ strm.next_in = (void *)"\x03";
+ ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
+ assert(ret == Z_STREAM_END);
+ /* force output error */
+ strm.avail_in = 3;
+ strm.next_in = (void *)"\x63\x00";
+ ret = inflateBack(&strm, pull, Z_NULL, push, &strm);
+ assert(ret == Z_BUF_ERROR);
+ /* force mode error by mucking with state */
+ ret = inflateBack(&strm, pull, &strm, push, Z_NULL);
+ assert(ret == Z_STREAM_ERROR);
+ ret = inflateBackEnd(&strm); assert(ret == Z_OK);
+ mem_done(&strm, "inflateBack bad state");
+
+ ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK);
+ ret = inflateBackEnd(&strm); assert(ret == Z_OK);
+ fputs("inflateBack built-in memory routines\n", stderr);
+}
+
+/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */
+local int try(char *hex, char *id, int err)
+{
+ int ret;
+ unsigned len, size;
+ unsigned char *in, *out, *win;
+ char *prefix;
+ z_stream strm;
+
+ /* convert to hex */
+ in = h2b(hex, &len);
+ assert(in != NULL);
+
+ /* allocate work areas */
+ size = len << 3;
+ out = malloc(size);
+ assert(out != NULL);
+ win = malloc(32768);
+ assert(win != NULL);
+ prefix = malloc(strlen(id) + 6);
+ assert(prefix != NULL);
+
+ /* first with inflate */
+ strcpy(prefix, id);
+ strcat(prefix, "-late");
+ mem_setup(&strm);
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit2(&strm, err < 0 ? 47 : -15);
+ assert(ret == Z_OK);
+ strm.avail_in = len;
+ strm.next_in = in;
+ do {
+ strm.avail_out = size;
+ strm.next_out = out;
+ ret = inflate(&strm, Z_TREES);
+ assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR);
+ if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT)
+ break;
+ } while (strm.avail_in || strm.avail_out == 0);
+ if (err) {
+ assert(ret == Z_DATA_ERROR);
+ assert(strcmp(id, strm.msg) == 0);
+ }
+ inflateEnd(&strm);
+ mem_done(&strm, prefix);
+
+ /* then with inflateBack */
+ if (err >= 0) {
+ strcpy(prefix, id);
+ strcat(prefix, "-back");
+ mem_setup(&strm);
+ ret = inflateBackInit(&strm, 15, win);
+ assert(ret == Z_OK);
+ strm.avail_in = len;
+ strm.next_in = in;
+ ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
+ assert(ret != Z_STREAM_ERROR);
+ if (err) {
+ assert(ret == Z_DATA_ERROR);
+ assert(strcmp(id, strm.msg) == 0);
+ }
+ inflateBackEnd(&strm);
+ mem_done(&strm, prefix);
+ }
+
+ /* clean up */
+ free(prefix);
+ free(win);
+ free(out);
+ free(in);
+ return ret;
+}
+
+/* cover deflate data cases in both inflate() and inflateBack() */
+local void cover_inflate(void)
+{
+ try("0 0 0 0 0", "invalid stored block lengths", 1);
+ try("3 0", "fixed", 0);
+ try("6", "invalid block type", 1);
+ try("1 1 0 fe ff 0", "stored", 0);
+ try("fc 0 0", "too many length or distance symbols", 1);
+ try("4 0 fe ff", "invalid code lengths set", 1);
+ try("4 0 24 49 0", "invalid bit length repeat", 1);
+ try("4 0 24 e9 ff ff", "invalid bit length repeat", 1);
+ try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1);
+ try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0",
+ "invalid literal/lengths set", 1);
+ try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1);
+ try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1);
+ try("2 7e ff ff", "invalid distance code", 1);
+ try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1);
+
+ /* also trailer mismatch just in inflate() */
+ try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1);
+ try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1",
+ "incorrect length check", -1);
+ try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0);
+ try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f",
+ "long code", 0);
+ try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0);
+ try("ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c",
+ "long distance and extra", 0);
+ try("ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0);
+ inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258,
+ Z_STREAM_END);
+ inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK);
+}
+
+/* cover remaining lines in inftrees.c */
+local void cover_trees(void)
+{
+ int ret;
+ unsigned bits;
+ unsigned short lens[16], work[16];
+ code *next, table[ENOUGH_DISTS];
+
+ /* we need to call inflate_table() directly in order to manifest not-
+ enough errors, since zlib insures that enough is always enough */
+ for (bits = 0; bits < 15; bits++)
+ lens[bits] = (unsigned short)(bits + 1);
+ lens[15] = 15;
+ next = table;
+ bits = 15;
+ ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
+ assert(ret == 1);
+ next = table;
+ bits = 1;
+ ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
+ assert(ret == 1);
+ fputs("inflate_table not enough errors\n", stderr);
+}
+
+/* cover remaining inffast.c decoding and window copying */
+local void cover_fast(void)
+{
+ inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68"
+ " ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR);
+ inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49"
+ " 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258,
+ Z_DATA_ERROR);
+ inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258,
+ Z_DATA_ERROR);
+ inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258,
+ Z_DATA_ERROR);
+ inf("d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0",
+ "fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR);
+ inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK);
+ inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0",
+ "contiguous and wrap around window", 6, -8, 259, Z_OK);
+ inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259,
+ Z_STREAM_END);
+}
+
+int main(void)
+{
+ fprintf(stderr, "%s\n", zlibVersion());
+ cover_support();
+ cover_wrap();
+ cover_back();
+ cover_inflate();
+ cover_trees();
+ cover_fast();
+ return 0;
+}
diff --git a/compat/zlib/minigzip.c b/compat/zlib/test/minigzip.c
index 4f64c9a..b3025a4 100644
--- a/compat/zlib/minigzip.c
+++ b/compat/zlib/test/minigzip.c
@@ -1,5 +1,5 @@
/* minigzip.c -- simulate gzip using the zlib compression library
- * Copyright (C) 1995-2006, 2010 Jean-loup Gailly.
+ * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -13,7 +13,7 @@
* or in pipe mode.
*/
-/* @(#) $Id: minigzip.c,v 1.3 2010/04/20 14:50:10 nijtmans Exp $ */
+/* @(#) $Id$ */
#include "zlib.h"
#include <stdio.h>
@@ -40,6 +40,10 @@
# define SET_BINARY_MODE(file)
#endif
+#ifdef _MSC_VER
+# define snprintf _snprintf
+#endif
+
#ifdef VMS
# define unlink delete
# define GZ_SUFFIX "-gz"
@@ -138,6 +142,197 @@ static void pwinerror (s)
# define local
#endif
+#ifdef Z_SOLO
+/* for Z_SOLO, create simplified gz* functions using deflate and inflate */
+
+#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
+# include <unistd.h> /* for unlink() */
+#endif
+
+void *myalloc OF((void *, unsigned, unsigned));
+void myfree OF((void *, void *));
+
+void *myalloc(q, n, m)
+ void *q;
+ unsigned n, m;
+{
+ q = Z_NULL;
+ return calloc(n, m);
+}
+
+void myfree(q, p)
+ void *q, *p;
+{
+ q = Z_NULL;
+ free(p);
+}
+
+typedef struct gzFile_s {
+ FILE *file;
+ int write;
+ int err;
+ char *msg;
+ z_stream strm;
+} *gzFile;
+
+gzFile gzopen OF((const char *, const char *));
+gzFile gzdopen OF((int, const char *));
+gzFile gz_open OF((const char *, int, const char *));
+
+gzFile gzopen(path, mode)
+const char *path;
+const char *mode;
+{
+ return gz_open(path, -1, mode);
+}
+
+gzFile gzdopen(fd, mode)
+int fd;
+const char *mode;
+{
+ return gz_open(NULL, fd, mode);
+}
+
+gzFile gz_open(path, fd, mode)
+ const char *path;
+ int fd;
+ const char *mode;
+{
+ gzFile gz;
+ int ret;
+
+ gz = malloc(sizeof(struct gzFile_s));
+ if (gz == NULL)
+ return NULL;
+ gz->write = strchr(mode, 'w') != NULL;
+ gz->strm.zalloc = myalloc;
+ gz->strm.zfree = myfree;
+ gz->strm.opaque = Z_NULL;
+ if (gz->write)
+ ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
+ else {
+ gz->strm.next_in = 0;
+ gz->strm.avail_in = Z_NULL;
+ ret = inflateInit2(&(gz->strm), 15 + 16);
+ }
+ if (ret != Z_OK) {
+ free(gz);
+ return NULL;
+ }
+ gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
+ fopen(path, gz->write ? "wb" : "rb");
+ if (gz->file == NULL) {
+ gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
+ free(gz);
+ return NULL;
+ }
+ gz->err = 0;
+ gz->msg = "";
+ return gz;
+}
+
+int gzwrite OF((gzFile, const void *, unsigned));
+
+int gzwrite(gz, buf, len)
+ gzFile gz;
+ const void *buf;
+ unsigned len;
+{
+ z_stream *strm;
+ unsigned char out[BUFLEN];
+
+ if (gz == NULL || !gz->write)
+ return 0;
+ strm = &(gz->strm);
+ strm->next_in = (void *)buf;
+ strm->avail_in = len;
+ do {
+ strm->next_out = out;
+ strm->avail_out = BUFLEN;
+ (void)deflate(strm, Z_NO_FLUSH);
+ fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
+ } while (strm->avail_out == 0);
+ return len;
+}
+
+int gzread OF((gzFile, void *, unsigned));
+
+int gzread(gz, buf, len)
+ gzFile gz;
+ void *buf;
+ unsigned len;
+{
+ int ret;
+ unsigned got;
+ unsigned char in[1];
+ z_stream *strm;
+
+ if (gz == NULL || gz->write)
+ return 0;
+ if (gz->err)
+ return 0;
+ strm = &(gz->strm);
+ strm->next_out = (void *)buf;
+ strm->avail_out = len;
+ do {
+ got = fread(in, 1, 1, gz->file);
+ if (got == 0)
+ break;
+ strm->next_in = in;
+ strm->avail_in = 1;
+ ret = inflate(strm, Z_NO_FLUSH);
+ if (ret == Z_DATA_ERROR) {
+ gz->err = Z_DATA_ERROR;
+ gz->msg = strm->msg;
+ return 0;
+ }
+ if (ret == Z_STREAM_END)
+ inflateReset(strm);
+ } while (strm->avail_out);
+ return len - strm->avail_out;
+}
+
+int gzclose OF((gzFile));
+
+int gzclose(gz)
+ gzFile gz;
+{
+ z_stream *strm;
+ unsigned char out[BUFLEN];
+
+ if (gz == NULL)
+ return Z_STREAM_ERROR;
+ strm = &(gz->strm);
+ if (gz->write) {
+ strm->next_in = Z_NULL;
+ strm->avail_in = 0;
+ do {
+ strm->next_out = out;
+ strm->avail_out = BUFLEN;
+ (void)deflate(strm, Z_FINISH);
+ fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
+ } while (strm->avail_out == 0);
+ deflateEnd(strm);
+ }
+ else
+ inflateEnd(strm);
+ fclose(gz->file);
+ free(gz);
+ return Z_OK;
+}
+
+const char *gzerror OF((gzFile, int *));
+
+const char *gzerror(gz, err)
+ gzFile gz;
+ int *err;
+{
+ *err = gz->err;
+ return gz->msg;
+}
+
+#endif
+
char *prog;
void error OF((const char *msg));
@@ -272,8 +467,12 @@ void file_compress(file, mode)
exit(1);
}
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX);
+#else
strcpy(outfile, file);
strcat(outfile, GZ_SUFFIX);
+#endif
in = fopen(file, "rb");
if (in == NULL) {
@@ -308,7 +507,11 @@ void file_uncompress(file)
exit(1);
}
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(buf, sizeof(buf), "%s", file);
+#else
strcpy(buf, file);
+#endif
if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
infile = file;
@@ -317,7 +520,11 @@ void file_uncompress(file)
} else {
outfile = file;
infile = buf;
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX);
+#else
strcat(infile, GZ_SUFFIX);
+#endif
}
in = gzopen(infile, "rb");
if (in == NULL) {
@@ -355,7 +562,11 @@ int main(argc, argv)
gzFile file;
char *bname, outmode[20];
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ snprintf(outmode, sizeof(outmode), "%s", "wb6 ");
+#else
strcpy(outmode, "wb6 ");
+#endif
prog = argv[0];
bname = strrchr(argv[0], '/');
diff --git a/compat/zlib/treebuild.xml b/compat/zlib/treebuild.xml
index 6b8f542..38d29d7 100644
--- a/compat/zlib/treebuild.xml
+++ b/compat/zlib/treebuild.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" ?>
-<package name="zlib" version="1.2.5">
- <library name="zlib" dlversion="1.2.5" dlname="z">
+<package name="zlib" version="1.2.8">
+ <library name="zlib" dlversion="1.2.8" dlname="z">
<property name="description"> zip compression library </property>
<property name="include-target-dir" value="$(@PACKAGE/install-includedir)" />
diff --git a/compat/zlib/trees.c b/compat/zlib/trees.c
index b207380..1fd7759 100644
--- a/compat/zlib/trees.c
+++ b/compat/zlib/trees.c
@@ -1,5 +1,5 @@
/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2010 Jean-loup Gailly
+ * Copyright (C) 1995-2012 Jean-loup Gailly
* detect_data_type() function provided freely by Cosmin Truta, 2006
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -30,7 +30,7 @@
* Addison-Wesley, 1983. ISBN 0-201-06672-6.
*/
-/* @(#) $Id: trees.c,v 1.3 2010/04/20 14:50:10 nijtmans Exp $ */
+/* @(#) $Id$ */
/* #define GEN_TREES_H */
@@ -74,11 +74,6 @@ local const uch bl_order[BL_CODES]
* probability, to avoid transmitting the lengths for unused bit length codes.
*/
-#define Buf_size (8 * 2*sizeof(char))
-/* Number of bits used within bi_buf. (bi_buf might be implemented on
- * more than 16 bits on some systems.)
- */
-
/* ===========================================================================
* Local data. These are initialized only once.
*/
@@ -151,8 +146,8 @@ local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
local int build_bl_tree OF((deflate_state *s));
local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
- ct_data *dtree));
+local void compress_block OF((deflate_state *s, const ct_data *ltree,
+ const ct_data *dtree));
local int detect_data_type OF((deflate_state *s));
local unsigned bi_reverse OF((unsigned value, int length));
local void bi_windup OF((deflate_state *s));
@@ -399,7 +394,6 @@ void ZLIB_INTERNAL _tr_init(s)
s->bi_buf = 0;
s->bi_valid = 0;
- s->last_eob_len = 8; /* enough lookahead for inflate */
#ifdef DEBUG
s->compressed_len = 0L;
s->bits_sent = 0L;
@@ -883,15 +877,17 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
}
/* ===========================================================================
+ * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
+ */
+void ZLIB_INTERNAL _tr_flush_bits(s)
+ deflate_state *s;
+{
+ bi_flush(s);
+}
+
+/* ===========================================================================
* Send one empty static block to give enough lookahead for inflate.
* This takes 10 bits, of which 7 may remain in the bit buffer.
- * The current inflate code requires 9 bits of lookahead. If the
- * last two codes for the previous block (real code plus EOB) were coded
- * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
- * the last real code. In this case we send two empty static blocks instead
- * of one. (There are no problems if the previous block is stored or fixed.)
- * To simplify the code, we assume the worst case of last real code encoded
- * on one bit only.
*/
void ZLIB_INTERNAL _tr_align(s)
deflate_state *s;
@@ -902,20 +898,6 @@ void ZLIB_INTERNAL _tr_align(s)
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
#endif
bi_flush(s);
- /* Of the 10 bits for the empty block, we have already sent
- * (10 - bi_valid) bits. The lookahead for the last real code (before
- * the EOB of the previous block) was thus at least one plus the length
- * of the EOB plus what we have just sent of the empty static block.
- */
- if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L;
-#endif
- bi_flush(s);
- }
- s->last_eob_len = 7;
}
/* ===========================================================================
@@ -990,7 +972,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
} else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
#endif
send_bits(s, (STATIC_TREES<<1)+last, 3);
- compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+ compress_block(s, (const ct_data *)static_ltree,
+ (const ct_data *)static_dtree);
#ifdef DEBUG
s->compressed_len += 3 + s->static_len;
#endif
@@ -998,7 +981,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
send_bits(s, (DYN_TREES<<1)+last, 3);
send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
max_blindex+1);
- compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+ compress_block(s, (const ct_data *)s->dyn_ltree,
+ (const ct_data *)s->dyn_dtree);
#ifdef DEBUG
s->compressed_len += 3 + s->opt_len;
#endif
@@ -1075,8 +1059,8 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
*/
local void compress_block(s, ltree, dtree)
deflate_state *s;
- ct_data *ltree; /* literal tree */
- ct_data *dtree; /* distance tree */
+ const ct_data *ltree; /* literal tree */
+ const ct_data *dtree; /* distance tree */
{
unsigned dist; /* distance of matched string */
int lc; /* match length or unmatched char (if dist == 0) */
@@ -1118,7 +1102,6 @@ local void compress_block(s, ltree, dtree)
} while (lx < s->last_lit);
send_code(s, END_BLOCK, ltree);
- s->last_eob_len = ltree[END_BLOCK].Len;
}
/* ===========================================================================
@@ -1226,7 +1209,6 @@ local void copy_block(s, buf, len, header)
int header; /* true if block header must be written */
{
bi_windup(s); /* align on byte boundary */
- s->last_eob_len = 8; /* enough lookahead for inflate */
if (header) {
put_short(s, (ush)len);
diff --git a/compat/zlib/uncompr.c b/compat/zlib/uncompr.c
index 5cbf08f..242e949 100644
--- a/compat/zlib/uncompr.c
+++ b/compat/zlib/uncompr.c
@@ -3,7 +3,7 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-/* @(#) $Id: uncompr.c,v 1.3 2010/04/20 14:50:10 nijtmans Exp $ */
+/* @(#) $Id$ */
#define ZLIB_INTERNAL
#include "zlib.h"
@@ -30,7 +30,7 @@ int ZEXPORT uncompress (dest, destLen, source, sourceLen)
z_stream stream;
int err;
- stream.next_in = (Bytef*)source;
+ stream.next_in = (z_const Bytef *)source;
stream.avail_in = (uInt)sourceLen;
/* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
diff --git a/compat/zlib/win32/Makefile.bor b/compat/zlib/win32/Makefile.bor
index 3981d42..d152bbb 100644
--- a/compat/zlib/win32/Makefile.bor
+++ b/compat/zlib/win32/Makefile.bor
@@ -74,9 +74,9 @@ uncompr.obj: uncompr.c zlib.h zconf.h
zutil.obj: zutil.c zutil.h zlib.h zconf.h
-example.obj: example.c zlib.h zconf.h
+example.obj: test/example.c zlib.h zconf.h
-minigzip.obj: minigzip.c zlib.h zconf.h
+minigzip.obj: test/minigzip.c zlib.h zconf.h
# For the sake of the old Borland make,
diff --git a/compat/zlib/win32/Makefile.gcc b/compat/zlib/win32/Makefile.gcc
index 0a33bf6..6d1ded6 100644
--- a/compat/zlib/win32/Makefile.gcc
+++ b/compat/zlib/win32/Makefile.gcc
@@ -1,23 +1,29 @@
# Makefile for zlib, derived from Makefile.dj2.
# Modified for mingw32 by C. Spieler, 6/16/98.
# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003.
-# Last updated: 1-Aug-2003.
+# Last updated: Mar 2012.
# Tested under Cygwin and MinGW.
# Copyright (C) 1995-2003 Jean-loup Gailly.
# For conditions of distribution and use, see copyright notice in zlib.h
-# To compile, or to compile and test, type:
+# To compile, or to compile and test, type from the top level zlib directory:
#
-# make -fmakefile.gcc; make test testdll -fmakefile.gcc
+# make -fwin32/Makefile.gcc; make test testdll -fwin32/Makefile.gcc
#
# To use the asm code, type:
# cp contrib/asm?86/match.S ./match.S
-# make LOC=-DASMV OBJA=match.o -fmakefile.gcc
+# make LOC=-DASMV OBJA=match.o -fwin32/Makefile.gcc
#
# To install libz.a, zconf.h and zlib.h in the system directories, type:
#
-# make install -fmakefile.gcc
+# make install -fwin32/Makefile.gcc
+#
+# BINARY_PATH, INCLUDE_PATH and LIBRARY_PATH must be set.
+#
+# To install the shared lib, append SHARED_MODE=1 to the make command :
+#
+# make install -fwin32/Makefile.gcc SHARED_MODE=1
# Note:
# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN),
@@ -25,7 +31,7 @@
STATICLIB = libz.a
SHAREDLIB = zlib1.dll
-IMPLIB = libzdll.a
+IMPLIB = libz.dll.a
#
# Set to 1 if shared object needs to be installed
@@ -38,7 +44,6 @@ SHARED_MODE=0
PREFIX =
CC = $(PREFIX)gcc
CFLAGS = $(LOC) -O3 -Wall
-EXTRA_CFLAGS = -DNO_VIZ
AS = $(CC)
ASFLAGS = $(LOC) -Wall
@@ -59,7 +64,7 @@ CP = cp -fp
INSTALL = $(CP)
RM = rm -f
-prefix = /usr/local
+prefix ?= /usr/local
exec_prefix = $(prefix)
OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \
@@ -77,7 +82,7 @@ testdll: example_d.exe minigzip_d.exe
echo hello world | ./minigzip_d | ./minigzip_d -d
.c.o:
- $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
+ $(CC) $(CFLAGS) -c -o $@ $<
.S.o:
$(AS) $(ASFLAGS) -c -o $@ $<
@@ -108,34 +113,49 @@ minigzip_d.exe: minigzip.o $(IMPLIB)
$(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB)
$(STRIP) $@
-zlibrc.o: win32/zlib1.rc
- $(RC) $(RCFLAGS) -o $@ win32/zlib1.rc
+example.o: test/example.c zlib.h zconf.h
+ $(CC) $(CFLAGS) -I. -c -o $@ test/example.c
+minigzip.o: test/minigzip.c zlib.h zconf.h
+ $(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c
-# BINARY_PATH, INCLUDE_PATH and LIBRARY_PATH must be set.
+zlibrc.o: win32/zlib1.rc
+ $(RC) $(RCFLAGS) -o $@ win32/zlib1.rc
.PHONY: install uninstall clean
install: zlib.h zconf.h $(STATICLIB) $(IMPLIB)
- -@mkdir -p $(INCLUDE_PATH)
- -@mkdir -p $(LIBRARY_PATH)
+ @if test -z "$(DESTDIR)$(INCLUDE_PATH)" -o -z "$(DESTDIR)$(LIBRARY_PATH)" -o -z "$(DESTDIR)$(BINARY_PATH)"; then \
+ echo INCLUDE_PATH, LIBRARY_PATH, and BINARY_PATH must be specified; \
+ exit 1; \
+ fi
+ -@mkdir -p '$(DESTDIR)$(INCLUDE_PATH)'
+ -@mkdir -p '$(DESTDIR)$(LIBRARY_PATH)' '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig
-if [ "$(SHARED_MODE)" = "1" ]; then \
- mkdir -p $(BINARY_PATH); \
- $(INSTALL) $(SHAREDLIB) $(BINARY_PATH); \
- $(INSTALL) $(IMPLIB) $(LIBRARY_PATH); \
+ mkdir -p '$(DESTDIR)$(BINARY_PATH)'; \
+ $(INSTALL) $(SHAREDLIB) '$(DESTDIR)$(BINARY_PATH)'; \
+ $(INSTALL) $(IMPLIB) '$(DESTDIR)$(LIBRARY_PATH)'; \
fi
- -$(INSTALL) zlib.h $(INCLUDE_PATH)
- -$(INSTALL) zconf.h $(INCLUDE_PATH)
- -$(INSTALL) $(STATICLIB) $(LIBRARY_PATH)
+ -$(INSTALL) zlib.h '$(DESTDIR)$(INCLUDE_PATH)'
+ -$(INSTALL) zconf.h '$(DESTDIR)$(INCLUDE_PATH)'
+ -$(INSTALL) $(STATICLIB) '$(DESTDIR)$(LIBRARY_PATH)'
+ sed \
+ -e 's|@prefix@|${prefix}|g' \
+ -e 's|@exec_prefix@|${exec_prefix}|g' \
+ -e 's|@libdir@|$(LIBRARY_PATH)|g' \
+ -e 's|@sharedlibdir@|$(LIBRARY_PATH)|g' \
+ -e 's|@includedir@|$(INCLUDE_PATH)|g' \
+ -e 's|@VERSION@|'`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' zlib.h`'|g' \
+ zlib.pc.in > '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig/zlib.pc
uninstall:
-if [ "$(SHARED_MODE)" = "1" ]; then \
- $(RM) $(BINARY_PATH)/$(SHAREDLIB); \
- $(RM) $(LIBRARY_PATH)/$(IMPLIB); \
+ $(RM) '$(DESTDIR)$(BINARY_PATH)'/$(SHAREDLIB); \
+ $(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(IMPLIB); \
fi
- -$(RM) $(INCLUDE_PATH)/zlib.h
- -$(RM) $(INCLUDE_PATH)/zconf.h
- -$(RM) $(LIBRARY_PATH)/$(STATICLIB)
+ -$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zlib.h
+ -$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zconf.h
+ -$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(STATICLIB)
clean:
-$(RM) $(STATICLIB)
@@ -149,7 +169,6 @@ adler32.o: zlib.h zconf.h
compress.o: zlib.h zconf.h
crc32.o: crc32.h zlib.h zconf.h
deflate.o: deflate.h zutil.h zlib.h zconf.h
-example.o: zlib.h zconf.h
gzclose.o: zlib.h zconf.h gzguts.h
gzlib.o: zlib.h zconf.h gzguts.h
gzread.o: zlib.h zconf.h gzguts.h
@@ -158,7 +177,6 @@ inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
inftrees.o: zutil.h zlib.h zconf.h inftrees.h
-minigzip.o: zlib.h zconf.h
trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
uncompr.o: zlib.h zconf.h
zutil.o: zutil.h zlib.h zconf.h
diff --git a/compat/zlib/win32/Makefile.msc b/compat/zlib/win32/Makefile.msc
index fa10a1a..67b7731 100644
--- a/compat/zlib/win32/Makefile.msc
+++ b/compat/zlib/win32/Makefile.msc
@@ -6,8 +6,12 @@
# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build)
# nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" \
# OBJA="inffas32.obj match686.obj" (use ASM code, x86)
-# nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF" \
-# OBJA="inffasx64.obj gvmat64.obj inffas8664.c" (use ASM code, x64)
+# nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." \
+# OBJA="inffasx64.obj gvmat64.obj inffas8664.obj" (use ASM code, x64)
+
+# The toplevel directory of the source tree.
+#
+TOP = .
# optional build flags
LOC =
@@ -30,7 +34,7 @@ ARFLAGS = -nologo
RCFLAGS = /dWIN32 /r
OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj \
- gzwrite.obj infback.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+ gzwrite.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj
OBJA =
@@ -43,8 +47,8 @@ $(STATICLIB): $(OBJS) $(OBJA)
$(IMPLIB): $(SHAREDLIB)
-$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlib1.res
- $(LD) $(LDFLAGS) -def:win32/zlib.def -dll -implib:$(IMPLIB) \
+$(SHAREDLIB): $(TOP)/win32/zlib.def $(OBJS) $(OBJA) zlib1.res
+ $(LD) $(LDFLAGS) -def:$(TOP)/win32/zlib.def -dll -implib:$(IMPLIB) \
-out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res
if exist $@.manifest \
mt -nologo -manifest $@.manifest -outputresource:$@;2
@@ -69,69 +73,71 @@ minigzip_d.exe: minigzip.obj $(IMPLIB)
if exist $@.manifest \
mt -nologo -manifest $@.manifest -outputresource:$@;1
-.c.obj:
+{$(TOP)}.c.obj:
$(CC) -c $(WFLAGS) $(CFLAGS) $<
-{contrib/masmx64}.c.obj:
+{$(TOP)/test}.c.obj:
+ $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $<
+
+{$(TOP)/contrib/masmx64}.c.obj:
$(CC) -c $(WFLAGS) $(CFLAGS) $<
-{contrib/masmx64}.asm.obj:
+{$(TOP)/contrib/masmx64}.asm.obj:
$(AS) -c $(ASFLAGS) $<
-{contrib/masmx86}.asm.obj:
+{$(TOP)/contrib/masmx86}.asm.obj:
$(AS) -c $(ASFLAGS) $<
-adler32.obj: adler32.c zlib.h zconf.h
-
-compress.obj: compress.c zlib.h zconf.h
+adler32.obj: $(TOP)/adler32.c $(TOP)/zlib.h $(TOP)/zconf.h
-crc32.obj: crc32.c zlib.h zconf.h crc32.h
+compress.obj: $(TOP)/compress.c $(TOP)/zlib.h $(TOP)/zconf.h
-deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+crc32.obj: $(TOP)/crc32.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/crc32.h
-gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+deflate.obj: $(TOP)/deflate.c $(TOP)/deflate.h $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h
-gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+gzclose.obj: $(TOP)/gzclose.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
-gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+gzlib.obj: $(TOP)/gzlib.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
-gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+gzread.obj: $(TOP)/gzread.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
-infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
+gzwrite.obj: $(TOP)/gzwrite.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
-inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h
+infback.obj: $(TOP)/infback.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
+ $(TOP)/inffast.h $(TOP)/inffixed.h
-inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
- inffast.h inffixed.h
+inffast.obj: $(TOP)/inffast.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
+ $(TOP)/inffast.h
-inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+inflate.obj: $(TOP)/inflate.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
+ $(TOP)/inffast.h $(TOP)/inffixed.h
-trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+inftrees.obj: $(TOP)/inftrees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h
-uncompr.obj: uncompr.c zlib.h zconf.h
+trees.obj: $(TOP)/trees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/deflate.h $(TOP)/trees.h
-zutil.obj: zutil.c zutil.h zlib.h zconf.h
+uncompr.obj: $(TOP)/uncompr.c $(TOP)/zlib.h $(TOP)/zconf.h
-gvmat64.obj: contrib\masmx64\gvmat64.asm
+zutil.obj: $(TOP)/zutil.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h
-inffasx64.obj: contrib\masmx64\inffasx64.asm
+gvmat64.obj: $(TOP)/contrib\masmx64\gvmat64.asm
-inffas8664.obj: contrib\masmx64\inffas8664.c zutil.h zlib.h zconf.h \
- inftrees.h inflate.h inffast.h
+inffasx64.obj: $(TOP)/contrib\masmx64\inffasx64.asm
-inffas32.obj: contrib\masmx86\inffas32.asm
+inffas8664.obj: $(TOP)/contrib\masmx64\inffas8664.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h \
+ $(TOP)/inftrees.h $(TOP)/inflate.h $(TOP)/inffast.h
-match686.obj: contrib\masmx86\match686.asm
+inffas32.obj: $(TOP)/contrib\masmx86\inffas32.asm
-example.obj: example.c zlib.h zconf.h
+match686.obj: $(TOP)/contrib\masmx86\match686.asm
-minigzip.obj: minigzip.c zlib.h zconf.h
+example.obj: $(TOP)/test/example.c $(TOP)/zlib.h $(TOP)/zconf.h
-zlib1.res: win32/zlib1.rc
- $(RC) $(RCFLAGS) /fo$@ win32/zlib1.rc
+minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zlib.h $(TOP)/zconf.h
+zlib1.res: $(TOP)/win32/zlib1.rc
+ $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/zlib1.rc
# testing
test: example.exe minigzip.exe
diff --git a/compat/zlib/win32/README-WIN32.txt b/compat/zlib/win32/README-WIN32.txt
index 1e4c093..3d77d52 100644
--- a/compat/zlib/win32/README-WIN32.txt
+++ b/compat/zlib/win32/README-WIN32.txt
@@ -1,6 +1,6 @@
ZLIB DATA COMPRESSION LIBRARY
-zlib 1.2.4 is a general purpose data compression library. All the code is
+zlib 1.2.8 is a general purpose data compression library. All the code is
thread safe. The data format used by the zlib library is described by RFCs
(Request for Comments) 1950 to 1952 in the files
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
@@ -22,7 +22,7 @@ before asking for help.
Manifest:
-The package zlib-1.2.4-win32-x86.zip contains the following files:
+The package zlib-1.2.8-win32-x86.zip will contain the following files:
README-WIN32.txt This document
ChangeLog Changes since previous zlib packages
@@ -58,7 +58,7 @@ The package zlib-1.2.4-win32-x86.zip contains the following files:
All .pdb files above are entirely optional, but are very useful to a developer
attempting to diagnose program misbehavior or a crash. Many additional
-important files for developers can be found in the zlib124.zip source package
+important files for developers can be found in the zlib127.zip source package
available from http://zlib.net/ - review that package's README file for details.
@@ -72,7 +72,7 @@ are too numerous to cite here.
Copyright notice:
- (C) 1995-2010 Jean-loup Gailly and Mark Adler
+ (C) 1995-2012 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
diff --git a/compat/zlib/win32/README.txt b/compat/zlib/win32/README.txt
index fad9f14..34a13b3 100644
--- a/compat/zlib/win32/README.txt
+++ b/compat/zlib/win32/README.txt
@@ -6,7 +6,7 @@ What's here
Source
======
- zlib version 1.2.5
+ zlib version 1.2.8
available at http://www.gzip.org/zlib/
@@ -22,17 +22,18 @@ Usage
Build info
==========
- Contributed by Cosmin Truta.
+ Contributed by Jan Nijtmans.
Compiler:
- gcc-4.5.0-1-mingw32
+ i686-w64-mingw32-gcc (GCC) 4.5.3
Library:
- mingwrt-3.17, w32api-3.14
+ mingw64-i686-runtime/headers: 3.0b_svn5747-1
Build commands:
- gcc -c -DASMV contrib/asm686/match.S
- gcc -c -DASMINF -I. -O3 contrib/inflate86/inffas86.c
- make -f win32/Makefile.gcc LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
-
+ i686-w64-mingw32-gcc -c -DASMV contrib/asm686/match.S
+ i686-w64-mingw32-gcc -c -DASMINF -I. -O3 contrib/inflate86/inffas86.c
+ make -f win32/Makefile.gcc PREFIX=i686-w64-mingw32- LOC="-mms-bitfields -DASMV -DASMINF" OBJA="inffas86.o match.o"
+ Finally, from VS commandline (VS2005 or higher):
+ lib -machine:X86 -name:zlib1.dll -def:zlib.def -out:zdll.lib
Copyright notice
================
diff --git a/compat/zlib/win32/zdll.lib b/compat/zlib/win32/zdll.lib
index 4e53491..8e6f719 100644
--- a/compat/zlib/win32/zdll.lib
+++ b/compat/zlib/win32/zdll.lib
Binary files differ
diff --git a/compat/zlib/win32/zlib.def b/compat/zlib/win32/zlib.def
index 03df8bf..face655 100644
--- a/compat/zlib/win32/zlib.def
+++ b/compat/zlib/win32/zlib.def
@@ -1,6 +1,4 @@
-LIBRARY
; zlib data compression library
-
EXPORTS
; basic functions
zlibVersion
@@ -15,9 +13,11 @@ EXPORTS
deflateParams
deflateTune
deflateBound
+ deflatePending
deflatePrime
deflateSetHeader
inflateSetDictionary
+ inflateGetDictionary
inflateSync
inflateCopy
inflateReset
@@ -40,6 +40,7 @@ EXPORTS
gzread
gzwrite
gzprintf
+ gzvprintf
gzputs
gzgets
gzputc
@@ -57,6 +58,13 @@ EXPORTS
gzclose_w
gzerror
gzclearerr
+; large file functions
+ gzopen64
+ gzseek64
+ gztell64
+ gzoffset64
+ adler32_combine64
+ crc32_combine64
; checksum functions
adler32
crc32
@@ -68,7 +76,11 @@ EXPORTS
inflateInit_
inflateInit2_
inflateBackInit_
+ gzgetc_
zError
inflateSyncPoint
get_crc_table
inflateUndermine
+ inflateResetKeep
+ deflateResetKeep
+ gzopen_w
diff --git a/compat/zlib/win32/zlib1.dll b/compat/zlib/win32/zlib1.dll
index 869b00d..9ea38d5 100644..100755
--- a/compat/zlib/win32/zlib1.dll
+++ b/compat/zlib/win32/zlib1.dll
Binary files differ
diff --git a/compat/zlib/win32/zlib1.rc b/compat/zlib/win32/zlib1.rc
index 0d1d7ff..5c0feed 100644
--- a/compat/zlib/win32/zlib1.rc
+++ b/compat/zlib/win32/zlib1.rc
@@ -26,7 +26,7 @@ BEGIN
VALUE "FileDescription", "zlib data compression library\0"
VALUE "FileVersion", ZLIB_VERSION "\0"
VALUE "InternalName", "zlib1.dll\0"
- VALUE "LegalCopyright", "(C) 1995-2006 Jean-loup Gailly & Mark Adler\0"
+ VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0"
VALUE "OriginalFilename", "zlib1.dll\0"
VALUE "ProductName", "zlib\0"
VALUE "ProductVersion", ZLIB_VERSION "\0"
diff --git a/compat/zlib/win64/libz.dll.a b/compat/zlib/win64/libz.dll.a
new file mode 100644
index 0000000..a3ae403
--- /dev/null
+++ b/compat/zlib/win64/libz.dll.a
Binary files differ
diff --git a/compat/zlib/win64/zdll.lib b/compat/zlib/win64/zdll.lib
new file mode 100644
index 0000000..ac9ffc9
--- /dev/null
+++ b/compat/zlib/win64/zdll.lib
Binary files differ
diff --git a/compat/zlib/win64/zlib1.dll b/compat/zlib/win64/zlib1.dll
new file mode 100755
index 0000000..bd1dbc6
--- /dev/null
+++ b/compat/zlib/win64/zlib1.dll
Binary files differ
diff --git a/compat/zlib/zconf.h b/compat/zlib/zconf.h
index e9f7bd7..9987a77 100644
--- a/compat/zlib/zconf.h
+++ b/compat/zlib/zconf.h
@@ -1,9 +1,9 @@
/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-/* @(#) $Id: zconf.h,v 1.3 2010/04/20 14:50:10 nijtmans Exp $ */
+/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
@@ -15,11 +15,13 @@
* this permanently in zconf.h using "./configure --zprefix".
*/
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
/* all linked symbols */
# define _dist_code z__dist_code
# define _length_code z__length_code
# define _tr_align z__tr_align
+# define _tr_flush_bits z__tr_flush_bits
# define _tr_flush_block z__tr_flush_block
# define _tr_init z__tr_init
# define _tr_stored_block z__tr_stored_block
@@ -27,9 +29,11 @@
# define adler32 z_adler32
# define adler32_combine z_adler32_combine
# define adler32_combine64 z_adler32_combine64
-# define compress z_compress
-# define compress2 z_compress2
-# define compressBound z_compressBound
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
# define crc32 z_crc32
# define crc32_combine z_crc32_combine
# define crc32_combine64 z_crc32_combine64
@@ -40,44 +44,53 @@
# define deflateInit2_ z_deflateInit2_
# define deflateInit_ z_deflateInit_
# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
# define deflatePrime z_deflatePrime
# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
# define deflateSetDictionary z_deflateSetDictionary
# define deflateSetHeader z_deflateSetHeader
# define deflateTune z_deflateTune
# define deflate_copyright z_deflate_copyright
# define get_crc_table z_get_crc_table
-# define gz_error z_gz_error
-# define gz_intmax z_gz_intmax
-# define gz_strwinerror z_gz_strwinerror
-# define gzbuffer z_gzbuffer
-# define gzclearerr z_gzclearerr
-# define gzclose z_gzclose
-# define gzclose_r z_gzclose_r
-# define gzclose_w z_gzclose_w
-# define gzdirect z_gzdirect
-# define gzdopen z_gzdopen
-# define gzeof z_gzeof
-# define gzerror z_gzerror
-# define gzflush z_gzflush
-# define gzgetc z_gzgetc
-# define gzgets z_gzgets
-# define gzoffset z_gzoffset
-# define gzoffset64 z_gzoffset64
-# define gzopen z_gzopen
-# define gzopen64 z_gzopen64
-# define gzprintf z_gzprintf
-# define gzputc z_gzputc
-# define gzputs z_gzputs
-# define gzread z_gzread
-# define gzrewind z_gzrewind
-# define gzseek z_gzseek
-# define gzseek64 z_gzseek64
-# define gzsetparams z_gzsetparams
-# define gztell z_gztell
-# define gztell64 z_gztell64
-# define gzungetc z_gzungetc
-# define gzwrite z_gzwrite
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzvprintf z_gzvprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzwrite z_gzwrite
+# endif
# define inflate z_inflate
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
@@ -92,16 +105,22 @@
# define inflateReset z_inflateReset
# define inflateReset2 z_inflateReset2
# define inflateSetDictionary z_inflateSetDictionary
+# define inflateGetDictionary z_inflateGetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateUndermine z_inflateUndermine
+# define inflateResetKeep z_inflateResetKeep
# define inflate_copyright z_inflate_copyright
# define inflate_fast z_inflate_fast
# define inflate_table z_inflate_table
-# define uncompress z_uncompress
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# endif
# define zError z_zError
-# define zcalloc z_zcalloc
-# define zcfree z_zcfree
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
# define zlibCompileFlags z_zlibCompileFlags
# define zlibVersion z_zlibVersion
@@ -111,7 +130,9 @@
# define alloc_func z_alloc_func
# define charf z_charf
# define free_func z_free_func
-# define gzFile z_gzFile
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
# define gz_header z_gz_header
# define gz_headerp z_gz_headerp
# define in_func z_in_func
@@ -197,6 +218,12 @@
# endif
#endif
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
@@ -243,6 +270,14 @@
# endif
#endif
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
@@ -356,12 +391,47 @@ typedef uLong FAR uLongf;
typedef Byte *voidp;
#endif
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include <limits.h>
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# elif (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# elif (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
# define Z_HAVE_UNISTD_H
#endif
+#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
#ifdef STDC
-# include <sys/types.h> /* for off_t */
+# ifndef Z_SOLO
+# include <sys/types.h> /* for off_t */
+# endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+# include <stdarg.h> /* for va_list */
+# endif
+#endif
+
+#ifdef _WIN32
+# ifndef Z_SOLO
+# include <stddef.h> /* for wchar_t */
+# endif
#endif
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
@@ -370,21 +440,38 @@ typedef uLong FAR uLongf;
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
* equivalently requesting no 64-bit operations
*/
-#if -_LARGEFILE64_SOURCE - -1 == 1
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
# undef _LARGEFILE64_SOURCE
#endif
-#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
-# include <unistd.h> /* for SEEK_* and off_t */
-# ifdef VMS
-# include <unixio.h> /* for off_t */
-# endif
-# ifndef z_off_t
-# define z_off_t off_t
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
# endif
#endif
-#ifndef SEEK_SET
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
@@ -394,18 +481,14 @@ typedef uLong FAR uLongf;
# define z_off_t long
#endif
-#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#if !defined(_WIN32) && defined(Z_LARGE64)
# define z_off64_t off64_t
#else
-# define z_off64_t z_off_t
-#endif
-
-#if defined(__OS400__)
-# define NO_vsnprintf
-#endif
-
-#if defined(__MVS__)
-# define NO_vsnprintf
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
diff --git a/compat/zlib/zconf.h.cmakein b/compat/zlib/zconf.h.cmakein
index 9e69b1b..043019c 100644
--- a/compat/zlib/zconf.h.cmakein
+++ b/compat/zlib/zconf.h.cmakein
@@ -1,9 +1,9 @@
/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-/* @(#) $Id: zconf.h.cmakein,v 1.2 2010/04/20 14:50:10 nijtmans Exp $ */
+/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
@@ -17,11 +17,13 @@
* this permanently in zconf.h using "./configure --zprefix".
*/
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
/* all linked symbols */
# define _dist_code z__dist_code
# define _length_code z__length_code
# define _tr_align z__tr_align
+# define _tr_flush_bits z__tr_flush_bits
# define _tr_flush_block z__tr_flush_block
# define _tr_init z__tr_init
# define _tr_stored_block z__tr_stored_block
@@ -29,9 +31,11 @@
# define adler32 z_adler32
# define adler32_combine z_adler32_combine
# define adler32_combine64 z_adler32_combine64
-# define compress z_compress
-# define compress2 z_compress2
-# define compressBound z_compressBound
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
# define crc32 z_crc32
# define crc32_combine z_crc32_combine
# define crc32_combine64 z_crc32_combine64
@@ -42,44 +46,53 @@
# define deflateInit2_ z_deflateInit2_
# define deflateInit_ z_deflateInit_
# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
# define deflatePrime z_deflatePrime
# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
# define deflateSetDictionary z_deflateSetDictionary
# define deflateSetHeader z_deflateSetHeader
# define deflateTune z_deflateTune
# define deflate_copyright z_deflate_copyright
# define get_crc_table z_get_crc_table
-# define gz_error z_gz_error
-# define gz_intmax z_gz_intmax
-# define gz_strwinerror z_gz_strwinerror
-# define gzbuffer z_gzbuffer
-# define gzclearerr z_gzclearerr
-# define gzclose z_gzclose
-# define gzclose_r z_gzclose_r
-# define gzclose_w z_gzclose_w
-# define gzdirect z_gzdirect
-# define gzdopen z_gzdopen
-# define gzeof z_gzeof
-# define gzerror z_gzerror
-# define gzflush z_gzflush
-# define gzgetc z_gzgetc
-# define gzgets z_gzgets
-# define gzoffset z_gzoffset
-# define gzoffset64 z_gzoffset64
-# define gzopen z_gzopen
-# define gzopen64 z_gzopen64
-# define gzprintf z_gzprintf
-# define gzputc z_gzputc
-# define gzputs z_gzputs
-# define gzread z_gzread
-# define gzrewind z_gzrewind
-# define gzseek z_gzseek
-# define gzseek64 z_gzseek64
-# define gzsetparams z_gzsetparams
-# define gztell z_gztell
-# define gztell64 z_gztell64
-# define gzungetc z_gzungetc
-# define gzwrite z_gzwrite
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzvprintf z_gzvprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzwrite z_gzwrite
+# endif
# define inflate z_inflate
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
@@ -94,16 +107,22 @@
# define inflateReset z_inflateReset
# define inflateReset2 z_inflateReset2
# define inflateSetDictionary z_inflateSetDictionary
+# define inflateGetDictionary z_inflateGetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateUndermine z_inflateUndermine
+# define inflateResetKeep z_inflateResetKeep
# define inflate_copyright z_inflate_copyright
# define inflate_fast z_inflate_fast
# define inflate_table z_inflate_table
-# define uncompress z_uncompress
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# endif
# define zError z_zError
-# define zcalloc z_zcalloc
-# define zcfree z_zcfree
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
# define zlibCompileFlags z_zlibCompileFlags
# define zlibVersion z_zlibVersion
@@ -113,7 +132,9 @@
# define alloc_func z_alloc_func
# define charf z_charf
# define free_func z_free_func
-# define gzFile z_gzFile
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
# define gz_header z_gz_header
# define gz_headerp z_gz_headerp
# define in_func z_in_func
@@ -199,6 +220,12 @@
# endif
#endif
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
@@ -245,6 +272,14 @@
# endif
#endif
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
@@ -358,12 +393,47 @@ typedef uLong FAR uLongf;
typedef Byte *voidp;
#endif
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include <limits.h>
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# elif (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# elif (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
# define Z_HAVE_UNISTD_H
#endif
+#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
#ifdef STDC
-# include <sys/types.h> /* for off_t */
+# ifndef Z_SOLO
+# include <sys/types.h> /* for off_t */
+# endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+# include <stdarg.h> /* for va_list */
+# endif
+#endif
+
+#ifdef _WIN32
+# ifndef Z_SOLO
+# include <stddef.h> /* for wchar_t */
+# endif
#endif
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
@@ -372,21 +442,38 @@ typedef uLong FAR uLongf;
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
* equivalently requesting no 64-bit operations
*/
-#if -_LARGEFILE64_SOURCE - -1 == 1
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
# undef _LARGEFILE64_SOURCE
#endif
-#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
-# include <unistd.h> /* for SEEK_* and off_t */
-# ifdef VMS
-# include <unixio.h> /* for off_t */
-# endif
-# ifndef z_off_t
-# define z_off_t off_t
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
# endif
#endif
-#ifndef SEEK_SET
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
@@ -396,18 +483,14 @@ typedef uLong FAR uLongf;
# define z_off_t long
#endif
-#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#if !defined(_WIN32) && defined(Z_LARGE64)
# define z_off64_t off64_t
#else
-# define z_off64_t z_off_t
-#endif
-
-#if defined(__OS400__)
-# define NO_vsnprintf
-#endif
-
-#if defined(__MVS__)
-# define NO_vsnprintf
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
diff --git a/compat/zlib/zconf.h.in b/compat/zlib/zconf.h.in
index d0a2267..9987a77 100644
--- a/compat/zlib/zconf.h.in
+++ b/compat/zlib/zconf.h.in
@@ -1,9 +1,9 @@
/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-/* @(#) $Id: zconf.h.in,v 1.2 2010/04/20 14:50:10 nijtmans Exp $ */
+/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
@@ -15,11 +15,13 @@
* this permanently in zconf.h using "./configure --zprefix".
*/
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
/* all linked symbols */
# define _dist_code z__dist_code
# define _length_code z__length_code
# define _tr_align z__tr_align
+# define _tr_flush_bits z__tr_flush_bits
# define _tr_flush_block z__tr_flush_block
# define _tr_init z__tr_init
# define _tr_stored_block z__tr_stored_block
@@ -27,9 +29,11 @@
# define adler32 z_adler32
# define adler32_combine z_adler32_combine
# define adler32_combine64 z_adler32_combine64
-# define compress z_compress
-# define compress2 z_compress2
-# define compressBound z_compressBound
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
# define crc32 z_crc32
# define crc32_combine z_crc32_combine
# define crc32_combine64 z_crc32_combine64
@@ -40,44 +44,53 @@
# define deflateInit2_ z_deflateInit2_
# define deflateInit_ z_deflateInit_
# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
# define deflatePrime z_deflatePrime
# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
# define deflateSetDictionary z_deflateSetDictionary
# define deflateSetHeader z_deflateSetHeader
# define deflateTune z_deflateTune
# define deflate_copyright z_deflate_copyright
# define get_crc_table z_get_crc_table
-# define gz_error z_gz_error
-# define gz_intmax z_gz_intmax
-# define gz_strwinerror z_gz_strwinerror
-# define gzbuffer z_gzbuffer
-# define gzclearerr z_gzclearerr
-# define gzclose z_gzclose
-# define gzclose_r z_gzclose_r
-# define gzclose_w z_gzclose_w
-# define gzdirect z_gzdirect
-# define gzdopen z_gzdopen
-# define gzeof z_gzeof
-# define gzerror z_gzerror
-# define gzflush z_gzflush
-# define gzgetc z_gzgetc
-# define gzgets z_gzgets
-# define gzoffset z_gzoffset
-# define gzoffset64 z_gzoffset64
-# define gzopen z_gzopen
-# define gzopen64 z_gzopen64
-# define gzprintf z_gzprintf
-# define gzputc z_gzputc
-# define gzputs z_gzputs
-# define gzread z_gzread
-# define gzrewind z_gzrewind
-# define gzseek z_gzseek
-# define gzseek64 z_gzseek64
-# define gzsetparams z_gzsetparams
-# define gztell z_gztell
-# define gztell64 z_gztell64
-# define gzungetc z_gzungetc
-# define gzwrite z_gzwrite
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzvprintf z_gzvprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzwrite z_gzwrite
+# endif
# define inflate z_inflate
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
@@ -92,16 +105,22 @@
# define inflateReset z_inflateReset
# define inflateReset2 z_inflateReset2
# define inflateSetDictionary z_inflateSetDictionary
+# define inflateGetDictionary z_inflateGetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateUndermine z_inflateUndermine
+# define inflateResetKeep z_inflateResetKeep
# define inflate_copyright z_inflate_copyright
# define inflate_fast z_inflate_fast
# define inflate_table z_inflate_table
-# define uncompress z_uncompress
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# endif
# define zError z_zError
-# define zcalloc z_zcalloc
-# define zcfree z_zcfree
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
# define zlibCompileFlags z_zlibCompileFlags
# define zlibVersion z_zlibVersion
@@ -111,7 +130,9 @@
# define alloc_func z_alloc_func
# define charf z_charf
# define free_func z_free_func
-# define gzFile z_gzFile
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
# define gz_header z_gz_header
# define gz_headerp z_gz_headerp
# define in_func z_in_func
@@ -197,6 +218,12 @@
# endif
#endif
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
@@ -243,6 +270,14 @@
# endif
#endif
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
@@ -356,12 +391,47 @@ typedef uLong FAR uLongf;
typedef Byte *voidp;
#endif
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include <limits.h>
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# elif (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# elif (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
# define Z_HAVE_UNISTD_H
#endif
+#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
#ifdef STDC
-# include <sys/types.h> /* for off_t */
+# ifndef Z_SOLO
+# include <sys/types.h> /* for off_t */
+# endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+# include <stdarg.h> /* for va_list */
+# endif
+#endif
+
+#ifdef _WIN32
+# ifndef Z_SOLO
+# include <stddef.h> /* for wchar_t */
+# endif
#endif
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
@@ -370,21 +440,38 @@ typedef uLong FAR uLongf;
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
* equivalently requesting no 64-bit operations
*/
-#if -_LARGEFILE64_SOURCE - -1 == 1
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
# undef _LARGEFILE64_SOURCE
#endif
-#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
-# include <unistd.h> /* for SEEK_* and off_t */
-# ifdef VMS
-# include <unixio.h> /* for off_t */
-# endif
-# ifndef z_off_t
-# define z_off_t off_t
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
# endif
#endif
-#ifndef SEEK_SET
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
@@ -394,18 +481,14 @@ typedef uLong FAR uLongf;
# define z_off_t long
#endif
-#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#if !defined(_WIN32) && defined(Z_LARGE64)
# define z_off64_t off64_t
#else
-# define z_off64_t z_off_t
-#endif
-
-#if defined(__OS400__)
-# define NO_vsnprintf
-#endif
-
-#if defined(__MVS__)
-# define NO_vsnprintf
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
diff --git a/compat/zlib/zlib.3 b/compat/zlib/zlib.3
index 27adc4c..0160e62 100644
--- a/compat/zlib/zlib.3
+++ b/compat/zlib/zlib.3
@@ -1,4 +1,4 @@
-.TH ZLIB 3 "19 Apr 2010"
+.TH ZLIB 3 "28 Apr 2013"
.SH NAME
zlib \- compression/decompression library
.SH SYNOPSIS
@@ -36,9 +36,9 @@ All functions of the compression library are documented in the file
.IR zlib.h .
The distribution source includes examples of use of the library
in the files
-.I example.c
+.I test/example.c
and
-.IR minigzip.c,
+.IR test/minigzip.c,
as well as other examples in the
.IR examples/
directory.
@@ -65,7 +65,7 @@ A Python interface to
written by A.M. Kuchling (amk@magnet.com),
is available in Python 1.5 and later versions:
.IP
-http://www.python.org/doc/lib/module-zlib.html
+http://docs.python.org/library/zlib.html
.LP
.I zlib
is built into
@@ -95,11 +95,11 @@ http://zlib.net/
The data format used by the zlib library is described by RFC
(Request for Comments) 1950 to 1952 in the files:
.IP
-http://www.ietf.org/rfc/rfc1950.txt (for the zlib header and trailer format)
+http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format)
.br
-http://www.ietf.org/rfc/rfc1951.txt (for the deflate compressed data format)
+http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format)
.br
-http://www.ietf.org/rfc/rfc1952.txt (for the gzip header and trailer format)
+http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format)
.LP
Mark Nelson wrote an article about
.I zlib
@@ -125,8 +125,8 @@ before asking for help.
Send questions and/or comments to zlib@gzip.org,
or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
.SH AUTHORS
-Version 1.2.5
-Copyright (C) 1995-2010 Jean-loup Gailly (jloup@gzip.org)
+Version 1.2.8
+Copyright (C) 1995-2013 Jean-loup Gailly (jloup@gzip.org)
and Mark Adler (madler@alumni.caltech.edu).
.LP
This software is provided "as-is,"
diff --git a/compat/zlib/zlib.3.pdf b/compat/zlib/zlib.3.pdf
index 9f8a2c3..a346b5d 100644
--- a/compat/zlib/zlib.3.pdf
+++ b/compat/zlib/zlib.3.pdf
Binary files differ
diff --git a/compat/zlib/zlib.h b/compat/zlib/zlib.h
index bfbba83..3e0c767 100644
--- a/compat/zlib/zlib.h
+++ b/compat/zlib/zlib.h
@@ -1,7 +1,7 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.2.5, April 19th, 2010
+ version 1.2.8, April 28th, 2013
- Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+ Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -24,8 +24,8 @@
The data format used by the zlib library is described by RFCs (Request for
- Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
- (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+ (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
#ifndef ZLIB_H
@@ -37,11 +37,11 @@
extern "C" {
#endif
-#define ZLIB_VERSION "1.2.5"
-#define ZLIB_VERNUM 0x1250
+#define ZLIB_VERSION "1.2.8"
+#define ZLIB_VERNUM 0x1280
#define ZLIB_VER_MAJOR 1
#define ZLIB_VER_MINOR 2
-#define ZLIB_VER_REVISION 5
+#define ZLIB_VER_REVISION 8
#define ZLIB_VER_SUBREVISION 0
/*
@@ -83,15 +83,15 @@ typedef void (*free_func) OF((voidpf opaque, voidpf address));
struct internal_state;
typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
+ z_const Bytef *next_in; /* next input byte */
uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
+ uLong total_in; /* total number of input bytes read so far */
Bytef *next_out; /* next output byte should be put there */
uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
+ uLong total_out; /* total number of bytes output so far */
- char *msg; /* last error message, NULL if no error */
+ z_const char *msg; /* last error message, NULL if no error */
struct internal_state FAR *state; /* not visible by applications */
alloc_func zalloc; /* used to allocate the internal state */
@@ -327,8 +327,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
Z_FINISH can be used immediately after deflateInit if all the compression
is to be done in a single step. In this case, avail_out must be at least the
- value returned by deflateBound (see below). If deflate does not return
- Z_STREAM_END, then it must be called again as described above.
+ value returned by deflateBound (see below). Then deflate is guaranteed to
+ return Z_STREAM_END. If not enough output space is provided, deflate will
+ not return Z_STREAM_END, and it must be called again as described above.
deflate() sets strm->adler to the adler32 checksum of all input read
so far (that is, total_in bytes).
@@ -451,23 +452,29 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
error. However if all decompression is to be performed in a single step (a
single call of inflate), the parameter flush should be set to Z_FINISH. In
this case all pending input is processed and all pending output is flushed;
- avail_out must be large enough to hold all the uncompressed data. (The size
- of the uncompressed data may have been saved by the compressor for this
- purpose.) The next operation on this stream must be inflateEnd to deallocate
- the decompression state. The use of Z_FINISH is never required, but can be
- used to inform inflate that a faster approach may be used for the single
- inflate() call.
+ avail_out must be large enough to hold all of the uncompressed data for the
+ operation to complete. (The size of the uncompressed data may have been
+ saved by the compressor for this purpose.) The use of Z_FINISH is not
+ required to perform an inflation in one step. However it may be used to
+ inform inflate that a faster approach can be used for the single inflate()
+ call. Z_FINISH also informs inflate to not maintain a sliding window if the
+ stream completes, which reduces inflate's memory footprint. If the stream
+ does not complete, either because not all of the stream is provided or not
+ enough output space is provided, then a sliding window will be allocated and
+ inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+ been used.
In this implementation, inflate() always flushes as much output as
possible to the output buffer, and always uses the faster approach on the
- first call. So the only effect of the flush parameter in this implementation
- is on the return value of inflate(), as noted below, or when it returns early
- because Z_BLOCK or Z_TREES is used.
+ first call. So the effects of the flush parameter in this implementation are
+ on the return value of inflate() as noted below, when inflate() returns early
+ when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+ memory for a sliding window when Z_FINISH is used.
If a preset dictionary is needed after this call (see inflateSetDictionary
- below), inflate sets strm->adler to the adler32 checksum of the dictionary
+ below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
- strm->adler to the adler32 checksum of all output produced so far (that is,
+ strm->adler to the Adler-32 checksum of all output produced so far (that is,
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
below. At the end of the stream, inflate() checks that its computed adler32
checksum is equal to that saved by the compressor and returns Z_STREAM_END
@@ -478,7 +485,9 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
initializing with inflateInit2(). Any information contained in the gzip
header is not retained, so applications that need that information should
instead use raw inflate, see inflateInit2() below, or inflateBack() and
- perform their own processing of the gzip header and trailer.
+ perform their own processing of the gzip header and trailer. When processing
+ gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+ producted so far. The CRC-32 is checked against the gzip trailer.
inflate() returns Z_OK if some progress has been made (more input processed
or more output produced), Z_STREAM_END if the end of the compressed data has
@@ -580,10 +589,15 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
uInt dictLength));
/*
Initializes the compression dictionary from the given byte sequence
- without producing any compressed output. This function must be called
- immediately after deflateInit, deflateInit2 or deflateReset, before any call
- of deflate. The compressor and decompressor must use exactly the same
- dictionary (see inflateSetDictionary).
+ without producing any compressed output. When using the zlib format, this
+ function must be called immediately after deflateInit, deflateInit2 or
+ deflateReset, and before any call of deflate. When doing raw deflate, this
+ function must be called either before any call of deflate, or immediately
+ after the completion of a deflate block, i.e. after all input has been
+ consumed and all output has been delivered when using any of the flush
+ options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
+ compressor and decompressor must use exactly the same dictionary (see
+ inflateSetDictionary).
The dictionary should consist of strings (byte sequences) that are likely
to be encountered later in the data to be compressed, with the most commonly
@@ -610,8 +624,8 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
inconsistent (for example if deflate has already been called for this stream
- or if the compression method is bsort). deflateSetDictionary does not
- perform any compression: this will be done by deflate().
+ or if not at a block boundary for raw deflate). deflateSetDictionary does
+ not perform any compression: this will be done by deflate().
*/
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
@@ -688,8 +702,28 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
deflation of sourceLen bytes. It must be called after deflateInit() or
deflateInit2(), and after deflateSetHeader(), if used. This would be used
to allocate an output buffer for deflation in a single pass, and so would be
- called before deflate().
-*/
+ called before deflate(). If that first deflate() call is provided the
+ sourceLen input bytes, an output buffer allocated to the size returned by
+ deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+ to return Z_STREAM_END. Note that it is possible for the compressed size to
+ be larger than the value returned by deflateBound() if flush options other
+ than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+ unsigned *pending,
+ int *bits));
+/*
+ deflatePending() returns the number of bytes and bits of output that have
+ been generated, but not yet provided in the available output. The bytes not
+ provided would be due to the available output space having being consumed.
+ The number of bits of output not provided are between 0 and 7, where they
+ await more bits to join them in order to fill out a full byte. If pending
+ or bits are Z_NULL, then those values are not set.
+
+ deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+ */
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
int bits,
@@ -703,8 +737,9 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
than or equal to 16, and that many of the least significant bits of value
will be inserted in the output.
- deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
+ deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+ room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+ source stream state was inconsistent.
*/
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
@@ -790,10 +825,11 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
can be determined from the adler32 value returned by that call of inflate.
The compressor and decompressor must use exactly the same dictionary (see
- deflateSetDictionary). For raw inflate, this function can be called
- immediately after inflateInit2() or inflateReset() and before any call of
- inflate() to set the dictionary. The application must insure that the
- dictionary that was used for compression is provided.
+ deflateSetDictionary). For raw inflate, this function can be called at any
+ time to set the dictionary. If the provided dictionary is smaller than the
+ window and there is already data in the window, then the provided dictionary
+ will amend what's there. The application must insure that the dictionary
+ that was used for compression is provided.
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
@@ -803,19 +839,38 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
inflate().
*/
+ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
+ Bytef *dictionary,
+ uInt *dictLength));
+/*
+ Returns the sliding dictionary being maintained by inflate. dictLength is
+ set to the number of bytes in the dictionary, and that many bytes are copied
+ to dictionary. dictionary must have enough space, where 32768 bytes is
+ always enough. If inflateGetDictionary() is called with dictionary equal to
+ Z_NULL, then only the dictionary length is returned, and nothing is copied.
+ Similary, if dictLength is Z_NULL, then it is not set.
+
+ inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+ stream state is inconsistent.
+*/
+
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
/*
- Skips invalid compressed data until a full flush point (see above the
- description of deflate with Z_FULL_FLUSH) can be found, or until all
+ Skips invalid compressed data until a possible full flush point (see above
+ for the description of deflate with Z_FULL_FLUSH) can be found, or until all
available input is skipped. No output is provided.
- inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no flush point has been
- found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the
- success case, the application may save the current current value of total_in
- which indicates where valid compressed data was found. In the error case,
- the application may repeatedly call inflateSync, providing more input each
- time, until success or end of the input data.
+ inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+ All full flush points have this pattern, but not all occurrences of this
+ pattern are full flush points.
+
+ inflateSync returns Z_OK if a possible full flush point has been found,
+ Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+ has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+ In the success case, the application may save the current current value of
+ total_in which indicates where valid compressed data was found. In the
+ error case, the application may repeatedly call inflateSync, providing more
+ input each time, until success or end of the input data.
*/
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
@@ -962,12 +1017,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
See inflateBack() for the usage of these routines.
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
- the paramaters are invalid, Z_MEM_ERROR if the internal state could not be
+ the parameters are invalid, Z_MEM_ERROR if the internal state could not be
allocated, or Z_VERSION_ERROR if the version of the library does not match
the version of the header file.
*/
-typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef unsigned (*in_func) OF((void FAR *,
+ z_const unsigned char FAR * FAR *));
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
@@ -975,11 +1031,12 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
out_func out, void FAR *out_desc));
/*
inflateBack() does a raw inflate with a single call using a call-back
- interface for input and output. This is more efficient than inflate() for
- file i/o applications in that it avoids copying between the output and the
- sliding window by simply making the window itself the output buffer. This
- function trusts the application to not change the output buffer passed by
- the output function, at least until inflateBack() returns.
+ interface for input and output. This is potentially more efficient than
+ inflate() for file i/o applications, in that it avoids copying between the
+ output and the sliding window by simply making the window itself the output
+ buffer. inflate() can be faster on modern CPUs when used with large
+ buffers. inflateBack() trusts the application to not change the output
+ buffer passed by the output function, at least until inflateBack() returns.
inflateBackInit() must be called first to allocate the internal state
and to initialize the state with the user-provided window buffer.
@@ -1088,6 +1145,7 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
27-31: 0 (reserved)
*/
+#ifndef Z_SOLO
/* utility functions */
@@ -1149,10 +1207,11 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
+ the case where there is not enough room, uncompress() will fill the output
+ buffer with the uncompressed data up to that point.
*/
-
/* gzip file access functions */
/*
@@ -1162,7 +1221,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
wrapper, documented in RFC 1952, wrapped around a deflate stream.
*/
-typedef voidp gzFile; /* opaque gzip file descriptor */
+typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
/*
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
@@ -1172,13 +1231,28 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
for fixed code compression as in "wb9F". (See the description of
- deflateInit2 for more information about the strategy parameter.) Also "a"
- can be used instead of "w" to request that the gzip stream that will be
- written be appended to the file. "+" will result in an error, since reading
- and writing to the same gzip file is not supported.
+ deflateInit2 for more information about the strategy parameter.) 'T' will
+ request transparent writing or appending with no compression and not using
+ the gzip format.
+
+ "a" can be used instead of "w" to request that the gzip stream that will
+ be written be appended to the file. "+" will result in an error, since
+ reading and writing to the same gzip file is not supported. The addition of
+ "x" when writing will create the file exclusively, which fails if the file
+ already exists. On systems that support it, the addition of "e" when
+ reading or writing will set the flag to close the file on an execve() call.
+
+ These functions, as well as gzip, will read and decode a sequence of gzip
+ streams in a file. The append function of gzopen() can be used to create
+ such a file. (Also see gzflush() for another way to do this.) When
+ appending, gzopen does not test whether the file begins with a gzip stream,
+ nor does it look for the end of the gzip streams to begin appending. gzopen
+ will simply append a gzip stream to the existing file.
gzopen can be used to read a file which is not in gzip format; in this
- case gzread will directly read from the file without decompression.
+ case gzread will directly read from the file without decompression. When
+ reading, this will be detected automatically by looking for the magic two-
+ byte gzip header.
gzopen returns NULL if the file could not be opened, if there was
insufficient memory to allocate the gzFile state, or if an invalid mode was
@@ -1197,7 +1271,11 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
mode);. The duplicated descriptor should be saved to avoid a leak, since
- gzdopen does not close fd if it fails.
+ gzdopen does not close fd if it fails. If you are using fileno() to get the
+ file descriptor from a FILE *, then you will have to use dup() to avoid
+ double-close()ing the file descriptor. Both gzclose() and fclose() will
+ close the associated file descriptor, so they need to have different file
+ descriptors.
gzdopen returns NULL if there was insufficient memory to allocate the
gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
@@ -1235,14 +1313,26 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
/*
Reads the given number of uncompressed bytes from the compressed file. If
- the input file was not in gzip format, gzread copies the given number of
- bytes into the buffer.
+ the input file is not in gzip format, gzread copies the given number of
+ bytes into the buffer directly from the file.
After reaching the end of a gzip stream in the input, gzread will continue
- to read, looking for another gzip stream, or failing that, reading the rest
- of the input file directly without decompression. The entire input file
- will be read if gzread is called until it returns less than the requested
- len.
+ to read, looking for another gzip stream. Any number of gzip streams may be
+ concatenated in the input file, and will all be decompressed by gzread().
+ If something other than a gzip stream is encountered after a gzip stream,
+ that remaining trailing garbage is ignored (and no error is returned).
+
+ gzread can be used to read a gzip file that is being concurrently written.
+ Upon reaching the end of the input, gzread will return with the available
+ data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+ gzclearerr can be used to clear the end of file indicator in order to permit
+ gzread to be tried again. Z_OK indicates that a gzip stream was completed
+ on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
+ middle of a gzip stream. Note that gzread does not return -1 in the event
+ of an incomplete gzip stream. This error is deferred until gzclose(), which
+ will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+ stream. Alternatively, gzerror can be used before gzclose to detect this
+ case.
gzread returns the number of uncompressed bytes actually read, less than
len for end of file, or -1 for error.
@@ -1256,7 +1346,7 @@ ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
error.
*/
-ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
/*
Converts, formats, and writes the arguments to the compressed file under
control of the format string, as in fprintf. gzprintf returns the number of
@@ -1301,7 +1391,10 @@ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
/*
Reads one byte from the compressed file. gzgetc returns this byte or -1
- in case of end of file or error.
+ in case of end of file or error. This is implemented as a macro for speed.
+ As such, it does not do all of the checking the other functions do. I.e.
+ it does not check to see if file is NULL, nor whether the structure file
+ points to has been clobbered or not.
*/
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
@@ -1397,9 +1490,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
/*
Returns true (1) if file is being copied directly while reading, or false
- (0) if file is a gzip stream being decompressed. This state can change from
- false to true while reading the input file if the end of a gzip stream is
- reached, but is followed by data that is not another gzip stream.
+ (0) if file is a gzip stream being decompressed.
If the input file is empty, gzdirect() will return true, since the input
does not contain a gzip stream.
@@ -1408,6 +1499,13 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
cause buffers to be allocated to allow reading the file to determine if it
is a gzip file. Therefore if gzbuffer() is used, it should be called before
gzdirect().
+
+ When writing, gzdirect() returns true (1) if transparent writing was
+ requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
+ gzdirect() is not needed when writing. Transparent writing must be
+ explicitly requested, so the application already knows the answer. When
+ linking statically, using gzdirect() will include all of the zlib code for
+ gzip file reading and decompression, which may not be desired.)
*/
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
@@ -1419,7 +1517,8 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file));
must not be called more than once on the same allocation.
gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
- file operation error, or Z_OK on success.
+ file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+ last read ended in the middle of a gzip stream, or Z_OK on success.
*/
ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
@@ -1457,6 +1556,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
file that is being written concurrently.
*/
+#endif /* !Z_SOLO */
/* checksum functions */
@@ -1492,16 +1592,17 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
- seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
+ that the z_off_t type (like off_t) is a signed integer. If len2 is
+ negative, the result has no meaning or utility.
*/
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
/*
Update a running CRC-32 with the bytes buf[0..len-1] and return the
updated CRC-32. If buf is Z_NULL, this function returns the required
- initial value for the for the crc. Pre- and post-conditioning (one's
- complement) is performed within this function so it shouldn't be done by the
- application.
+ initial value for the crc. Pre- and post-conditioning (one's complement) is
+ performed within this function so it shouldn't be done by the application.
Usage example:
@@ -1544,17 +1645,42 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
const char *version,
int stream_size));
#define deflateInit(strm, level) \
- deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
+ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
#define inflateInit(strm) \
- inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
+ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
- (strategy), ZLIB_VERSION, sizeof(z_stream))
+ (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
#define inflateInit2(strm, windowBits) \
- inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+ (int)sizeof(z_stream))
#define inflateBackInit(strm, windowBits, window) \
inflateBackInit_((strm), (windowBits), (window), \
- ZLIB_VERSION, sizeof(z_stream))
+ ZLIB_VERSION, (int)sizeof(z_stream))
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure. Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro. The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously. They can
+ * only be used by the gzgetc() macro. You have been warned.
+ */
+struct gzFile_s {
+ unsigned have;
+ unsigned char *next;
+ z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+# define z_gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#else
+# define gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#endif
/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
* change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
@@ -1562,7 +1688,7 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
* functions are changed to 64 bits) -- in case these are set on systems
* without large file support, _LFS64_LARGEFILE must also be true
*/
-#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#ifdef Z_LARGE64
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
@@ -1571,14 +1697,23 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
#endif
-#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0
-# define gzopen gzopen64
-# define gzseek gzseek64
-# define gztell gztell64
-# define gzoffset gzoffset64
-# define adler32_combine adler32_combine64
-# define crc32_combine crc32_combine64
-# ifdef _LARGEFILE64_SOURCE
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+# ifdef Z_PREFIX_SET
+# define z_gzopen z_gzopen64
+# define z_gzseek z_gzseek64
+# define z_gztell z_gztell64
+# define z_gzoffset z_gzoffset64
+# define z_adler32_combine z_adler32_combine64
+# define z_crc32_combine z_crc32_combine64
+# else
+# define gzopen gzopen64
+# define gzseek gzseek64
+# define gztell gztell64
+# define gzoffset gzoffset64
+# define adler32_combine adler32_combine64
+# define crc32_combine crc32_combine64
+# endif
+# ifndef Z_LARGE64
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
@@ -1595,6 +1730,13 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
#endif
+#else /* Z_SOLO */
+
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
/* hack for buggy compilers */
#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
struct internal_state {int dummy;};
@@ -1603,8 +1745,21 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
/* undocumented functions */
ZEXTERN const char * ZEXPORT zError OF((int));
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
-ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
+#if defined(_WIN32) && !defined(Z_SOLO)
+ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
+ const char *mode));
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+ const char *format,
+ va_list va));
+# endif
+#endif
#ifdef __cplusplus
}
diff --git a/compat/zlib/zlib.map b/compat/zlib/zlib.map
index f282d36..55c6647 100644
--- a/compat/zlib/zlib.map
+++ b/compat/zlib/zlib.map
@@ -66,3 +66,18 @@ ZLIB_1.2.3.5 {
gzclose_r;
gzclose_w;
} ZLIB_1.2.3.4;
+
+ZLIB_1.2.5.1 {
+ deflatePending;
+} ZLIB_1.2.3.5;
+
+ZLIB_1.2.5.2 {
+ deflateResetKeep;
+ gzgetc_;
+ inflateResetKeep;
+} ZLIB_1.2.5.1;
+
+ZLIB_1.2.7.1 {
+ inflateGetDictionary;
+ gzvprintf;
+} ZLIB_1.2.5.2;
diff --git a/compat/zlib/zlib.pc.cmakein b/compat/zlib/zlib.pc.cmakein
new file mode 100644
index 0000000..a5e6429
--- /dev/null
+++ b/compat/zlib/zlib.pc.cmakein
@@ -0,0 +1,13 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@
+libdir=@INSTALL_LIB_DIR@
+sharedlibdir=@INSTALL_LIB_DIR@
+includedir=@INSTALL_INC_DIR@
+
+Name: zlib
+Description: zlib compression library
+Version: @VERSION@
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -lz
+Cflags: -I${includedir}
diff --git a/compat/zlib/zutil.c b/compat/zlib/zutil.c
index 7a55c44..23d2ebe 100644
--- a/compat/zlib/zutil.c
+++ b/compat/zlib/zutil.c
@@ -1,17 +1,20 @@
/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2005, 2010 Jean-loup Gailly.
+ * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-/* @(#) $Id: zutil.c,v 1.3 2010/04/20 14:50:10 nijtmans Exp $ */
+/* @(#) $Id$ */
#include "zutil.h"
+#ifndef Z_SOLO
+# include "gzguts.h"
+#endif
#ifndef NO_DUMMY_DECL
struct internal_state {int dummy;}; /* for buggy compilers */
#endif
-const char * const z_errmsg[10] = {
+z_const char * const z_errmsg[10] = {
"need dictionary", /* Z_NEED_DICT 2 */
"stream end", /* Z_STREAM_END 1 */
"", /* Z_OK 0 */
@@ -85,27 +88,27 @@ uLong ZEXPORT zlibCompileFlags()
#ifdef FASTEST
flags += 1L << 21;
#endif
-#ifdef STDC
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifdef NO_vsnprintf
- flags += 1L << 25;
+ flags += 1L << 25;
# ifdef HAS_vsprintf_void
- flags += 1L << 26;
+ flags += 1L << 26;
# endif
# else
# ifdef HAS_vsnprintf_void
- flags += 1L << 26;
+ flags += 1L << 26;
# endif
# endif
#else
- flags += 1L << 24;
+ flags += 1L << 24;
# ifdef NO_snprintf
- flags += 1L << 25;
+ flags += 1L << 25;
# ifdef HAS_sprintf_void
- flags += 1L << 26;
+ flags += 1L << 26;
# endif
# else
# ifdef HAS_snprintf_void
- flags += 1L << 26;
+ flags += 1L << 26;
# endif
# endif
#endif
@@ -181,6 +184,7 @@ void ZLIB_INTERNAL zmemzero(dest, len)
}
#endif
+#ifndef Z_SOLO
#ifdef SYS16BIT
@@ -316,3 +320,5 @@ void ZLIB_INTERNAL zcfree (opaque, ptr)
}
#endif /* MY_ZCALLOC */
+
+#endif /* !Z_SOLO */
diff --git a/compat/zlib/zutil.h b/compat/zlib/zutil.h
index 51a43fb..24ab06b 100644
--- a/compat/zlib/zutil.h
+++ b/compat/zlib/zutil.h
@@ -1,5 +1,5 @@
/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -8,12 +8,12 @@
subject to change. Applications should only use zlib.h.
*/
-/* @(#) $Id: zutil.h,v 1.3 2010/04/20 14:50:10 nijtmans Exp $ */
+/* @(#) $Id$ */
#ifndef ZUTIL_H
#define ZUTIL_H
-#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ)
+#ifdef HAVE_HIDDEN
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
#else
# define ZLIB_INTERNAL
@@ -21,7 +21,7 @@
#include "zlib.h"
-#ifdef STDC
+#if defined(STDC) && !defined(Z_SOLO)
# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
# include <stddef.h>
# endif
@@ -29,6 +29,10 @@
# include <stdlib.h>
#endif
+#ifdef Z_SOLO
+ typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
+#endif
+
#ifndef local
# define local static
#endif
@@ -40,13 +44,13 @@ typedef unsigned short ush;
typedef ush FAR ushf;
typedef unsigned long ulg;
-extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* (size given to avoid silly warnings with Visual C++) */
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
#define ERR_RETURN(strm,err) \
- return (strm->msg = (char*)ERR_MSG(err), (err))
+ return (strm->msg = ERR_MSG(err), (err))
/* To be used only when the state is known to be valid */
/* common constants */
@@ -78,16 +82,18 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
# define OS_CODE 0x00
-# if defined(__TURBOC__) || defined(__BORLANDC__)
-# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
- /* Allow compilation with ANSI keywords only enabled */
- void _Cdecl farfree( void *block );
- void *_Cdecl farmalloc( unsigned long nbytes );
-# else
-# include <alloc.h>
+# ifndef Z_SOLO
+# if defined(__TURBOC__) || defined(__BORLANDC__)
+# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+ /* Allow compilation with ANSI keywords only enabled */
+ void _Cdecl farfree( void *block );
+ void *_Cdecl farmalloc( unsigned long nbytes );
+# else
+# include <alloc.h>
+# endif
+# else /* MSC or DJGPP */
+# include <malloc.h>
# endif
-# else /* MSC or DJGPP */
-# include <malloc.h>
# endif
#endif
@@ -107,18 +113,20 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#ifdef OS2
# define OS_CODE 0x06
-# ifdef M_I86
+# if defined(M_I86) && !defined(Z_SOLO)
# include <malloc.h>
# endif
#endif
#if defined(MACOS) || defined(TARGET_OS_MAC)
# define OS_CODE 0x07
-# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-# include <unix.h> /* for fdopen */
-# else
-# ifndef fdopen
-# define fdopen(fd,mode) NULL /* No fdopen() */
+# ifndef Z_SOLO
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fdopen */
+# else
+# ifndef fdopen
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# endif
# endif
# endif
#endif
@@ -153,14 +161,15 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# endif
#endif
-#if defined(__BORLANDC__)
+#if defined(__BORLANDC__) && !defined(MSDOS)
#pragma warn -8004
#pragma warn -8008
#pragma warn -8066
#endif
/* provide prototypes for these when building zlib without LFS */
-#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+#if !defined(_WIN32) && \
+ (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
#endif
@@ -177,42 +186,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* functions */
-#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
-# ifndef HAVE_VSNPRINTF
-# define HAVE_VSNPRINTF
-# endif
-#endif
-#if defined(__CYGWIN__)
-# ifndef HAVE_VSNPRINTF
-# define HAVE_VSNPRINTF
-# endif
-#endif
-#ifndef HAVE_VSNPRINTF
-# ifdef MSDOS
- /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
- but for now we just assume it doesn't. */
-# define NO_vsnprintf
-# endif
-# ifdef __TURBOC__
-# define NO_vsnprintf
-# endif
-# ifdef WIN32
- /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
-# if !defined(vsnprintf) && !defined(NO_vsnprintf)
-# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
-# define vsnprintf _vsnprintf
-# endif
-# endif
-# endif
-# ifdef __SASC
-# define NO_vsnprintf
-# endif
-#endif
-#ifdef VMS
-# define NO_vsnprintf
-#endif
-
-#if defined(pyr)
+#if defined(pyr) || defined(Z_SOLO)
# define NO_MEMCPY
#endif
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
@@ -261,14 +235,19 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# define Tracecv(c,x)
#endif
-
-voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
- unsigned size));
-void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
+#ifndef Z_SOLO
+ voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+ unsigned size));
+ void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
+#endif
#define ZALLOC(strm, items, size) \
(*((strm)->zalloc))((strm)->opaque, (items), (size))
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+/* Reverse the bytes in a 32-bit value */
+#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
#endif /* ZUTIL_H */
diff --git a/doc/Access.3 b/doc/Access.3
index 1e82e07..668e1db 100644
--- a/doc/Access.3
+++ b/doc/Access.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Access 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_Access, Tcl_Stat \- check file permissions and other attributes
diff --git a/doc/AddErrInfo.3 b/doc/AddErrInfo.3
index 025ce86..d4bf7d5 100644
--- a/doc/AddErrInfo.3
+++ b/doc/AddErrInfo.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_AddErrorInfo 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_GetReturnOptions, Tcl_SetReturnOptions, Tcl_AddErrorInfo, Tcl_AppendObjToErrorInfo, Tcl_AddObjErrorInfo, Tcl_SetObjErrorCode, Tcl_SetErrorCode, Tcl_SetErrorCodeVA, Tcl_SetErrorLine, Tcl_GetErrorLine, Tcl_PosixError, Tcl_LogCommandInfo \- retrieve or record information about errors and other return options
@@ -107,7 +107,12 @@ with the value of \fIcode\fR. The \fB(Tcl_Obj *)\fR returned
by \fBTcl_GetReturnOptions\fR points to an unshared
\fBTcl_Obj\fR with reference count of zero. The dictionary
may be written to, either adding, removing, or overwriting
-any entries in it, with the need to check for a shared object.
+any entries in it, without the need to check for a shared value.
+As with any \fBTcl_Obj\fR with reference count of zero, it is up to
+the caller to arrange for its disposal with \fBTcl_DecrRefCount\fR or
+to a reference to it via \fBTcl_IncrRefCount\fR (or one of the many
+functions that call that, notably including \fBTcl_SetObjResult\fR and
+\fBTcl_SetVar2Ex\fR).
.PP
A typical usage for \fBTcl_GetReturnOptions\fR is to
retrieve the stack trace when script evaluation returns
@@ -123,6 +128,7 @@ if (code == TCL_ERROR) {
Tcl_DictObjGet(NULL, options, key, &stackTrace);
Tcl_DecrRefCount(key);
/* Do something with stackTrace */
+ Tcl_DecrRefCount(options);
}
.CE
.PP
@@ -170,16 +176,16 @@ these return options.
The \fB\-errorinfo\fR option holds a stack trace of the
operations that were in progress when an error occurred,
and is intended to be human-readable.
-The \fB\-errorcode\fR option holds a list of items that
+The \fB\-errorcode\fR option holds a Tcl list of items that
are intended to be machine-readable.
The first item in the \fB\-errorcode\fR value identifies the class of
error that occurred
-(e.g. POSIX means an error occurred in a POSIX system call)
+(e.g., POSIX means an error occurred in a POSIX system call)
and additional elements hold additional pieces
of information that depend on the class.
-See the \fBtclvars\fR manual entry for details on the various
-formats for the \fB\-errorcode\fR option used by
-Tcl's built-in commands.
+See the manual entry on the \fBerrorCode\fR variable for details on the
+various formats for the \fB\-errorcode\fR option used by Tcl's built-in
+commands.
.PP
The \fB\-errorinfo\fR option value is gradually built up as an
error unwinds through the nested operations.
@@ -226,7 +232,7 @@ the need for a null byte. If the \fBTcl_AddObjErrorInfo\fR
interface is used at all, it should be with a negative \fIlength\fR value.
.PP
The procedure \fBTcl_SetObjErrorCode\fR is used to set the
-\fB\-errorcode\fR return option to the list object \fIerrorObjPtr\fR
+\fB\-errorcode\fR return option to the list value \fIerrorObjPtr\fR
built up by the caller.
\fBTcl_SetObjErrorCode\fR is typically invoked just
before returning an error. If an error is
@@ -236,7 +242,7 @@ the \fB\-errorcode\fR return option to \fBNONE\fR.
.PP
The procedure \fBTcl_SetErrorCode\fR is also used to set the
\fB\-errorcode\fR return option. However, it takes one or more strings to
-record instead of an object. Otherwise, it is similar to
+record instead of a value. Otherwise, it is similar to
\fBTcl_SetObjErrorCode\fR in behavior.
.PP
\fBTcl_SetErrorCodeVA\fR is the same as \fBTcl_SetErrorCode\fR except that
@@ -301,6 +307,6 @@ so they continue to hold a record of information about the
most recent error seen in an interpreter.
.SH "SEE ALSO"
Tcl_DecrRefCount(3), Tcl_IncrRefCount(3), Tcl_Interp(3), Tcl_ResetResult(3),
-Tcl_SetErrno(3), tclvars(n)
+Tcl_SetErrno(3), errorCode(n), errorInfo(n)
.SH KEYWORDS
-error, object, object result, stack, trace, variable
+error, value, value result, stack, trace, variable
diff --git a/doc/Alloc.3 b/doc/Alloc.3
index ca4f949..585704a 100644
--- a/doc/Alloc.3
+++ b/doc/Alloc.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Alloc 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_Alloc, Tcl_Free, Tcl_Realloc, Tcl_AttemptAlloc, Tcl_AttemptRealloc, ckalloc, ckfree, ckrealloc, attemptckalloc, attemptckrealloc \- allocate or free heap memory
diff --git a/doc/AllowExc.3 b/doc/AllowExc.3
index ae595f1..2343e66 100644
--- a/doc/AllowExc.3
+++ b/doc/AllowExc.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_AllowExceptions 3 7.4 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_AllowExceptions \- allow all exceptions in next script evaluation
diff --git a/doc/AppInit.3 b/doc/AppInit.3
index e4ae971..3e47c1f 100644
--- a/doc/AppInit.3
+++ b/doc/AppInit.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_AppInit 3 7.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_AppInit \- perform application-specific initialization
diff --git a/doc/AssocData.3 b/doc/AssocData.3
index 59c26a4..f819acb 100644
--- a/doc/AssocData.3
+++ b/doc/AssocData.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_SetAssocData 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_GetAssocData, Tcl_SetAssocData, Tcl_DeleteAssocData \- manage associations of string keys and user specified data with Tcl interpreters
diff --git a/doc/Async.3 b/doc/Async.3
index d02f76d..558b511 100644
--- a/doc/Async.3
+++ b/doc/Async.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_AsyncCreate 3 7.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_AsyncCreate, Tcl_AsyncMark, Tcl_AsyncInvoke, Tcl_AsyncDelete, Tcl_AsyncReady \- handle asynchronous events
diff --git a/doc/BackgdErr.3 b/doc/BackgdErr.3
index 3116671..4ebcb60 100644
--- a/doc/BackgdErr.3
+++ b/doc/BackgdErr.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_BackgroundError 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_BackgroundException, Tcl_BackgroundError \- report Tcl exception that occurred in background processing
diff --git a/doc/Backslash.3 b/doc/Backslash.3
index 8b399fc..f121c7c 100644
--- a/doc/Backslash.3
+++ b/doc/Backslash.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Backslash 3 "8.1" Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_Backslash \- parse a backslash sequence
diff --git a/doc/BoolObj.3 b/doc/BoolObj.3
index 395d159..5c8414d 100644
--- a/doc/BoolObj.3
+++ b/doc/BoolObj.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_BooleanObj 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_NewBooleanObj, Tcl_SetBooleanObj, Tcl_GetBooleanFromObj \- store/retrieve boolean value in a Tcl_Obj
@@ -30,7 +30,7 @@ Points to the Tcl_Obj in which to store, or from which to
retrieve a boolean value.
.AP Tcl_Interp *interp in/out
If a boolean value cannot be retrieved,
-an error message is left in the interpreter's result object
+an error message is left in the interpreter's result value
unless \fIinterp\fR is NULL.
.AP int *boolPtr out
Points to place where \fBTcl_GetBooleanFromObj\fR
@@ -92,4 +92,4 @@ a \fBTCL_ERROR\fR return.
Tcl_NewObj, Tcl_IsShared, Tcl_GetBoolean
.SH KEYWORDS
-boolean, object
+boolean, value
diff --git a/doc/ByteArrObj.3 b/doc/ByteArrObj.3
index 77c94ac..a1f9330 100644
--- a/doc/ByteArrObj.3
+++ b/doc/ByteArrObj.3
@@ -4,11 +4,11 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_ByteArrayObj 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
-Tcl_NewByteArrayObj, Tcl_SetByteArrayObj, Tcl_GetByteArrayFromObj, Tcl_SetByteArrayLength \- manipulate Tcl objects as a arrays of bytes
+Tcl_NewByteArrayObj, Tcl_SetByteArrayObj, Tcl_GetByteArrayFromObj, Tcl_SetByteArrayLength \- manipulate Tcl values as a arrays of bytes
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -27,65 +27,65 @@ unsigned char *
.SH ARGUMENTS
.AS "const unsigned char" *lengthPtr in/out
.AP "const unsigned char" *bytes in
-The array of bytes used to initialize or set a byte-array object. May be NULL
+The array of bytes used to initialize or set a byte-array value. May be NULL
even if \fIlength\fR is non-zero.
.AP int length in
The length of the array of bytes. It must be >= 0.
.AP Tcl_Obj *objPtr in/out
-For \fBTcl_SetByteArrayObj\fR, this points to the object to be converted to
+For \fBTcl_SetByteArrayObj\fR, this points to the value to be converted to
byte-array type. For \fBTcl_GetByteArrayFromObj\fR and
-\fBTcl_SetByteArrayLength\fR, this points to the object from which to get
+\fBTcl_SetByteArrayLength\fR, this points to the value from which to get
the byte-array value; if \fIobjPtr\fR does not already point to a byte-array
-object, it will be converted to one.
+value, it will be converted to one.
.AP int *lengthPtr out
-If non-NULL, filled with the length of the array of bytes in the object.
+If non-NULL, filled with the length of the array of bytes in the value.
.BE
.SH DESCRIPTION
.PP
-These procedures are used to create, modify, and read Tcl byte-array objects
-from C code. Byte-array objects are typically used to hold the
+These procedures are used to create, modify, and read Tcl byte-array values
+from C code. Byte-array values are typically used to hold the
results of binary IO operations or data structures created with the
\fBbinary\fR command. In Tcl, an array of bytes is not equivalent to a
string. Conceptually, a string is an array of Unicode characters, while a
byte-array is an array of 8-bit quantities with no implicit meaning.
Accessor functions are provided to get the string representation of a
-byte-array or to convert an arbitrary object to a byte-array. Obtaining the
-string representation of a byte-array object (by calling
+byte-array or to convert an arbitrary value to a byte-array. Obtaining the
+string representation of a byte-array value (by calling
\fBTcl_GetStringFromObj\fR) produces a properly formed UTF-8 sequence with a
one-to-one mapping between the bytes in the internal representation and the
UTF-8 characters in the string representation.
.PP
\fBTcl_NewByteArrayObj\fR and \fBTcl_SetByteArrayObj\fR will
-create a new object of byte-array type or modify an existing object to have a
-byte-array type. Both of these procedures set the object's type to be
-byte-array and set the object's internal representation to a copy of the
+create a new value of byte-array type or modify an existing value to have a
+byte-array type. Both of these procedures set the value's type to be
+byte-array and set the value's internal representation to a copy of the
array of bytes given by \fIbytes\fR. \fBTcl_NewByteArrayObj\fR returns a
-pointer to a newly allocated object with a reference count of zero.
+pointer to a newly allocated value with a reference count of zero.
\fBTcl_SetByteArrayObj\fR invalidates any old string representation and, if
-the object is not already a byte-array object, frees any old internal
+the value is not already a byte-array value, frees any old internal
representation. If \fIbytes\fR is NULL then the new byte array contains
arbitrary values.
.PP
-\fBTcl_GetByteArrayFromObj\fR converts a Tcl object to byte-array type and
-returns a pointer to the object's new internal representation as an array of
+\fBTcl_GetByteArrayFromObj\fR converts a Tcl value to byte-array type and
+returns a pointer to the value's new internal representation as an array of
bytes. The length of this array is stored in \fIlengthPtr\fR if
\fIlengthPtr\fR is non-NULL. The storage for the array of bytes is owned by
-the object and should not be freed. The contents of the array may be
-modified by the caller only if the object is not shared and the caller
+the value and should not be freed. The contents of the array may be
+modified by the caller only if the value is not shared and the caller
invalidates the string representation.
.PP
-\fBTcl_SetByteArrayLength\fR converts the Tcl object to byte-array type
-and changes the length of the object's internal representation as an
+\fBTcl_SetByteArrayLength\fR converts the Tcl value to byte-array type
+and changes the length of the value's internal representation as an
array of bytes. If \fIlength\fR is greater than the space currently
allocated for the array, the array is reallocated to the new length; the
newly allocated bytes at the end of the array have arbitrary values. If
\fIlength\fR is less than the space currently allocated for the array,
the length of array is reduced to the new length. The return value is a
-pointer to the object's new array of bytes.
+pointer to the value's new array of bytes.
.SH "SEE ALSO"
Tcl_GetStringFromObj, Tcl_NewObj, Tcl_IncrRefCount, Tcl_DecrRefCount
.SH KEYWORDS
-object, byte array, utf, unicode, internationalization
+value, binary data, byte array, utf, unicode, internationalization
diff --git a/doc/CallDel.3 b/doc/CallDel.3
index dec4392..766621a 100644
--- a/doc/CallDel.3
+++ b/doc/CallDel.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_CallWhenDeleted 3 7.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_CallWhenDeleted, Tcl_DontCallWhenDeleted \- Arrange for callback when interpreter is deleted
diff --git a/doc/Cancel.3 b/doc/Cancel.3
index 80db3a3..5d258b7 100644
--- a/doc/Cancel.3
+++ b/doc/Cancel.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Cancel 3 8.6 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_CancelEval, Tcl_Canceled \- cancel Tcl scripts
diff --git a/doc/ChnlStack.3 b/doc/ChnlStack.3
index 9ec38b4..b046cd2 100644
--- a/doc/ChnlStack.3
+++ b/doc/ChnlStack.3
@@ -3,8 +3,8 @@
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-.so man.macros
.TH Tcl_StackChannel 3 8.3 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/Class.3 b/doc/Class.3
index dbb5b99..7e421fe 100644
--- a/doc/Class.3
+++ b/doc/Class.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Class 3 0.1 TclOO "TclOO Library Functions"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -111,7 +111,7 @@ function. Note that the Tcl_Obj reference returned by \fBTcl_GetObjectName\fR
is a shared reference.
.PP
Instances of classes are created using \fBTcl_NewObjectInstance\fR, which
-takes creates an object from any class (and which is internally called by both
+creates an object from any class (and which is internally called by both
the \fBcreate\fR and \fBnew\fR methods of the \fBoo::class\fR class). It takes
parameters that optionally give the name of the object and namespace to
create, and which describe the arguments to pass to the class's constructor
@@ -125,7 +125,7 @@ any constructors.
Every object and every class may have arbitrary amounts of metadata attached
to it, which the object or class attaches no meaning to beyond what is
described in a Tcl_ObjectMetadataType structure instance. Metadata to be
-attached is described by the the type of the metadata (given in the
+attached is described by the type of the metadata (given in the
\fImetaTypePtr\fR argument) and an arbitrary pointer (the \fImetadata\fR
argument) that are given to \fBTcl_ObjectSetMetadata\fR and
\fBTcl_ClassSetMetadata\fR, and a particular piece of metadata can be
diff --git a/doc/CmdCmplt.3 b/doc/CmdCmplt.3
index eeae039..25b372e 100644
--- a/doc/CmdCmplt.3
+++ b/doc/CmdCmplt.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_CommandComplete 3 "" Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_CommandComplete \- Check for unmatched braces in a Tcl command
diff --git a/doc/Concat.3 b/doc/Concat.3
index c38bf82..58a0fb6 100644
--- a/doc/Concat.3
+++ b/doc/Concat.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Concat 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_Concat \- concatenate a collection of strings
diff --git a/doc/CrtChannel.3 b/doc/CrtChannel.3
index 9aadba2..1c5c665 100644
--- a/doc/CrtChannel.3
+++ b/doc/CrtChannel.3
@@ -4,8 +4,8 @@
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-.so man.macros
.TH Tcl_CreateChannel 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -211,7 +211,7 @@ call to \fBTcl_GetStdChannel\fR or a call to \fBTcl_SetStdChannel\fR
closing this standard channel will cause the next call to
\fBTcl_CreateChannel\fR to make the new channel the new standard
channel too. See \fBTcl_StandardChannels\fR for a general treatise
-about standard channels and the behaviour of the Tcl library with
+about standard channels and the behavior of the Tcl library with
regard to them.
.PP
\fBTcl_GetChannelInstanceData\fR returns the instance data associated with
@@ -250,8 +250,8 @@ the default value of 4096 is returned.
.PP
\fBTcl_SetChannelBufferSize\fR sets the size, in bytes, of buffers that
will be allocated in subsequent operations on the channel to store input or
-output. The \fIsize\fR argument should be between ten and one million,
-allowing buffers of ten bytes to one million bytes. If \fIsize\fR is
+output. The \fIsize\fR argument should be between one and one million,
+allowing buffers of one byte to one million bytes. If \fIsize\fR is
outside this range, \fBTcl_SetChannelBufferSize\fR sets the buffer size to
4096.
.PP
@@ -846,7 +846,7 @@ the generic options error message string.
.PP
It always returns \fBTCL_ERROR\fR
.PP
-An error message is generated in \fIinterp\fR's result object to
+An error message is generated in \fIinterp\fR's result value to
indicate that a command was invoked with a bad option.
The message has the form
.CS
diff --git a/doc/CrtChnlHdlr.3 b/doc/CrtChnlHdlr.3
index 1451e30..0ecd3c9 100644
--- a/doc/CrtChnlHdlr.3
+++ b/doc/CrtChnlHdlr.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_CreateChannelHandler 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/CrtCloseHdlr.3 b/doc/CrtCloseHdlr.3
index a114f9c..bac2431 100644
--- a/doc/CrtCloseHdlr.3
+++ b/doc/CrtCloseHdlr.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_CreateCloseHandler 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/CrtCommand.3 b/doc/CrtCommand.3
index f0a7b43..fca64ce 100644
--- a/doc/CrtCommand.3
+++ b/doc/CrtCommand.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_CreateCommand 3 "" Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_CreateCommand \- implement new commands in C
@@ -41,18 +41,18 @@ will call \fIproc\fR to process the command.
It differs from \fBTcl_CreateObjCommand\fR in that a new string-based
command is defined;
that is, a command procedure is defined that takes an array of
-argument strings instead of objects.
-The object-based command procedures registered by \fBTcl_CreateObjCommand\fR
+argument strings instead of values.
+The value-based command procedures registered by \fBTcl_CreateObjCommand\fR
can execute significantly faster than the string-based command procedures
defined by \fBTcl_CreateCommand\fR.
-This is because they take Tcl objects as arguments
-and those objects can retain an internal representation that
+This is because they take Tcl values as arguments
+and those values can retain an internal representation that
can be manipulated more efficiently.
-Also, Tcl's interpreter now uses objects internally.
+Also, Tcl's interpreter now uses values internally.
In order to invoke a string-based command procedure
registered by \fBTcl_CreateCommand\fR,
it must generate and fetch a string representation
-from each argument object before the call.
+from each argument value before the call.
New commands should be defined using \fBTcl_CreateObjCommand\fR.
We support \fBTcl_CreateCommand\fR for backwards compatibility.
.PP
diff --git a/doc/CrtFileHdlr.3 b/doc/CrtFileHdlr.3
index cbc5e9f..c1bc1fa 100644
--- a/doc/CrtFileHdlr.3
+++ b/doc/CrtFileHdlr.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_CreateFileHandler 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_CreateFileHandler, Tcl_DeleteFileHandler \- associate procedure callbacks with files or devices (Unix only)
diff --git a/doc/CrtInterp.3 b/doc/CrtInterp.3
index a248cf4..679795e 100644
--- a/doc/CrtInterp.3
+++ b/doc/CrtInterp.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_CreateInterp 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_CreateInterp, Tcl_DeleteInterp, Tcl_InterpActive, Tcl_InterpDeleted \- create and delete Tcl command interpreters
@@ -41,8 +41,9 @@ may only be passed to Tcl routines called from the same thread as
the original \fBTcl_CreateInterp\fR call. It is not safe for multiple
threads to pass the same token to Tcl's routines.
The new interpreter is initialized with the built-in Tcl commands
-and with the variables documented in the \fBtclvars\fR manual page. To bind in
-additional commands, call \fBTcl_CreateCommand\fR.
+and with standard variables like \fBtcl_platform\fR and \fBenv\fR. To
+bind in additional commands, call \fBTcl_CreateCommand\fR, and to
+create additional variables, call \fBTcl_SetVar\fR.
.PP
\fBTcl_DeleteInterp\fR marks an interpreter as deleted; the interpreter
will eventually be deleted when all calls to \fBTcl_Preserve\fR for it have
@@ -144,6 +145,6 @@ should be used to determine when an interpreter is a candidate for deletion
due to inactivity.
.VE 8.6
.SH "SEE ALSO"
-Tcl_Preserve(3), Tcl_Release(3), tclvars(n)
+Tcl_Preserve(3), Tcl_Release(3)
.SH KEYWORDS
command, create, delete, interpreter
diff --git a/doc/CrtMathFnc.3 b/doc/CrtMathFnc.3
index 3f2c84e..84cde650 100644
--- a/doc/CrtMathFnc.3
+++ b/doc/CrtMathFnc.3
@@ -5,11 +5,18 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_CreateMathFunc 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_CreateMathFunc, Tcl_GetMathFuncInfo, Tcl_ListMathFuncs \- Define, query and enumerate math functions for expressions
+.SH "NOTICE OF EVENTUAL DEPRECATION"
+.PP
+The \fBTcl_CreateMathFunc\fR and \fBTcl_GetMathFuncInfo\fR functions
+are rendered somewhat obsolete by the ability to create functions for
+expressions by placing commands in the \fBtcl::mathfunc\fR namespace,
+as described in the \fBmathfunc\fR manual page; the API described on
+this page is not expected to be maintained indefinitely.
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -146,9 +153,9 @@ will not be modified. The variable pointed to by \fInumArgsPointer\fR
will contain -1, and no argument types will be stored in the variable
pointed to by \fIargTypesPointer\fR.
.PP
-\fBTcl_ListMathFuncs\fR returns a Tcl object containing a list of all
+\fBTcl_ListMathFuncs\fR returns a Tcl value containing a list of all
the math functions defined in the interpreter whose name matches
-\fIpattern\fR. The returned object has a reference count of zero.
+\fIpattern\fR. The returned value has a reference count of zero.
.SH "SEE ALSO"
expr(n), info(n), Tcl_CreateObjCommand(3), Tcl_Free(3), Tcl_NewListObj(3)
.SH KEYWORDS
diff --git a/doc/CrtObjCmd.3 b/doc/CrtObjCmd.3
index 343b3dd..e94c8cd 100644
--- a/doc/CrtObjCmd.3
+++ b/doc/CrtObjCmd.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_CreateObjCommand 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, Tcl_GetCommandInfo, Tcl_GetCommandInfoFromToken, Tcl_SetCommandInfo, Tcl_SetCommandInfoFromToken, Tcl_GetCommandName, Tcl_GetCommandFullName, Tcl_GetCommandFromObj \- implement new commands in C
@@ -64,7 +64,7 @@ The command must not have been deleted.
Pointer to structure containing various information about a
Tcl command.
.AP Tcl_Obj *objPtr in
-Object containing the name of a Tcl command.
+Value containing the name of a Tcl command.
.BE
.SH DESCRIPTION
.PP
@@ -102,10 +102,10 @@ will be copies of the \fIclientData\fR and \fIinterp\fR arguments given to
\fBTcl_CreateObjCommand\fR. Typically, \fIclientData\fR points to an
application-specific data structure that describes what to do when the
command procedure is invoked. \fIObjc\fR and \fIobjv\fR describe the
-arguments to the command, \fIobjc\fR giving the number of argument objects
+arguments to the command, \fIobjc\fR giving the number of argument values
(including the command name) and \fIobjv\fR giving the values of the
arguments. The \fIobjv\fR array will contain \fIobjc\fR values, pointing to
-the argument objects. Unlike \fIargv\fR[\fIargv\fR] used in a
+the argument values. Unlike \fIargv\fR[\fIargv\fR] used in a
string-based command procedure, \fIobjv\fR[\fIobjc\fR] will not contain NULL.
.PP
Additionally, when \fIproc\fR is invoked, it must not modify the contents
@@ -115,9 +115,9 @@ cause memory to be lost and the runtime stack to be corrupted. The
\fBconst\fR in the declaration of \fIobjv\fR will cause ANSI-compliant
compilers to report any such attempted assignment as an error. However,
it is acceptable to modify the internal representation of any individual
-object argument. For instance, the user may call
+value argument. For instance, the user may call
\fBTcl_GetIntFromObj\fR on \fIobjv\fR[\fB2\fR] to obtain the integer
-representation of that object; that call may change the type of the object
+representation of that value; that call may change the type of the value
that \fIobjv\fR[\fB2\fR] points at, but will not change where
\fIobjv\fR[\fB2\fR] points.
.PP
@@ -133,7 +133,7 @@ of the command,
and in the case of \fBTCL_ERROR\fR this gives an error message.
Before invoking a command procedure,
\fBTcl_EvalObjEx\fR sets interpreter's result to
-point to an object representing an empty string, so simple
+point to a value representing an empty string, so simple
commands can return an empty result by doing nothing at all.
.PP
The contents of the \fIobjv\fR array belong to Tcl and are not
@@ -225,7 +225,7 @@ if \fIisNativeObjectProc\fR has the value 1.
The fields \fIobjProc\fR and \fIobjClientData\fR
have the same meaning as the \fIproc\fR and \fIclientData\fR
arguments to \fBTcl_CreateObjCommand\fR;
-they hold information about the object-based command procedure
+they hold information about the value-based command procedure
that the Tcl interpreter calls to implement the command.
The fields \fIproc\fR and \fIclientData\fR
hold information about the string-based command procedure
@@ -235,7 +235,7 @@ this is the procedure passed to it;
otherwise, this is a compatibility procedure
registered by \fBTcl_CreateObjCommand\fR
that simply calls the command's
-object-based procedure after converting its string arguments to Tcl objects.
+value-based procedure after converting its string arguments to Tcl values.
The field \fIdeleteData\fR is the ClientData value
to pass to \fIdeleteProc\fR; it is normally the same as
\fIclientData\fR but may be set independently using the
@@ -290,7 +290,7 @@ they need to keep it for a long time.
\fBTcl_GetCommandFullName\fR produces the fully qualified name
of a command from a command token.
The name, including all namespace prefixes,
-is appended to the object specified by \fIobjPtr\fR.
+is appended to the value specified by \fIobjPtr\fR.
.PP
\fBTcl_GetCommandFromObj\fR returns a token for the command
specified by the name in a \fBTcl_Obj\fR.
@@ -299,4 +299,4 @@ Returns NULL if the command is not found.
.SH "SEE ALSO"
Tcl_CreateCommand(3), Tcl_ResetResult(3), Tcl_SetObjResult(3)
.SH KEYWORDS
-bind, command, create, delete, namespace, object
+bind, command, create, delete, namespace, value
diff --git a/doc/CrtSlave.3 b/doc/CrtSlave.3
index 3863373..fdcef6f 100644
--- a/doc/CrtSlave.3
+++ b/doc/CrtSlave.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_CreateSlave 3 7.6 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_IsSafe, Tcl_MakeSafe, Tcl_CreateSlave, Tcl_GetSlave, Tcl_GetMaster, Tcl_GetInterpPath, Tcl_CreateAlias, Tcl_CreateAliasObj, Tcl_GetAlias, Tcl_GetAliasObj, Tcl_ExposeCommand, Tcl_HideCommand \- manage multiple Tcl interpreters, aliases and hidden commands
@@ -78,10 +78,10 @@ Count of additional arguments to pass to the alias command.
Vector of strings, the additional arguments to pass to the alias command.
This storage is owned by the caller.
.AP int objc in
-Count of additional object arguments to pass to the alias object command.
+Count of additional value arguments to pass to the aliased command.
.AP Tcl_Obj **objv in
-Vector of Tcl_Obj structures, the additional object arguments to pass to
-the alias object command.
+Vector of Tcl_Obj structures, the additional value arguments to pass to
+the aliased command.
This storage is owned by the caller.
.AP Tcl_Interp **targetInterpPtr in
Pointer to location to store the address of the interpreter where a target
@@ -97,11 +97,11 @@ Pointer to location to store a vector of strings, the additional arguments
to pass to an alias. The location is in storage owned by the caller, the
vector of strings is owned by the called function.
.AP int *objcPtr out
-Pointer to location to store count of additional object arguments to be
+Pointer to location to store count of additional value arguments to be
passed to the alias. The location is in storage owned by the caller.
.AP Tcl_Obj ***objvPtr out
Pointer to location to store a vector of Tcl_Obj structures, the additional
-arguments to pass to an object alias command. The location is in storage
+arguments to pass to an alias command. The location is in storage
owned by the caller, the vector of Tcl_Obj structures is owned by the
called function.
.AP "const char" *cmdName in
@@ -165,13 +165,13 @@ of the relative path succeeds, \fBTCL_OK\fR is returned, else
\fBTCL_ERROR\fR is returned and the \fIresult\fR field in
\fIaskingInterp\fR contains the error message.
.PP
-\fBTcl_CreateAlias\fR creates an object command named \fIslaveCmd\fR in
+\fBTcl_CreateAlias\fR creates a command named \fIslaveCmd\fR in
\fIslaveInterp\fR that when invoked, will cause the command \fItargetCmd\fR
to be invoked in \fItargetInterp\fR. The arguments specified by the strings
contained in \fIargv\fR are always prepended to any arguments supplied in the
invocation of \fIslaveCmd\fR and passed to \fItargetCmd\fR.
This operation returns \fBTCL_OK\fR if it succeeds, or \fBTCL_ERROR\fR if
-it fails; in that case, an error message is left in the object result
+it fails; in that case, an error message is left in the value result
of \fIslaveInterp\fR.
Note that there are no restrictions on the ancestry relationship (as
created by \fBTcl_CreateSlave\fR) between \fIslaveInterp\fR and
@@ -179,7 +179,7 @@ created by \fBTcl_CreateSlave\fR) between \fIslaveInterp\fR and
restrictions on how they are related.
.PP
\fBTcl_CreateAliasObj\fR is similar to \fBTcl_CreateAlias\fR except
-that it takes a vector of objects to pass as additional arguments instead
+that it takes a vector of values to pass as additional arguments instead
of a vector of strings.
.PP
\fBTcl_GetAlias\fR returns information about an alias \fIaliasName\fR
@@ -202,7 +202,7 @@ command, or the operation will return \fBTCL_ERROR\fR and leave an error
message in the \fIresult\fR field in \fIinterp\fR.
If an exposed command named \fIcmdName\fR already exists,
the operation returns \fBTCL_ERROR\fR and leaves an error message in the
-object result of \fIinterp\fR.
+value result of \fIinterp\fR.
If the operation succeeds, it returns \fBTCL_OK\fR.
After executing this command, attempts to use \fIcmdName\fR in a call to
\fBTcl_Eval\fR or with the Tcl \fBeval\fR command will again succeed.
@@ -212,10 +212,10 @@ exposed commands to the set of hidden commands, under the name
\fIhiddenCmdName\fR.
\fICmdName\fR must be the name of an existing exposed
command, or the operation will return \fBTCL_ERROR\fR and leave an error
-message in the object result of \fIinterp\fR.
+message in the value result of \fIinterp\fR.
Currently both \fIcmdName\fR and \fIhiddenCmdName\fR must not contain
namespace qualifiers, or the operation will return \fBTCL_ERROR\fR and
-leave an error message in the object result of \fIinterp\fR.
+leave an error message in the value result of \fIinterp\fR.
The \fICmdName\fR will be looked up in the global namespace, and not
relative to the current namespace, even if the current namespace is not the
global one.
diff --git a/doc/CrtTimerHdlr.3 b/doc/CrtTimerHdlr.3
index 2c9f90a..f3957c7 100644
--- a/doc/CrtTimerHdlr.3
+++ b/doc/CrtTimerHdlr.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_CreateTimerHandler 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_CreateTimerHandler, Tcl_DeleteTimerHandler \- call a procedure at a given time
diff --git a/doc/CrtTrace.3 b/doc/CrtTrace.3
index 3689add..239941f 100644
--- a/doc/CrtTrace.3
+++ b/doc/CrtTrace.3
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_CreateTrace 3 "" Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_CreateTrace, Tcl_CreateObjTrace, Tcl_DeleteTrace \- arrange for command execution to be traced
diff --git a/doc/DString.3 b/doc/DString.3
index a85b1cf..0e571d2 100644
--- a/doc/DString.3
+++ b/doc/DString.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_DString 3 7.4 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_DStringInit, Tcl_DStringAppend, Tcl_DStringAppendElement, Tcl_DStringStartSublist, Tcl_DStringEndSublist, Tcl_DStringLength, Tcl_DStringValue, Tcl_DStringSetLength, Tcl_DStringTrunc, Tcl_DStringFree, Tcl_DStringResult, Tcl_DStringGetResult \- manipulate dynamic strings
diff --git a/doc/DetachPids.3 b/doc/DetachPids.3
index 0535cd8..39a51d3 100644
--- a/doc/DetachPids.3
+++ b/doc/DetachPids.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_DetachPids 3 "" Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_DetachPids, Tcl_ReapDetachedProcs, Tcl_WaitPid \- manage child processes in background
diff --git a/doc/DictObj.3 b/doc/DictObj.3
index 74b8dd1..90ca9e3 100644
--- a/doc/DictObj.3
+++ b/doc/DictObj.3
@@ -4,12 +4,12 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_DictObj 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-Tcl_NewDictObj, Tcl_DictObjPut, Tcl_DictObjGet, Tcl_DictObjRemove, Tcl_DictObjSize, Tcl_DictObjFirst, Tcl_DictObjNext, Tcl_DictObjDone, Tcl_DictObjPutKeyList, Tcl_DictObjRemoveKeyList \- manipulate Tcl objects as dictionaries
+Tcl_NewDictObj, Tcl_DictObjPut, Tcl_DictObjGet, Tcl_DictObjRemove, Tcl_DictObjSize, Tcl_DictObjFirst, Tcl_DictObjNext, Tcl_DictObjDone, Tcl_DictObjPutKeyList, Tcl_DictObjRemoveKeyList \- manipulate Tcl values as dictionaries
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -47,23 +47,23 @@ int
.SH ARGUMENTS
.AS Tcl_DictSearch "**valuePtrPtr" in/out
.AP Tcl_Interp *interp in
-If an error occurs while converting an object to be a dictionary object,
-an error message is left in the interpreter's result object
+If an error occurs while converting a value to be a dictionary value,
+an error message is left in the interpreter's result value
unless \fIinterp\fR is NULL.
.AP Tcl_Obj *dictPtr in/out
-Points to the dictionary object to be manipulated.
-If \fIdictPtr\fR does not already point to a dictionary object,
+Points to the dictionary value to be manipulated.
+If \fIdictPtr\fR does not already point to a dictionary value,
an attempt will be made to convert it to one.
.AP Tcl_Obj *keyPtr in
Points to the key for the key/value pair being manipulated within the
-dictionary object.
+dictionary value.
.AP Tcl_Obj **keyPtrPtr out
Points to a variable that will have the key from a key/value pair
placed within it. May be NULL to indicate that the caller is not
interested in the key.
.AP Tcl_Obj *valuePtr in
-Points to the value for the key/value pair being manipulate within the
-dictionary object (or sub-object, in the case of
+Points to the value for the key/value pair being manipulated within the
+dictionary value (or sub-value, in the case of
\fBTcl_DictObjPutKeyList\fR.)
.AP Tcl_Obj **valuePtrPtr out
Points to a variable that will have the value from a key/value pair
@@ -88,15 +88,15 @@ completed, and a zero otherwise.
Indicates the number of keys that will be supplied in the \fIkeyv\fR
array.
.AP "Tcl_Obj *const" *keyv in
-Array of \fIkeyc\fR pointers to objects that
+Array of \fIkeyc\fR pointers to values that
\fBTcl_DictObjPutKeyList\fR and \fBTcl_DictObjRemoveKeyList\fR will
use to locate the key/value pair to manipulate within the
-sub-dictionaries of the main dictionary object passed to them.
+sub-dictionaries of the main dictionary value passed to them.
.BE
.SH DESCRIPTION
.PP
-Tcl dictionary objects have an internal representation that supports
+Tcl dictionary values have an internal representation that supports
efficient mapping from keys to values and which guarantees that the
particular ordering of keys within the dictionary remains the same
modulo any keys being deleted (which removes them from the order) or
@@ -106,11 +106,11 @@ keys of the dictionary, and each will be followed (in the odd-valued
index) by the value associated with that key.
.PP
The procedures described in this man page are used to
-create, modify, index, and iterate over dictionary objects from C code.
+create, modify, index, and iterate over dictionary values from C code.
.PP
-\fBTcl_NewDictObj\fR creates a new, empty dictionary object. The
-string representation of the object will be invalid, and the reference
-count of the object will be zero.
+\fBTcl_NewDictObj\fR creates a new, empty dictionary value. The
+string representation of the value will be invalid, and the reference
+count of the value will be zero.
.PP
\fBTcl_DictObjGet\fR looks up the given key within the given
dictionary and writes a pointer to the value associated with that key
@@ -217,7 +217,7 @@ if (\fBTcl_DictObjFirst\fR(interp, objPtr, &search,
for (; !done ; \fBTcl_DictObjNext\fR(&search, &key, &value, &done)) {
/*
* Note that strcmp() is not a good way of comparing
- * objects and is just used here for demonstration
+ * values and is just used here for demonstration
* purposes.
*/
if (!strcmp(Tcl_GetString(key), Tcl_GetString(value))) {
@@ -231,4 +231,4 @@ return TCL_OK;
.SH "SEE ALSO"
Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_InitObjHashTable
.SH KEYWORDS
-dict, dict object, dictionary, dictionary object, hash table, iteration, object
+dict, dict value, dictionary, dictionary value, hash table, iteration, value
diff --git a/doc/DoOneEvent.3 b/doc/DoOneEvent.3
index 9bdf926..6f08b34 100644
--- a/doc/DoOneEvent.3
+++ b/doc/DoOneEvent.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_DoOneEvent 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_DoOneEvent \- wait for events and invoke event handlers
diff --git a/doc/DoWhenIdle.3 b/doc/DoWhenIdle.3
index 27a4b8c..3e28b4d 100644
--- a/doc/DoWhenIdle.3
+++ b/doc/DoWhenIdle.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_DoWhenIdle 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_DoWhenIdle, Tcl_CancelIdleCall \- invoke a procedure when there are no pending events
diff --git a/doc/DoubleObj.3 b/doc/DoubleObj.3
index 12818b0..4b422d4 100644
--- a/doc/DoubleObj.3
+++ b/doc/DoubleObj.3
@@ -4,11 +4,11 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_DoubleObj 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
-Tcl_NewDoubleObj, Tcl_SetDoubleObj, Tcl_GetDoubleFromObj \- manipulate Tcl objects as floating-point values
+Tcl_NewDoubleObj, Tcl_SetDoubleObj, Tcl_GetDoubleFromObj \- manipulate Tcl values as floating-point values
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -23,11 +23,11 @@ int
.SH ARGUMENTS
.AS Tcl_Interp doubleValue in/out
.AP double doubleValue in
-A double-precision floating-point value used to initialize or set a Tcl object.
+A double-precision floating-point value used to initialize or set a Tcl value.
.AP Tcl_Obj *objPtr in/out
-For \fBTcl_SetDoubleObj\fR, this points to the object in which to store a
+For \fBTcl_SetDoubleObj\fR, this points to the value in which to store a
double value.
-For \fBTcl_GetDoubleFromObj\fR, this refers to the object
+For \fBTcl_GetDoubleFromObj\fR, this refers to the value
from which to retrieve a double value.
.AP Tcl_Interp *interp in/out
When non-NULL, an error message is left here when double value retrieval fails.
@@ -37,21 +37,21 @@ Points to place to store the double value obtained from \fIobjPtr\fR.
.SH DESCRIPTION
.PP
-These procedures are used to create, modify, and read Tcl objects that
+These procedures are used to create, modify, and read Tcl values that
hold double-precision floating-point values.
.PP
-\fBTcl_NewDoubleObj\fR creates and returns a new Tcl object initialized to
-the double value \fIdoubleValue\fR. The returned Tcl object is unshared.
+\fBTcl_NewDoubleObj\fR creates and returns a new Tcl value initialized to
+the double value \fIdoubleValue\fR. The returned Tcl value is unshared.
.PP
-\fBTcl_SetDoubleObj\fR sets the value of an existing Tcl object pointed to
+\fBTcl_SetDoubleObj\fR sets the value of an existing Tcl value pointed to
by \fIobjPtr\fR to the double value \fIdoubleValue\fR. The \fIobjPtr\fR
-argument must point to an unshared Tcl object. Any attempt to set the value
-of a shared Tcl object violates Tcl's copy-on-write policy. Any existing
-string representation or internal representation in the unshared Tcl object
+argument must point to an unshared Tcl value. Any attempt to set the value
+of a shared Tcl value violates Tcl's copy-on-write policy. Any existing
+string representation or internal representation in the unshared Tcl value
will be freed as a consequence of setting the new value.
.PP
\fBTcl_GetDoubleFromObj\fR attempts to retrieve a double value from the
-Tcl object \fIobjPtr\fR. If the attempt succeeds, then \fBTCL_OK\fR is
+Tcl value \fIobjPtr\fR. If the attempt succeeds, then \fBTCL_OK\fR is
returned, and the double value is written to the storage pointed to by
\fIdoublePtr\fR. If the attempt fails, then \fBTCL_ERROR\fR is returned,
and if \fIinterp\fR is non-NULL, an error message is left in \fIinterp\fR.
@@ -61,4 +61,4 @@ calls to \fBTcl_GetDoubleFromObj\fR more efficient.
.SH "SEE ALSO"
Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_GetObjResult
.SH KEYWORDS
-double, double object, double type, internal representation, object, object type, string representation
+double, double value, double type, internal representation, value, value type, string representation
diff --git a/doc/DumpActiveMemory.3 b/doc/DumpActiveMemory.3
index 1f6cb46..f4d78d1 100644
--- a/doc/DumpActiveMemory.3
+++ b/doc/DumpActiveMemory.3
@@ -3,8 +3,8 @@
'\" Copyright (c) 2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
-.so man.macros
.TH "Tcl_DumpActiveMemory" 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_DumpActiveMemory, Tcl_InitMemory, Tcl_ValidateAllMemory \- Validated memory allocation interface
diff --git a/doc/Encoding.3 b/doc/Encoding.3
index 7bcb285..1478c35 100644
--- a/doc/Encoding.3
+++ b/doc/Encoding.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_GetEncoding 3 "8.1" Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_GetEncoding, Tcl_FreeEncoding, Tcl_GetEncodingFromObj, Tcl_ExternalToUtfDString, Tcl_ExternalToUtf, Tcl_UtfToExternalDString, Tcl_UtfToExternal, Tcl_WinTCharToUtf, Tcl_WinUtfToTChar, Tcl_GetEncodingName, Tcl_SetSystemEncoding, Tcl_GetEncodingNameFromEnvironment, Tcl_GetEncodingNames, Tcl_CreateEncoding, Tcl_GetEncodingSearchPath, Tcl_SetEncodingSearchPath, Tcl_GetDefaultEncodingDir, Tcl_SetDefaultEncodingDir \- procedures for creating and using encodings
diff --git a/doc/Ensemble.3 b/doc/Ensemble.3
index 19c6099..8457ddc 100644
--- a/doc/Ensemble.3
+++ b/doc/Ensemble.3
@@ -6,8 +6,8 @@
'\"
'\" This documents the C API introduced in TIP#235
'\"
-.so man.macros
.TH Tcl_Ensemble 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_CreateEnsemble, Tcl_FindEnsemble, Tcl_GetEnsembleFlags, Tcl_GetEnsembleMappingDict, Tcl_GetEnsembleNamespace, Tcl_GetEnsembleParameterList, Tcl_GetEnsembleUnknownHandler, Tcl_GetEnsembleSubcommandList, Tcl_IsEnsemble, Tcl_SetEnsembleFlags, Tcl_SetEnsembleMappingDict, Tcl_SetEnsembleParameterList, Tcl_SetEnsembleSubcommandList, Tcl_SetEnsembleUnknownHandler \- manipulate ensemble commands
@@ -95,7 +95,7 @@ Pointer to a variable into which to write the current ensemble mapping
dictionary.
.AP Tcl_Obj *listObj in
A list value to use for the list of formal pre-subcommand parameters, the
-defined list of subcommands in the dictionary or the unknown subcommmand
+defined list of subcommands in the dictionary or the unknown subcommand
handler command prefix. May be NULL if the subcommand list or unknown handler
are to be removed.
.AP Tcl_Obj **listObjPtr out
@@ -159,6 +159,8 @@ code (\fBTCL_OK\fR, or \fBTCL_ERROR\fR if the token does not refer to an
ensemble) and the dictionary obtained from
\fBTcl_GetEnsembleMappingDict\fR should always be treated as immutable
even if it is unshared.
+All command names in prefixes set via \fBTcl_SetEnsembleMappingDict\fR
+must be fully qualified.
.TP
\fBformal pre-subcommand parameter list\fR (read-write)
.VS 8.6
diff --git a/doc/Environment.3 b/doc/Environment.3
index 3753f43..85880b4 100644
--- a/doc/Environment.3
+++ b/doc/Environment.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_PutEnv 3 "7.5" Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_PutEnv \- procedures to manipulate the environment
@@ -33,6 +33,6 @@ Tcl-based applications using \fBputenv\fR should redefine it to
\fBTcl_PutEnv\fR so that they will interface properly to the Tcl
runtime.
.SH "SEE ALSO"
-tclvars(n)
+env(n)
.SH KEYWORDS
environment, variable
diff --git a/doc/Eval.3 b/doc/Eval.3
index b776e93..c104f7a 100644
--- a/doc/Eval.3
+++ b/doc/Eval.3
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Eval 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_EvalObjEx, Tcl_EvalFile, Tcl_EvalObjv, Tcl_Eval, Tcl_EvalEx, Tcl_GlobalEval, Tcl_GlobalEvalObj, Tcl_VarEval, Tcl_VarEvalVA \- execute Tcl scripts
@@ -47,17 +47,17 @@ int
Interpreter in which to execute the script. The interpreter's result is
modified to hold the result or error message from the script.
.AP Tcl_Obj *objPtr in
-A Tcl object containing the script to execute.
+A Tcl value containing the script to execute.
.AP int flags in
ORed combination of flag bits that specify additional options.
\fBTCL_EVAL_GLOBAL\fR and \fBTCL_EVAL_DIRECT\fR are currently supported.
.AP "const char" *fileName in
Name of a file containing a Tcl script.
.AP int objc in
-The number of objects in the array pointed to by \fIobjPtr\fR;
+The number of values in the array pointed to by \fIobjPtr\fR;
this is also the number of words in the command.
.AP Tcl_Obj **objv in
-Points to an array of pointers to objects; each object holds the
+Points to an array of pointers to values; each value holds the
value of a single word in the command to execute.
.AP int numBytes in
The number of bytes in \fIscript\fR, not including any
@@ -83,7 +83,7 @@ If this is the first time \fIobjPtr\fR has been executed,
its commands are compiled into bytecode instructions
which are then executed. The
bytecodes are saved in \fIobjPtr\fR so that the compilation step
-can be skipped if the object is evaluated again in the future.
+can be skipped if the value is evaluated again in the future.
.PP
The return value from \fBTcl_EvalObjEx\fR (and all the other procedures
described here) is a Tcl completion code with
@@ -111,15 +111,15 @@ which will be safely substituted by the Tcl interpreter into
.PP
\fBTcl_EvalObjv\fR executes a single pre-parsed command instead of a
script. The \fIobjc\fR and \fIobjv\fR arguments contain the values
-of the words for the Tcl command, one word in each object in
+of the words for the Tcl command, one word in each value in
\fIobjv\fR. \fBTcl_EvalObjv\fR evaluates the command and returns
a completion code and result just like \fBTcl_EvalObjEx\fR.
The caller of \fBTcl_EvalObjv\fR has to manage the reference count of the
-elements of \fIobjv\fR, insuring that the objects are valid until
+elements of \fIobjv\fR, insuring that the values are valid until
\fBTcl_EvalObjv\fR returns.
.PP
\fBTcl_Eval\fR is similar to \fBTcl_EvalObjEx\fR except that the script to
-be executed is supplied as a string instead of an object and no compilation
+be executed is supplied as a string instead of a value and no compilation
occurs. The string should be a proper UTF-8 string as converted by
\fBTcl_ExternalToUtfDString\fR or \fBTcl_ExternalToUtf\fR when it is known
to possibly contain upper ASCII characters whose possible combinations
@@ -129,7 +129,7 @@ bytecodes. In situations where it is known that the script will never be
executed again, \fBTcl_Eval\fR may be faster than \fBTcl_EvalObjEx\fR.
\fBTcl_Eval\fR returns a completion code and result just like
\fBTcl_EvalObjEx\fR. Note: for backward compatibility with versions before
-Tcl 8.0, \fBTcl_Eval\fR copies the object result in \fIinterp\fR to
+Tcl 8.0, \fBTcl_Eval\fR copies the value result in \fIinterp\fR to
\fIinterp->result\fR (use is deprecated) where it can be accessed directly.
This makes \fBTcl_Eval\fR somewhat slower than \fBTcl_EvalEx\fR, which
does not do the copy.
@@ -170,7 +170,7 @@ other procedures. If this flag bit is set, the script is not
compiled to bytecodes; instead it is executed directly
as is done by \fBTcl_EvalEx\fR. The
\fBTCL_EVAL_DIRECT\fR flag is useful in situations where the
-contents of an object are going to change immediately, so the
+contents of a value are going to change immediately, so the
bytecodes will not be reused in a future execution. In this case,
it is faster to execute the script directly.
.TP 23
@@ -208,4 +208,4 @@ This means that top-level applications should never see a return code
from \fBTcl_EvalObjEx\fR other then \fBTCL_OK\fR or \fBTCL_ERROR\fR.
.SH KEYWORDS
-execute, file, global, object, result, script
+execute, file, global, result, script, value
diff --git a/doc/Exit.3 b/doc/Exit.3
index fd251c7..3ea09bf 100644
--- a/doc/Exit.3
+++ b/doc/Exit.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Exit 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_Exit, Tcl_Finalize, Tcl_CreateExitHandler, Tcl_DeleteExitHandler, Tcl_ExitThread, Tcl_FinalizeThread, Tcl_CreateThreadExitHandler, Tcl_DeleteThreadExitHandler, Tcl_SetExitProc \- end the application or thread (and invoke exit handlers)
diff --git a/doc/ExprLong.3 b/doc/ExprLong.3
index ef93284..1615f88 100644
--- a/doc/ExprLong.3
+++ b/doc/ExprLong.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_ExprLong 3 7.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean, Tcl_ExprString \- evaluate an expression
@@ -49,11 +49,11 @@ given by the \fIexpr\fR argument
and return the result in one of four different forms.
The expression can have any of the forms accepted by the \fBexpr\fR command.
Note that these procedures have been largely replaced by the
-object-based procedures \fBTcl_ExprLongObj\fR, \fBTcl_ExprDoubleObj\fR,
+value-based procedures \fBTcl_ExprLongObj\fR, \fBTcl_ExprDoubleObj\fR,
\fBTcl_ExprBooleanObj\fR, and \fBTcl_ExprObj\fR.
-Those object-based procedures evaluate an expression held in a Tcl object
+Those value-based procedures evaluate an expression held in a Tcl value
instead of a string.
-The object argument can retain an internal representation
+The value argument can retain an internal representation
that is more efficient to execute.
.PP
The \fIinterp\fR argument refers to an interpreter used to
@@ -103,4 +103,4 @@ string stored in the interpreter's result.
Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj, Tcl_ExprObj
.SH KEYWORDS
-boolean, double, evaluate, expression, integer, object, string
+boolean, double, evaluate, expression, integer, value, string
diff --git a/doc/ExprLongObj.3 b/doc/ExprLongObj.3
index c8a564d..35edb5f 100644
--- a/doc/ExprLongObj.3
+++ b/doc/ExprLongObj.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_ExprLongObj 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj, Tcl_ExprObj \- evaluate an expression
@@ -29,7 +29,7 @@ int
.AP Tcl_Interp *interp in
Interpreter in whose context to evaluate \fIobjPtr\fR.
.AP Tcl_Obj *objPtr in
-Pointer to an object containing the expression to evaluate.
+Pointer to a value containing the expression to evaluate.
.AP long *longPtr out
Pointer to location in which to store the integer value of the
expression.
@@ -40,7 +40,7 @@ expression.
Pointer to location in which to store the 0/1 boolean value of the
expression.
.AP Tcl_Obj **resultPtrPtr out
-Pointer to location in which to store a pointer to the object
+Pointer to location in which to store a pointer to the value
that is the result of the expression.
.BE
@@ -93,14 +93,14 @@ or
or else an error occurs.
.PP
If \fBTcl_ExprObj\fR successfully evaluates the expression,
-it stores a pointer to the Tcl object
+it stores a pointer to the Tcl value
containing the expression's value at \fI*resultPtrPtr\fR.
In this case, the caller is responsible for calling
-\fBTcl_DecrRefCount\fR to decrement the object's reference count
-when it is finished with the object.
+\fBTcl_DecrRefCount\fR to decrement the value's reference count
+when it is finished with the value.
.SH "SEE ALSO"
Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean, Tcl_ExprString, Tcl_GetObjResult
.SH KEYWORDS
-boolean, double, evaluate, expression, integer, object, string
+boolean, double, evaluate, expression, integer, value, string
diff --git a/doc/FileSystem.3 b/doc/FileSystem.3
index e3870c3..6a8158c 100644
--- a/doc/FileSystem.3
+++ b/doc/FileSystem.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Filesystem 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_FSRegister, Tcl_FSUnregister, Tcl_FSData, Tcl_FSMountsChanged, Tcl_FSGetFileSystemForPath, Tcl_FSGetPathType, Tcl_FSCopyFile, Tcl_FSCopyDirectory, Tcl_FSCreateDirectory, Tcl_FSDeleteFile, Tcl_FSRemoveDirectory, Tcl_FSRenameFile, Tcl_FSListVolumes, Tcl_FSEvalFile, Tcl_FSEvalFileEx, Tcl_FSLoadFile, Tcl_FSUnloadFile, Tcl_FSMatchInDirectory, Tcl_FSLink, Tcl_FSLstat, Tcl_FSUtime, Tcl_FSFileAttrsGet, Tcl_FSFileAttrsSet, Tcl_FSFileAttrStrings, Tcl_FSStat, Tcl_FSAccess, Tcl_FSOpenFileChannel, Tcl_FSGetCwd, Tcl_FSChdir, Tcl_FSPathSeparator, Tcl_FSJoinPath, Tcl_FSSplitPath, Tcl_FSEqualPaths, Tcl_FSGetNormalizedPath, Tcl_FSJoinToPath, Tcl_FSConvertToPathType, Tcl_FSGetInternalRep, Tcl_FSGetTranslatedPath, Tcl_FSGetTranslatedStringPath, Tcl_FSNewNativePath, Tcl_FSGetNativePath, Tcl_FSFileSystemInfo, Tcl_GetAccessTimeFromStat, Tcl_GetBlockSizeFromStat, Tcl_GetBlocksFromStat, Tcl_GetChangeTimeFromStat, Tcl_GetDeviceTypeFromStat, Tcl_GetFSDeviceFromStat, Tcl_GetFSInodeFromStat, Tcl_GetGroupIdFromStat, Tcl_GetLinkCountFromStat, Tcl_GetModeFromStat, Tcl_GetModificationTimeFromStat, Tcl_GetSizeFromStat, Tcl_GetUserIdFromStat, Tcl_AllocStatBuf \- procedures to interact with any filesystem
@@ -86,7 +86,7 @@ int
int
\fBTcl_FSFileAttrsSet\fR(\fIinterp, int index, pathPtr, Tcl_Obj *objPtr\fR)
.sp
-const char **
+const char *const *
\fBTcl_FSFileAttrStrings\fR(\fIpathPtr, objPtrRef\fR)
.sp
int
@@ -192,8 +192,8 @@ int
Points to a structure containing the addresses of procedures that
can be called to perform the various filesystem operations.
.AP Tcl_Obj *pathPtr in
-The path represented by this object is used for the operation in
-question. If the object does not already have an internal \fBpath\fR
+The path represented by this value is used for the operation in
+question. If the value does not already have an internal \fBpath\fR
representation, it will be converted to have one.
.AP Tcl_Obj *srcPathPtr in
As for \fIpathPtr\fR, but used for the source file for a copy or
@@ -213,12 +213,12 @@ this structure will be returned. This parameter may be NULL.
Interpreter to use either for results, evaluation, or reporting error
messages.
.AP ClientData clientData in
-The native description of the path object to create.
+The native description of the path value to create.
.AP Tcl_Obj *firstPtr in
-The first of two path objects to compare. The object may be converted
+The first of two path values to compare. The value may be converted
to \fBpath\fR type.
.AP Tcl_Obj *secondPtr in
-The second of two path objects to compare. The object may be converted
+The second of two path values to compare. The value may be converted
to \fBpath\fR type.
.AP Tcl_Obj *listObj in
The list of path elements to operate on with a \fBjoin\fR operation.
@@ -226,12 +226,12 @@ The list of path elements to operate on with a \fBjoin\fR operation.
If non-negative, the number of elements in the \fIlistObj\fR which should
be joined together. If negative, then all elements are joined.
.AP Tcl_Obj **errorPtr out
-In the case of an error, filled with an object containing the name of
+In the case of an error, filled with a value containing the name of
the file which caused an error in the various copy/rename operations.
.AP Tcl_Obj **objPtrRef out
-Filled with an object containing the result of the operation.
+Filled with a value containing the result of the operation.
.AP Tcl_Obj *resultPtr out
-Pre-allocated object in which to store (using
+Pre-allocated value in which to store (using
\fBTcl_ListObjAppendElement\fR) the list of
files or directories which are successfully matched.
.AP int mode in
@@ -331,17 +331,17 @@ buffer is actually
declared to be, allowing the same code to be used both on systems with
and systems without support for files larger than 2GB in size.
.PP
-The \fBTcl_FS\fR API is objectified and may cache internal
+The \fBTcl_FS\fR API is \fBTcl_Obj\fR-ified and may cache internal
representations and other path-related strings (e.g.\ the current working
-directory). One side-effect of this is that one must not pass in objects
+directory). One side-effect of this is that one must not pass in values
with a reference count of zero to any of these functions. If such calls were
handled, they might result
in memory leaks (under some circumstances, the filesystem code may wish
-to retain a reference to the passed in object, and so one must not assume
-that after any of these calls return, the object still has a reference count of
+to retain a reference to the passed in value, and so one must not assume
+that after any of these calls return, the value still has a reference count of
zero - it may have been incremented) or in a direct segmentation fault
(or other memory access error)
-due to the object being freed part way through the complex object
+due to the value being freed part way through the complex value
manipulation required to ensure that the path is fully normalized and
absolute for filesystem determination. The practical lesson to learn
from this is that
@@ -354,9 +354,9 @@ Tcl_DecrRefCount(path);
.PP
is wrong, and may cause memory errors. The \fIpath\fR must have its
reference count incremented before passing it in, or
-decrementing it. For this reason, objects with a reference count of zero are
+decrementing it. For this reason, values with a reference count of zero are
considered not to be valid filesystem paths and calling any Tcl_FS API
-function with such an object will result in no action being taken.
+function with such a value will result in no action being taken.
.SS "FS API FUNCTIONS"
\fBTcl_FSCopyFile\fR attempts to copy the file given by \fIsrcPathPtr\fR to the
path name given by \fIdestPathPtr\fR. If the two paths given lie in the same
@@ -484,7 +484,7 @@ If the \fItoPtr\fR is NULL, a
action is performed. The result
is a Tcl_Obj specifying the contents of the symbolic link given by
\fIlinkNamePtr\fR, or NULL if the link could not be read. The result is owned
-by the caller, which should call Tcl_DecrRefCount when the result is no
+by the caller, which should call \fBTcl_DecrRefCount\fR when the result is no
longer needed. If the \fItoPtr\fR is not NULL, Tcl should create a link
of one of the types passed in in the \fIlinkAction\fR flag. This flag is
an ORed combination of \fBTCL_CREATE_SYMBOLIC_LINK\fR and \fBTCL_CREATE_HARD_LINK\fR.
@@ -523,7 +523,7 @@ values of the file given.
attributes\fR subcommand. The appropriate function for the filesystem to
which \fIpathPtr\fR belongs will be called.
.PP
-If the result is \fBTCL_OK\fR, then an object was placed in
+If the result is \fBTCL_OK\fR, then a value was placed in
\fIobjPtrRef\fR, which
will only be temporarily valid (unless \fBTcl_IncrRefCount\fR is called).
.PP
@@ -541,7 +541,7 @@ will take that list and first increment its reference count before using it.
On completion of that use, Tcl will decrement its reference count. Hence if
the list should be disposed of by Tcl when done, it should have a
reference count of zero, and if the list should not be disposed of, the
-filesystem should ensure it retains a reference count to the object.
+filesystem should ensure it retains a reference count to the value.
.PP
\fBTcl_FSAccess\fR checks whether the process would be allowed to read,
write or test for existence of the file (or other filesystem object)
@@ -582,7 +582,7 @@ In addition, if \fIinterp\fR is non-NULL, \fBTcl_FSOpenFileChannel\fR
leaves an error message in \fIinterp\fR's result after any error.
.PP
The newly created channel is not registered in the supplied interpreter; to
-register it, use \fBTcl_RegisterChannel\fR, described below.
+register it, use \fBTcl_RegisterChannel\fR.
If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
previously closed, the act of creating the new channel also assigns it as a
replacement for the standard channel.
@@ -622,35 +622,34 @@ The separator is returned as a Tcl_Obj containing a string of length
.PP
\fBTcl_FSJoinPath\fR takes the given Tcl_Obj, which must be a valid
list (which is allowed to have a reference count of zero), and returns the path
-object given by considering the first \fIelements\fR elements as valid path
+value given by considering the first \fIelements\fR elements as valid path
segments (each path segment may be a complete path, a partial path or
just a single possible directory or file name). If any path segment is
actually an absolute path, then all prior path segments are discarded.
If \fIelements\fR is less than 0, we use the entire list.
.PP
-It is possible that the returned object is actually an element
+It is possible that the returned value is actually an element
of the given list, so the caller should be careful to increment the
reference count of the result before freeing the list.
.PP
-The returned object, typically with a reference count of zero (but it
+The returned value, typically with a reference count of zero (but it
could be shared
under some conditions), contains the joined path. The caller must
-add a reference count to the object before using it. In particular, the
-returned object could be an element of the given list, so freeing the
-list might free the object prematurely if no reference count has been taken.
-If the number of elements is zero, then the returned object will be
+add a reference count to the value before using it. In particular, the
+returned value could be an element of the given list, so freeing the
+list might free the value prematurely if no reference count has been taken.
+If the number of elements is zero, then the returned value will be
an empty-string Tcl_Obj.
.PP
\fBTcl_FSSplitPath\fR takes the given Tcl_Obj, which should be a valid path,
-and returns a Tcl list object containing each segment of that path as
+and returns a Tcl list value containing each segment of that path as
an element.
-It returns a list object with a reference count of zero. If the
+It returns a list value with a reference count of zero. If the
passed in \fIlenPtr\fR is non-NULL, the variable it points to will be
updated to contain the number of elements in the returned list.
.PP
\fBTcl_FSEqualPaths\fR tests whether the two paths given represent the same
-filesystem object
-.PP
+filesystem object.
It returns 1 if the paths are equal, and 0 if they are different. If
either path is NULL, 0 is always returned.
.PP
@@ -658,7 +657,7 @@ either path is NULL, 0 is always returned.
from the given Tcl_Obj a unique normalized path representation, whose
string value can be used as a unique identifier for the file.
.PP
-It returns the normalized path object, owned by Tcl, or NULL if the path
+It returns the normalized path value, owned by Tcl, or NULL if the path
was invalid or could otherwise not be successfully converted.
Extraction of absolute, normalized paths is very efficient (because the
filesystem operates on these representations internally), although the
@@ -666,35 +665,36 @@ result when the filesystem contains numerous symbolic links may not be
the most user-friendly version of a path. The return value is owned by
Tcl and has a lifetime equivalent to that of the \fIpathPtr\fR passed in
(unless that is a relative path, in which case the normalized path
-object may be freed any time the cwd changes) - the caller can of
-course increment the refCount if it wishes to maintain a copy for longer.
+value may be freed any time the cwd changes) - the caller can of
+course increment the reference count if it wishes to maintain a copy for longer.
.PP
-\fBTcl_FSJoinToPath\fR takes the given object, which should usually be a
+\fBTcl_FSJoinToPath\fR takes the given value, which should usually be a
valid path or NULL, and joins onto it the array of paths segments
given.
.PP
-Returns object, typically with refCount of zero (but it could be shared
+Returns a value, typically with reference count of zero (but it could be shared
under some conditions), containing the joined path. The caller must
-add a refCount to the object before using it. If any of the objects
-passed into this function (pathPtr or path elements) have a refCount
+add a reference count to the value before using it. If any of the values
+passed into this function (\fIpathPtr\fR or \fIpath\fR elements) have
+a reference count
of zero, they will be freed when this function returns.
.PP
\fBTcl_FSConvertToPathType\fR tries to convert the given Tcl_Obj to a valid
Tcl path type, taking account of the fact that the cwd may have changed
-even if this object is already supposedly of the correct type.
+even if this value is already supposedly of the correct type.
The filename may begin with
.QW ~
(to indicate current user's home directory) or
.QW ~<user>
(to indicate any user's home directory).
.PP
-If the conversion succeeds (i.e.\ the object is a valid path in one of
+If the conversion succeeds (i.e.\ the value is a valid path in one of
the current filesystems), then \fBTCL_OK\fR is returned. Otherwise
\fBTCL_ERROR\fR is returned, and an error message may
be left in the interpreter.
.PP
\fBTcl_FSGetInternalRep\fR extracts the internal representation of a given
-path object, in the given filesystem. If the path object belongs to a
+path value, in the given filesystem. If the path value belongs to a
different filesystem, we return NULL. If the internal representation is
currently NULL, we attempt to generate it, by calling the filesystem's
\fBTcl_FSCreateInternalRepProc\fR.
@@ -706,7 +706,7 @@ not require additional conversions.
\fBTcl_FSGetTranslatedPath\fR attempts to extract the translated path
from the given Tcl_Obj.
.PP
-If the translation succeeds (i.e.\ the object is a valid path), then it is
+If the translation succeeds (i.e.\ the value is a valid path), then it is
returned. Otherwise NULL will be returned, and an error message may be
left in the interpreter. A
.QW translated
@@ -715,8 +715,8 @@ path is one which contains no
or
.QW ~user
sequences (these have been expanded to their current
-representation in the filesystem). The object returned is owned by the
-caller, which must store it or call Tcl_DecrRefCount to ensure memory is
+representation in the filesystem). The value returned is owned by the
+caller, which must store it or call \fBTcl_DecrRefCount\fR to ensure memory is
freed. This function is of little practical use, and
\fBTcl_FSGetNormalizedPath\fR or \fBTcl_FSGetNativePath\fR are usually
better functions to use for most purposes.
@@ -732,11 +732,11 @@ better functions to use for most purposes.
usual obj->path->nativerep conversions. If some code retrieves a path
in native form (from, e.g.\ \fBreadlink\fR or a native dialog), and that path
is to be used at the Tcl level, then calling this function is an
-efficient way of creating the appropriate path object type.
+efficient way of creating the appropriate path value type.
.PP
-The resulting object is a pure
+The resulting value is a pure
.QW path
-object, which will only receive
+value, which will only receive
a UTF-8 string representation if that is required by some Tcl code.
.PP
\fBTcl_FSGetNativePath\fR is for use by the Win/Unix native
@@ -774,7 +774,7 @@ given path within that filesystem (which is filesystem dependent). The
second element may be empty if the filesystem does not provide a
further categorization of files.
.PP
-A valid list object is returned, unless the path object is not
+A valid list value is returned, unless the path value is not
recognized, when NULL will be returned.
.PP
\fBTcl_FSGetFileSystemForPath\fR returns a pointer to the
@@ -1002,14 +1002,14 @@ The \fIversion\fR field should be set to \fBTCL_FILESYSTEM_VERSION_1\fR.
.SS PATHINFILESYSTEMPROC
.PP
The \fIpathInFilesystemProc\fR field contains the address of a function
-which is called to determine whether a given path object belongs to this
+which is called to determine whether a given path value belongs to this
filesystem or not. Tcl will only call the rest of the filesystem
functions with a path for which this function has returned \fBTCL_OK\fR.
-If the path does not belong, -1 should be returned (the behaviour of Tcl
+If the path does not belong, -1 should be returned (the behavior of Tcl
for any other return value is not defined). If \fBTCL_OK\fR is returned,
then the optional \fIclientDataPtr\fR output parameter can be used to
return an internal (filesystem specific) representation of the path,
-which will be cached inside the path object, and may be retrieved
+which will be cached inside the path value, and may be retrieved
efficiently by the other filesystem functions. Tcl will simultaneously
cache the fact that this path belongs to this filesystem. Such caches
are invalidated when filesystem structures are added or removed from
@@ -1023,7 +1023,7 @@ typedef int \fBTcl_FSPathInFilesystemProc\fR(
.SS DUPINTERNALREPPROC
.PP
This function makes a copy of a path's internal representation, and is
-called when Tcl needs to duplicate a path object. If NULL, Tcl will
+called when Tcl needs to duplicate a path value. If NULL, Tcl will
simply not copy the internal representation, which may then need to be
regenerated later.
.PP
@@ -1043,8 +1043,8 @@ typedef void \fBTcl_FSFreeInternalRepProc\fR(
.SS INTERNALTONORMALIZEDPROC
.PP
Function to convert internal representation to a normalized path. Only
-required if the filesystem creates pure path objects with no string/path
-representation. The return value is a Tcl object whose string
+required if the filesystem creates pure path values with no string/path
+representation. The return value is a Tcl value whose string
representation is the normalized path.
.PP
.CS
@@ -1053,9 +1053,9 @@ typedef Tcl_Obj *\fBTcl_FSInternalToNormalizedProc\fR(
.CE
.SS CREATEINTERNALREPPROC
.PP
-Function to take a path object, and calculate an internal
+Function to take a path value, and calculate an internal
representation for it, and store that native representation in the
-object. May be NULL if paths have no internal representation, or if
+value. May be NULL if paths have no internal representation, or if
the \fITcl_FSPathInFilesystemProc\fR for this filesystem always
immediately creates an internal representation for paths it accepts.
.PP
@@ -1067,7 +1067,7 @@ typedef ClientData \fBTcl_FSCreateInternalRepProc\fR(
.PP
Function to normalize a path. Should be implemented for all
filesystems which can have multiple string representations for the same
-path object. In Tcl, every
+path value. In Tcl, every
.QW path
must have a single unique
.QW normalized
@@ -1079,7 +1079,7 @@ reference to a home directory such as
.QW ~ ,
a path containing symbolic
links, etc). If the very last component in the path is a symbolic
-link, it should not be converted into the object it points to (but
+link, it should not be converted into the value it points to (but
its case or other aspects should be made unique). All other path
components should be converted from symbolic links. This one
exception is required to agree with Tcl's semantics with \fBfile
@@ -1123,7 +1123,7 @@ which is returned. A typical return value might be
or
.QW ftp .
The Tcl_Obj result is owned by the filesystem and so Tcl will
-increment the refCount of that object if it wishes to retain a reference
+increment the reference count of that value if it wishes to retain a reference
to it.
.PP
.CS
@@ -1138,7 +1138,7 @@ different separator than the standard string
.QW / .
Amongst other
uses, it is returned by the \fBfile separator\fR command. The
-return value should be an object with refCount of zero.
+return value should be a value with reference count of zero.
.PP
.CS
typedef Tcl_Obj *\fBTcl_FSFilesystemSeparatorProc\fR(
@@ -1219,8 +1219,9 @@ In addition, if \fIinterp\fR is non-NULL, the
\fBTcl_FSOpenFileChannelProc\fR leaves an error message in \fIinterp\fR's
result after any error.
.PP
-The newly created channel is not registered in the supplied
-interpreter; to register it, use \fBTcl_RegisterChannel\fR. If one of
+The newly created channel must not be registered in the supplied interpreter
+by a \fBTcl_FSOpenFileChannelProc\fR; that task is up to the caller of
+\fBTcl_FSOpenFileChannel\fR (if necessary). If one of
the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
previously closed, the act of creating the new channel also assigns it
as a replacement for the standard channel.
@@ -1256,7 +1257,7 @@ The return value is a standard Tcl result indicating whether an error
occurred in the matching process. Error messages are placed in
\fIinterp\fR, unless \fIinterp\fR in NULL in which case no error
message need be generated; on a \fBTCL_OK\fR result, results should be
-added to the \fIresultPtr\fR object given (which can be assumed to be a
+added to the \fIresultPtr\fR value given (which can be assumed to be a
valid unshared Tcl list). The matches added
to \fIresultPtr\fR should include any path prefix given in \fIpathPtr\fR
(this usually means they will be absolute path specifications).
@@ -1326,7 +1327,7 @@ contents of a link. The result is a Tcl_Obj specifying the contents of
the link given by \fIlinkNamePtr\fR, or NULL if the link could
not be read. The result is owned by the caller (and should therefore
have its ref count incremented before being returned). Any callers
-should call Tcl_DecrRefCount on this result when it is no longer needed.
+should call \fBTcl_DecrRefCount\fR on this result when it is no longer needed.
If \fItoPtr\fR is not NULL, the function should attempt to create a link.
The result in this case should be \fItoPtr\fR if the link was successful
and NULL otherwise. In this case the result is not owned by the caller
@@ -1344,16 +1345,16 @@ typedef Tcl_Obj *\fBTcl_FSListVolumesProc\fR(void);
.CE
.PP
The result should be a list of volumes added by this filesystem, or
-NULL (or an empty list) if no volumes are provided. The result object
+NULL (or an empty list) if no volumes are provided. The result value
is considered to be owned by the filesystem (not by Tcl's core), but
-should be given a refCount for Tcl. Tcl will use the contents of the
-list and then decrement that refCount. This allows filesystems to
+should be given a reference count for Tcl. Tcl will use the contents of the
+list and then decrement that reference count. This allows filesystems to
choose whether they actually want to retain a
.QW "master list"
of volumes
or not (if not, they generate the list on the fly and pass it to Tcl
-with a refCount of 1 and then forget about the list, if yes, then
-they simply increment the refCount of their master list and pass it
+with a reference count of 1 and then forget about the list, if yes, then
+they simply increment the reference count of their master list and pass it
to Tcl which will copy the contents and then decrement the count back
to where it was).
.PP
@@ -1379,7 +1380,7 @@ will take that list and first increment its reference count before using it.
On completion of that use, Tcl will decrement its reference count. Hence if
the list should be disposed of by Tcl when done, it should have a
reference count of zero, and if the list should not be disposed of, the
-filesystem should ensure it returns an object with a reference count
+filesystem should ensure it returns a value with a reference count
of at least one.
.SS FILEATTRSGETPROC
.PP
diff --git a/doc/FindExec.3 b/doc/FindExec.3
index 66cc1f1..b01315c 100644
--- a/doc/FindExec.3
+++ b/doc/FindExec.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_FindExecutable 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_FindExecutable, Tcl_GetNameOfExecutable \- identify or return the name of the binary file containing the application
@@ -47,7 +47,7 @@ will return an empty string.
.PP
On Windows platforms this procedure is typically invoked as the very
first thing in the application's main program as well; Its \fIargv[0]\fR
-argument is only used to indicate wheter the executable has a stderr
+argument is only used to indicate whether the executable has a stderr
channel (any non-null value) or not (the value null). If \fBTcl_SetPanicProc\fR
is never called and no debugger is running, this determines whether
the panic message is sent to stderr or to a standard system dialog.
diff --git a/doc/GetCwd.3 b/doc/GetCwd.3
index 964e237..58abcde 100755..100644
--- a/doc/GetCwd.3
+++ b/doc/GetCwd.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_GetCwd 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_GetCwd, Tcl_Chdir \- manipulate the current working directory
diff --git a/doc/GetHostName.3 b/doc/GetHostName.3
index 28f3a4f..8aed0dc 100644
--- a/doc/GetHostName.3
+++ b/doc/GetHostName.3
@@ -2,8 +2,8 @@
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
-.so man.macros
.TH Tcl_GetHostName 3 8.3 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_GetHostName \- get the name of the local host
diff --git a/doc/GetIndex.3 b/doc/GetIndex.3
index f60feb5..fc6f40b 100644
--- a/doc/GetIndex.3
+++ b/doc/GetIndex.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_GetIndexFromObj 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_GetIndexFromObj, Tcl_GetIndexFromObjStruct \- lookup string in table of keywords
@@ -26,16 +26,22 @@ int
Interpreter to use for error reporting; if NULL, then no message is
provided on errors.
.AP Tcl_Obj *objPtr in/out
-The string value of this object is used to search through \fItablePtr\fR.
+The string value of this value is used to search through \fItablePtr\fR.
The internal representation is modified to hold the index of the matching
table entry.
.AP "const char *const" *tablePtr in
An array of null-terminated strings. The end of the array is marked
by a NULL string pointer.
+Note that references to the \fItablePtr\fR may be retained in the
+internal representation of \fIobjPtr\fR, so this should represent the
+address of a statically-allocated array.
.AP "const void" *structTablePtr in
An array of arbitrary type, typically some \fBstruct\fR type.
The first member of the structure must be a null-terminated string.
The size of the structure is given by \fIoffset\fR.
+Note that references to the \fIstructTablePtr\fR may be retained in the
+internal representation of \fIobjPtr\fR, so this should represent the
+address of a statically-allocated array of structures.
.AP int offset in
The offset to add to structTablePtr to get to the next entry.
The end of the array is marked by a NULL string pointer.
@@ -51,10 +57,10 @@ The index of the string in \fItablePtr\fR that matches the value of
.BE
.SH DESCRIPTION
.PP
-This procedure provides an efficient way for looking up keywords,
-switch names, option names, and similar things where the value of
-an object must be one of a predefined set of values.
-\fIObjPtr\fR is compared against each of
+These procedures provide an efficient way for looking up keywords,
+switch names, option names, and similar things where the literal value of
+a Tcl value must be chosen from a predefined set.
+\fBTcl_GetIndexFromObj\fR compares \fIobjPtr\fR against each of
the strings in \fItablePtr\fR to find a match. A match occurs if
\fIobjPtr\fR's string value is identical to one of the strings in
\fItablePtr\fR, or if it is a non-empty unique abbreviation
@@ -95,4 +101,4 @@ each of several array elements.
.SH "SEE ALSO"
prefix(n), Tcl_WrongNumArgs(3)
.SH KEYWORDS
-index, object, table lookup
+index, option, value, table lookup
diff --git a/doc/GetInt.3 b/doc/GetInt.3
index f77d337..4e9d636 100644
--- a/doc/GetInt.3
+++ b/doc/GetInt.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_GetInt 3 "" Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_GetInt, Tcl_GetDouble, Tcl_GetBoolean \- convert from string to integer, double, or boolean
diff --git a/doc/GetOpnFl.3 b/doc/GetOpnFl.3
index 38aa976..86d1b94 100644
--- a/doc/GetOpnFl.3
+++ b/doc/GetOpnFl.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_GetOpenFile 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_GetOpenFile \- Return a FILE* for a channel registered in the given interpreter (Unix only)
diff --git a/doc/GetStdChan.3 b/doc/GetStdChan.3
index 7bc2e1b..8af1e7e 100644
--- a/doc/GetStdChan.3
+++ b/doc/GetStdChan.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_GetStdChannel 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -77,7 +77,7 @@ assigned starting with standard input, followed by standard output, with
standard error being last.
.PP
See \fBTcl_StandardChannels\fR for a general treatise about standard
-channels and the behaviour of the Tcl library with regard to them.
+channels and the behavior of the Tcl library with regard to them.
.SH "SEE ALSO"
Tcl_Close(3), Tcl_CreateChannel(3), Tcl_Main(3), tclsh(1)
diff --git a/doc/GetTime.3 b/doc/GetTime.3
index d902f90..6b885ee 100644
--- a/doc/GetTime.3
+++ b/doc/GetTime.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_GetTime 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_GetTime, Tcl_SetTimeProc, Tcl_QueryTimeProc \- get date and time
@@ -90,21 +90,19 @@ typedef void \fBTcl_ScaleTimeProc\fR(
.CE
.PP
The \fItimebuf\fR fields contain the time to manipulate, and the
-\fIclientData\fR fields contain a pointer supplied at the time the
-handler functions were registered.
+\fIclientData\fR fields contain a pointer supplied at the time the handler
+functions were registered.
.PP
-Any handler pair specified has to return data which is consistent
-between them. In other words, setting one handler of the pair to
-something assuming a 10-times slowdown, and the other handler of the
-pair to something assuming a two-times slowdown is wrong and not
-allowed.
+Any handler pair specified has to return data which is consistent between
+them. In other words, setting one handler of the pair to something assuming a
+10-times slowdown, and the other handler of the pair to something assuming a
+two-times slowdown is wrong and not allowed.
.PP
-The set handler functions are allowed to run the delivered time
-backwards, however this should be avoided. We have to allow it as the
-native time can run backwards as the user can fiddle with the system
-time one way or other. Note that the insertion of the hooks will not
-change the behaviour of the Tcl core with regard to this situation,
-i.e. the existing behaviour is retained.
+The set handler functions are allowed to run the delivered time backwards,
+however this should be avoided. We have to allow it as the native time can run
+backwards as the user can fiddle with the system time one way or other. Note
+that the insertion of the hooks will not change the behavior of the Tcl core
+with regard to this situation, i.e. the existing behavior is retained.
.SH "SEE ALSO"
clock(n)
.SH KEYWORDS
diff --git a/doc/GetVersion.3 b/doc/GetVersion.3
index 47034d0..89f63d5 100755..100644
--- a/doc/GetVersion.3
+++ b/doc/GetVersion.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_GetVersion 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_GetVersion \- get the version of the library at runtime
diff --git a/doc/Hash.3 b/doc/Hash.3
index 5a19d72..fcc0d83a 100644
--- a/doc/Hash.3
+++ b/doc/Hash.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Hash 3 "" Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_InitHashTable, Tcl_InitCustomHashTable, Tcl_InitObjHashTable, Tcl_DeleteHashTable, Tcl_CreateHashEntry, Tcl_DeleteHashEntry, Tcl_FindHashEntry, Tcl_GetHashValue, Tcl_SetHashValue, Tcl_GetHashKey, Tcl_FirstHashEntry, Tcl_NextHashEntry, Tcl_HashStats \- procedures to manage hash tables
@@ -57,7 +57,7 @@ Kind of keys to use for new hash table. Must be either
\fBTCL_STRING_KEYS\fR, \fBTCL_ONE_WORD_KEYS\fR, \fBTCL_CUSTOM_TYPE_KEYS\fR,
\fBTCL_CUSTOM_PTR_KEYS\fR, or an integer value greater than 1.
.AP Tcl_HashKeyType *typePtr in
-Address of structure which defines the behaviour of the hash table.
+Address of structure which defines the behavior of the hash table.
.AP "const void" *key in
Key to use for probe into table. Exact form depends on
\fIkeyType\fR used to create table.
@@ -310,14 +310,14 @@ typedef Tcl_HashEntry *\fBTcl_AllocHashEntryProc\fR(
void *\fIkeyPtr\fR);
.CE
.PP
-If this is NULL then Tcl_Alloc is used to allocate enough space for a
+If this is NULL then \fBTcl_Alloc\fR is used to allocate enough space for a
Tcl_HashEntry, the key pointer is assigned to key.oneWordValue and the
clientData is set to NULL. String keys and array keys use this function to
allocate enough space for the entry and the key in one block, rather than
doing it in two blocks. This saves space for a pointer to the key from the
entry and another memory allocation. Tcl_Obj* keys use this function to
allocate enough space for an entry and increment the reference count on the
-object.
+value.
.PP
The \fIfreeEntryProc\fR member contains the address of a function called to
free space for an entry.
@@ -327,8 +327,8 @@ typedef void \fBTcl_FreeHashEntryProc\fR(
Tcl_HashEntry *\fIhPtr\fR);
.CE
.PP
-If this is NULL then Tcl_Free is used to free the space for the entry.
+If this is NULL then \fBTcl_Free\fR is used to free the space for the entry.
Tcl_Obj* keys use this function to decrement the reference count on the
-object.
+value.
.SH KEYWORDS
hash table, key, lookup, search, value
diff --git a/doc/Init.3 b/doc/Init.3
index f421479..33c27a3 100644
--- a/doc/Init.3
+++ b/doc/Init.3
@@ -2,8 +2,8 @@
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
-.so man.macros
.TH Tcl_Init 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_Init \- find and source initialization script
diff --git a/doc/InitStubs.3 b/doc/InitStubs.3
index 318c564..73c3437 100644
--- a/doc/InitStubs.3
+++ b/doc/InitStubs.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_InitStubs 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_InitStubs \- initialize the Tcl stubs mechanism
@@ -63,9 +63,9 @@ Define the \fBUSE_TCL_STUBS\fR symbol. Typically, you would include the
\fB\-DUSE_TCL_STUBS\fR flag when compiling the extension.
.IP 3) 5
Link the extension with the Tcl stubs library instead of the standard
-Tcl library. On Unix platforms, the library name is
-\fIlibtclstub8.1.a\fR; on Windows platforms, the library name is
-\fItclstub81.lib\fR.
+Tcl library. For example, to use the Tcl 8.6 ABI on Unix platforms,
+the library name is \fIlibtclstub8.6.a\fR; on Windows platforms, the
+library name is \fItclstub86.lib\fR.
.PP
If the extension also requires the Tk API, it must also call
\fBTk_InitStubs\fR to initialize the Tk stubs interface and link
diff --git a/doc/IntObj.3 b/doc/IntObj.3
index cde96f8..d42b44a 100644
--- a/doc/IntObj.3
+++ b/doc/IntObj.3
@@ -4,11 +4,11 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_IntObj 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
-Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj, Tcl_GetIntFromObj, Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_NewBignumObj, Tcl_SetBignumObj, Tcl_GetBignumFromObj, Tcl_TakeBignumFromObj \- manipulate Tcl objects as integer values
+Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj, Tcl_GetIntFromObj, Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_NewBignumObj, Tcl_SetBignumObj, Tcl_GetBignumFromObj, Tcl_TakeBignumFromObj \- manipulate Tcl values as integers
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -56,17 +56,17 @@ int
.SH ARGUMENTS
.AS Tcl_WideInt doubleValue in/out
.AP int intValue in
-Integer value used to initialize or set a Tcl object.
+Integer value used to initialize or set a Tcl value.
.AP long longValue in
-Long integer value used to initialize or set a Tcl object.
+Long integer value used to initialize or set a Tcl value.
.AP Tcl_WideInt wideValue in
-Wide integer value used to initialize or set a Tcl object.
+Wide integer value used to initialize or set a Tcl value.
.AP Tcl_Obj *objPtr in/out
For \fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR, \fBTcl_SetWideIntObj\fR,
-and \fBTcl_SetBignumObj\fR, this points to the object in which to store an
+and \fBTcl_SetBignumObj\fR, this points to the value in which to store an
integral value. For \fBTcl_GetIntFromObj\fR, \fBTcl_GetLongFromObj\fR,
\fBTcl_GetWideIntFromObj\fR, \fBTcl_GetBignumFromObj\fR, and
-\fBTcl_TakeBignumFromObj\fR, this refers to the object from which
+\fBTcl_TakeBignumFromObj\fR, this refers to the value from which
to retrieve an integral value.
.AP Tcl_Interp *interp in/out
When non-NULL, an error message is left here when integral value
@@ -86,7 +86,7 @@ used to initialize a multi-precision integer value.
.BE
.SH DESCRIPTION
.PP
-These procedures are used to create, modify, and read Tcl objects
+These procedures are used to create, modify, and read Tcl values
that hold integral values.
.PP
The different routines exist to accommodate different integral types in C
@@ -103,22 +103,22 @@ by the LibTomMath multiple-precision integer library.
.PP
The \fBTcl_NewIntObj\fR, \fBTcl_NewLongObj\fR, \fBTcl_NewWideIntObj\fR,
and \fBTcl_NewBignumObj\fR routines each create and return a new
-Tcl object initialized to the integral value of the argument. The
-returned Tcl object is unshared.
+Tcl value initialized to the integral value of the argument. The
+returned Tcl value is unshared.
.PP
The \fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR, \fBTcl_SetWideIntObj\fR,
and \fBTcl_SetBignumObj\fR routines each set the value of an existing
-Tcl object pointed to by \fIobjPtr\fR to the integral value provided
+Tcl value pointed to by \fIobjPtr\fR to the integral value provided
by the other argument. The \fIobjPtr\fR argument must point to an
-unshared Tcl object. Any attempt to set the value of a shared Tcl object
+unshared Tcl value. Any attempt to set the value of a shared Tcl value
violates Tcl's copy-on-write policy. Any existing string representation
-or internal representation in the unshared Tcl object will be freed
+or internal representation in the unshared Tcl value will be freed
as a consequence of setting the new value.
.PP
The \fBTcl_GetIntFromObj\fR, \fBTcl_GetLongFromObj\fR,
\fBTcl_GetWideIntFromObj\fR, \fBTcl_GetBignumFromObj\fR, and
\fBTcl_TakeBignumFromObj\fR routines attempt to retrieve an integral
-value of the appropriate type from the Tcl object \fIobjPtr\fR. If the
+value of the appropriate type from the Tcl value \fIobjPtr\fR. If the
attempt succeeds, then \fBTCL_OK\fR is returned, and the value is
written to the storage provided by the caller. The attempt might
fail if \fIobjPtr\fR does not hold an integral value, or if the
@@ -127,7 +127,7 @@ then \fBTCL_ERROR\fR is returned, and if \fIinterp\fR is non-NULL,
an error message is left in \fIinterp\fR. The \fBTcl_ObjType\fR
of \fIobjPtr\fR may be changed to make subsequent calls to the
same routine more efficient. Unlike the other functions,
-\fBTcl_TakeBignumFromObj\fR may set the content of the Tcl object
+\fBTcl_TakeBignumFromObj\fR may set the content of the Tcl value
\fIobjPtr\fR to an empty string in the process of retrieving the
multiple-precision integer value.
.PP
@@ -148,4 +148,5 @@ integer value in the \fBmp_int\fR value \fIbigValue\fR.
.SH "SEE ALSO"
Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_GetObjResult
.SH KEYWORDS
-integer, integer object, integer type, internal representation, object, object type, string representation
+integer, integer value, integer type, internal representation, value,
+value type, string representation
diff --git a/doc/Interp.3 b/doc/Interp.3
index d908057..b639add 100644
--- a/doc/Interp.3
+++ b/doc/Interp.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Interp 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_Interp \- client-visible fields of interpreter structures
diff --git a/doc/Limit.3 b/doc/Limit.3
index 2941ee8..20a2e02 100644
--- a/doc/Limit.3
+++ b/doc/Limit.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_LimitCheck 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_LimitAddHandler, Tcl_LimitCheck, Tcl_LimitExceeded, Tcl_LimitGetCommands, Tcl_LimitGetGranularity, Tcl_LimitGetTime, Tcl_LimitReady, Tcl_LimitRemoveHandler, Tcl_LimitSetCommands, Tcl_LimitSetGranularity, Tcl_LimitSetTime, Tcl_LimitTypeEnabled, Tcl_LimitTypeExceeded, Tcl_LimitTypeReset, Tcl_LimitTypeSet \- manage and check resource limits on interpreters
diff --git a/doc/LinkVar.3 b/doc/LinkVar.3
index dc71a45..c64720b 100644
--- a/doc/LinkVar.3
+++ b/doc/LinkVar.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_LinkVar 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_LinkVar, Tcl_UnlinkVar, Tcl_UpdateLinkedVar \- link Tcl variable to C variable
diff --git a/doc/ListObj.3 b/doc/ListObj.3
index b93e52b..3af0e7e 100644
--- a/doc/ListObj.3
+++ b/doc/ListObj.3
@@ -4,11 +4,11 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_ListObj 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
-Tcl_ListObjAppendList, Tcl_ListObjAppendElement, Tcl_NewListObj, Tcl_SetListObj, Tcl_ListObjGetElements, Tcl_ListObjLength, Tcl_ListObjIndex, Tcl_ListObjReplace \- manipulate Tcl objects as lists
+Tcl_ListObjAppendList, Tcl_ListObjAppendElement, Tcl_NewListObj, Tcl_SetListObj, Tcl_ListObjGetElements, Tcl_ListObjLength, Tcl_ListObjIndex, Tcl_ListObjReplace \- manipulate Tcl values as lists
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -38,44 +38,44 @@ int
.SH ARGUMENTS
.AS "Tcl_Obj *const" *elemListPtr in/out
.AP Tcl_Interp *interp in
-If an error occurs while converting an object to be a list object,
-an error message is left in the interpreter's result object
+If an error occurs while converting a value to be a list value,
+an error message is left in the interpreter's result value
unless \fIinterp\fR is NULL.
.AP Tcl_Obj *listPtr in/out
-Points to the list object to be manipulated.
-If \fIlistPtr\fR does not already point to a list object,
+Points to the list value to be manipulated.
+If \fIlistPtr\fR does not already point to a list value,
an attempt will be made to convert it to one.
.AP Tcl_Obj *elemListPtr in/out
-For \fBTcl_ListObjAppendList\fR, this points to a list object
+For \fBTcl_ListObjAppendList\fR, this points to a list value
containing elements to be appended onto \fIlistPtr\fR.
Each element of *\fIelemListPtr\fR will
become a new element of \fIlistPtr\fR.
If *\fIelemListPtr\fR is not NULL and
-does not already point to a list object,
+does not already point to a list value,
an attempt will be made to convert it to one.
.AP Tcl_Obj *objPtr in
For \fBTcl_ListObjAppendElement\fR,
-points to the Tcl object that will be appended to \fIlistPtr\fR.
+points to the Tcl value that will be appended to \fIlistPtr\fR.
For \fBTcl_SetListObj\fR,
-this points to the Tcl object that will be converted to a list object
+this points to the Tcl value that will be converted to a list value
containing the \fIobjc\fR elements of the array referenced by \fIobjv\fR.
.AP int *objcPtr in
Points to location where \fBTcl_ListObjGetElements\fR
-stores the number of element objects in \fIlistPtr\fR.
+stores the number of element values in \fIlistPtr\fR.
.AP Tcl_Obj ***objvPtr out
A location where \fBTcl_ListObjGetElements\fR stores a pointer to an array
-of pointers to the element objects of \fIlistPtr\fR.
+of pointers to the element values of \fIlistPtr\fR.
.AP int objc in
-The number of Tcl objects that \fBTcl_NewListObj\fR
-will insert into a new list object,
+The number of Tcl values that \fBTcl_NewListObj\fR
+will insert into a new list value,
and \fBTcl_ListObjReplace\fR will insert into \fIlistPtr\fR.
For \fBTcl_SetListObj\fR,
-the number of Tcl objects to insert into \fIobjPtr\fR.
+the number of Tcl values to insert into \fIobjPtr\fR.
.AP "Tcl_Obj *const" objv[] in
-An array of pointers to objects.
-\fBTcl_NewListObj\fR will insert these objects into a new list object
+An array of pointers to values.
+\fBTcl_NewListObj\fR will insert these values into a new list value
and \fBTcl_ListObjReplace\fR will insert them into an existing \fIlistPtr\fR.
-Each object will become a separate list element.
+Each value will become a separate list element.
.AP int *intPtr out
Points to location where \fBTcl_ListObjLength\fR
stores the length of the list.
@@ -85,7 +85,7 @@ is to return.
The first element has index 0.
.AP Tcl_Obj **objPtrPtr out
Points to place where \fBTcl_ListObjIndex\fR is to store
-a pointer to the resulting list element object.
+a pointer to the resulting list element value.
.AP int first in
Index of the starting list element that \fBTcl_ListObjReplace\fR
is to replace.
@@ -97,85 +97,85 @@ is to replace.
.SH DESCRIPTION
.PP
-Tcl list objects have an internal representation that supports
+Tcl list values have an internal representation that supports
the efficient indexing and appending.
The procedures described in this man page are used to
-create, modify, index, and append to Tcl list objects from C code.
+create, modify, index, and append to Tcl list values from C code.
.PP
\fBTcl_ListObjAppendList\fR and \fBTcl_ListObjAppendElement\fR
-both add one or more objects
-to the end of the list object referenced by \fIlistPtr\fR.
-\fBTcl_ListObjAppendList\fR appends each element of the list object
+both add one or more values
+to the end of the list value referenced by \fIlistPtr\fR.
+\fBTcl_ListObjAppendList\fR appends each element of the list value
referenced by \fIelemListPtr\fR while
-\fBTcl_ListObjAppendElement\fR appends the single object
+\fBTcl_ListObjAppendElement\fR appends the single value
referenced by \fIobjPtr\fR.
-Both procedures will convert the object referenced by \fIlistPtr\fR
-to a list object if necessary.
+Both procedures will convert the value referenced by \fIlistPtr\fR
+to a list value if necessary.
If an error occurs during conversion,
both procedures return \fBTCL_ERROR\fR and leave an error message
-in the interpreter's result object if \fIinterp\fR is not NULL.
-Similarly, if \fIelemListPtr\fR does not already refer to a list object,
+in the interpreter's result value if \fIinterp\fR is not NULL.
+Similarly, if \fIelemListPtr\fR does not already refer to a list value,
\fBTcl_ListObjAppendList\fR will attempt to convert it to one
and if an error occurs during conversion,
will return \fBTCL_ERROR\fR
-and leave an error message in the interpreter's result object
+and leave an error message in the interpreter's result value
if interp is not NULL.
Both procedures invalidate any old string representation of \fIlistPtr\fR
-and, if it was converted to a list object,
+and, if it was converted to a list value,
free any old internal representation.
Similarly, \fBTcl_ListObjAppendList\fR frees any old internal representation
-of \fIelemListPtr\fR if it converts it to a list object.
+of \fIelemListPtr\fR if it converts it to a list value.
After appending each element in \fIelemListPtr\fR,
\fBTcl_ListObjAppendList\fR increments the element's reference count
since \fIlistPtr\fR now also refers to it.
For the same reason, \fBTcl_ListObjAppendElement\fR
increments \fIobjPtr\fR's reference count.
If no error occurs,
-the two procedures return \fBTCL_OK\fR after appending the objects.
+the two procedures return \fBTCL_OK\fR after appending the values.
.PP
\fBTcl_NewListObj\fR and \fBTcl_SetListObj\fR
-create a new object or modify an existing object to hold
+create a new value or modify an existing value to hold
the \fIobjc\fR elements of the array referenced by \fIobjv\fR
-where each element is a pointer to a Tcl object.
+where each element is a pointer to a Tcl value.
If \fIobjc\fR is less than or equal to zero,
-they return an empty object.
-The new object's string representation is left invalid.
+they return an empty value.
+The new value's string representation is left invalid.
The two procedures increment the reference counts
-of the elements in \fIobjc\fR since the list object now refers to them.
-The new list object returned by \fBTcl_NewListObj\fR
+of the elements in \fIobjc\fR since the list value now refers to them.
+The new list value returned by \fBTcl_NewListObj\fR
has reference count zero.
.PP
\fBTcl_ListObjGetElements\fR returns a count and a pointer to an array of
-the elements in a list object. It returns the count by storing it in the
+the elements in a list value. It returns the count by storing it in the
address \fIobjcPtr\fR. Similarly, it returns the array pointer by storing
it in the address \fIobjvPtr\fR.
The memory pointed to is managed by Tcl and should not be freed or written
to by the caller. If the list is empty, 0 is stored at \fIobjcPtr\fR
and NULL at \fIobjvPtr\fR.
-If \fIlistPtr\fR is not already a list object, \fBTcl_ListObjGetElements\fR
+If \fIlistPtr\fR is not already a list value, \fBTcl_ListObjGetElements\fR
will attempt to convert it to one; if the conversion fails, it returns
\fBTCL_ERROR\fR and leaves an error message in the interpreter's result
-object if \fIinterp\fR is not NULL.
+value if \fIinterp\fR is not NULL.
Otherwise it returns \fBTCL_OK\fR after storing the count and array pointer.
.PP
-\fBTcl_ListObjLength\fR returns the number of elements in the list object
+\fBTcl_ListObjLength\fR returns the number of elements in the list value
referenced by \fIlistPtr\fR.
It returns this count by storing an integer in the address \fIintPtr\fR.
-If the object is not already a list object,
+If the value is not already a list value,
\fBTcl_ListObjLength\fR will attempt to convert it to one;
if the conversion fails, it returns \fBTCL_ERROR\fR
-and leaves an error message in the interpreter's result object
+and leaves an error message in the interpreter's result value
if \fIinterp\fR is not NULL.
Otherwise it returns \fBTCL_OK\fR after storing the list's length.
.PP
-The procedure \fBTcl_ListObjIndex\fR returns a pointer to the object
+The procedure \fBTcl_ListObjIndex\fR returns a pointer to the value
at element \fIindex\fR in the list referenced by \fIlistPtr\fR.
-It returns this object by storing a pointer to it
+It returns this value by storing a pointer to it
in the address \fIobjPtrPtr\fR.
-If \fIlistPtr\fR does not already refer to a list object,
+If \fIlistPtr\fR does not already refer to a list value,
\fBTcl_ListObjIndex\fR will attempt to convert it to one;
if the conversion fails, it returns \fBTCL_ERROR\fR
-and leaves an error message in the interpreter's result object
+and leaves an error message in the interpreter's result value
if \fIinterp\fR is not NULL.
If the index is out of range,
that is, \fIindex\fR is negative or
@@ -183,19 +183,19 @@ greater than or equal to the number of elements in the list,
\fBTcl_ListObjIndex\fR stores a NULL in \fIobjPtrPtr\fR
and returns \fBTCL_OK\fR.
Otherwise it returns \fBTCL_OK\fR after storing the element's
-object pointer.
+value pointer.
The reference count for the list element is not incremented;
the caller must do that if it needs to retain a pointer to the element.
.PP
\fBTcl_ListObjReplace\fR replaces zero or more elements
of the list referenced by \fIlistPtr\fR
-with the \fIobjc\fR objects in the array referenced by \fIobjv\fR.
-If \fIlistPtr\fR does not point to a list object,
+with the \fIobjc\fR values in the array referenced by \fIobjv\fR.
+If \fIlistPtr\fR does not point to a list value,
\fBTcl_ListObjReplace\fR will attempt to convert it to one;
if the conversion fails, it returns \fBTCL_ERROR\fR
-and leaves an error message in the interpreter's result object
+and leaves an error message in the interpreter's result value
if \fIinterp\fR is not NULL.
-Otherwise, it returns \fBTCL_OK\fR after replacing the objects.
+Otherwise, it returns \fBTCL_OK\fR after replacing the values.
If \fIobjv\fR is NULL, no new elements are added.
If the argument \fIfirst\fR is zero or negative,
it refers to the first element.
@@ -210,13 +210,13 @@ designated by \fIfirst\fR.
old string representation.
The reference counts of any elements inserted from \fIobjv\fR
are incremented since the resulting list now refers to them.
-Similarly, the reference counts for any replaced objects are decremented.
+Similarly, the reference counts for any replaced values are decremented.
.PP
Because \fBTcl_ListObjReplace\fR combines
both element insertion and deletion,
it can be used to implement a number of list operations.
-For example, the following code inserts the \fIobjc\fR objects
-referenced by the array of object pointers \fIobjv\fR
+For example, the following code inserts the \fIobjc\fR values
+referenced by the array of value pointers \fIobjv\fR
just before the element \fIindex\fR of the list referenced by \fIlistPtr\fR:
.PP
.CS
@@ -224,7 +224,7 @@ result = \fBTcl_ListObjReplace\fR(interp, listPtr, index, 0,
objc, objv);
.CE
.PP
-Similarly, the following code appends the \fIobjc\fR objects
+Similarly, the following code appends the \fIobjc\fR values
referenced by the array \fIobjv\fR
to the end of the list \fIlistPtr\fR:
.PP
@@ -247,4 +247,5 @@ result = \fBTcl_ListObjReplace\fR(interp, listPtr, first, count,
.SH "SEE ALSO"
Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3), Tcl_GetObjResult(3)
.SH KEYWORDS
-append, index, insert, internal representation, length, list, list object, list type, object, object type, replace, string representation
+append, index, insert, internal representation, length, list, list value,
+list type, value, value type, replace, string representation
diff --git a/doc/Load.3 b/doc/Load.3
index c088f32..0ffaf57 100644
--- a/doc/Load.3
+++ b/doc/Load.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Load 3 8.6 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_LoadFile, Tcl_FindSymbol \- platform-independent dynamic library loading
@@ -31,7 +31,8 @@ Array of names of symbols to be resolved during the load of the library, or
NULL if no symbols are to be resolved. If an array is given, the last entry in
the array must be NULL.
.AP int flags in
-Reserved for future expansion. Must be 0.
+The value should normally be 0, but \fITCL_LOAD_GLOBAL\fR or \fITCL_LOAD_LAZY\fR
+or a combination of those two is allowed as well.
.AP void *procPtrs out
Points to an array that will hold the addresses of the functions described in
the \fIsymbols\fR argument. Should be NULL if no symbols are to be resolved.
diff --git a/doc/Method.3 b/doc/Method.3
index 43b3609..550b64a 100644
--- a/doc/Method.3
+++ b/doc/Method.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Method 3 0.1 TclOO "TclOO Library Functions"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -172,8 +172,9 @@ typedef struct {
.PP
The \fIversion\fR field allows for future expansion of the structure, and
should always be declared equal to TCL_OO_METHOD_VERSION_CURRENT. The
-\fIname\fR field provides a human-readable name for the type, and is reserved
-for debugging.
+\fIname\fR field provides a human-readable name for the type, and is the value
+that is exposed via the \fBinfo class methodtype\fR and
+\fBinfo object methodtype\fR Tcl commands.
.PP
The \fIcallProc\fR field gives a function that is called when the method is
invoked; it must never be NULL.
diff --git a/doc/NRE.3 b/doc/NRE.3
index 5c27491..a8ac477 100644
--- a/doc/NRE.3
+++ b/doc/NRE.3
@@ -4,11 +4,11 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH NRE 3 8.6 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
-Tcl_NRCreateCommand, Tcl_NRCallObjProc, Tcl_NREvalObj, Tcl_NREvalObjv, Tcl_NRCmdSwap, Tcl_NRAddCallback \- Non-Recursive (stackless) evaluation of Tcl scripts.
+Tcl_NRCreateCommand, Tcl_NRCallObjProc, Tcl_NREvalObj, Tcl_NREvalObjv, Tcl_NRCmdSwap, Tcl_NRExprObj, Tcl_NRAddCallback \- Non-Recursive (stackless) evaluation of Tcl scripts.
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -57,7 +57,7 @@ is \fBNULL\fR, then no procedure is called before the command is deleted.
.AP int objc in
Count of parameters provided to the implementation of a command.
.AP Tcl_Obj **objv in
-Pointer to an array of Tcl objects. Each object holds the value of a
+Pointer to an array of Tcl values. Each value holds the value of a
single word in the command to execute.
.AP Tcl_Obj *objPtr in
Pointer to a Tcl_Obj whose value is a script or expression to execute.
@@ -141,10 +141,10 @@ 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 object (returned from \fBTcl_CreateObjCommand\fR or
+\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_NREvalObj\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
@@ -207,7 +207,7 @@ is something like:
.PP
.CS
int
-\fITheCmdObjProc\fR(
+\fITheCmdOldObjProc\fR(
ClientData clientData,
Tcl_Interp *interp,
int objc,
@@ -225,7 +225,7 @@ int
return result;
}
\fBTcl_CreateObjCommand\fR(interp, "theCommand",
- \fITheCmdObjProc\fR, clientData, TheCmdDeleteProc);
+ \fITheCmdOldObjProc\fR, clientData, TheCmdDeleteProc);
.CE
.PP
To enable a command like this one for trampoline-based evaluation,
@@ -255,8 +255,8 @@ int
int objc,
Tcl_Obj *const objv[])
{
- return \fBTcl_NRCallObjProc\fR(interp, name,
- \fITheCmdNRObjProc\fR, clientData, objc, objv);
+ return \fBTcl_NRCallObjProc\fR(interp, \fITheCmdNRObjProc\fR,
+ clientData, objc, objv);
}
.CE
.PP
@@ -295,7 +295,7 @@ int
int result)
{
/* \fIdata[0] .. data[3]\fR are the four words of data
- * passed to \fBTcl_NREvalObj\fR */
+ * passed to \fBTcl_NRAddCallback\fR */
\fI... postprocessing ...\fR
@@ -317,12 +317,12 @@ and the second is for use when there is already a trampoline in place.
.PP
.CS
\fBTcl_NRCreateCommand\fR(interp, "theCommand",
- \fITheCmdObjProc\fR, \fITheCmdNRObjProc\fR, clientData,
+ \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, object, result, script
+stackless, nonrecursive, execute, command, global, value, result, script
.SH COPYRIGHT
Copyright (c) 2008 by Kevin B. Kenny
diff --git a/doc/Namespace.3 b/doc/Namespace.3
index 50cc559..be89597 100644
--- a/doc/Namespace.3
+++ b/doc/Namespace.3
@@ -7,8 +7,8 @@
'\" Note that some of these functions do not seem to belong, but they
'\" were all introduced with the same TIP (#139)
'\"
-.so man.macros
.TH Tcl_Namespace 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_AppendExportList, Tcl_CreateNamespace, Tcl_DeleteNamespace, Tcl_Export, Tcl_FindCommand, Tcl_FindNamespace, Tcl_ForgetImport, Tcl_GetCurrentNamespace, Tcl_GetGlobalNamespace, Tcl_GetNamespaceUnknownHandler, Tcl_Import, Tcl_SetNamespaceUnknownHandler \- manipulate namespaces
@@ -67,7 +67,7 @@ if no such callback is to be performed.
The namespace to be manipulated, or NULL (for other than
\fBTcl_DeleteNamespace\fR) to manipulate the current namespace.
.AP Tcl_Obj *objPtr out
-A reference to an unshared object to which the function output will be
+A reference to an unshared value to which the function output will be
written.
.AP "const char" *pattern in
The glob-style pattern (see \fBTcl_StringMatch\fR) that describes the
diff --git a/doc/Notifier.3 b/doc/Notifier.3
index 435f779..f2976b1 100644
--- a/doc/Notifier.3
+++ b/doc/Notifier.3
@@ -5,11 +5,11 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Notifier 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
-Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrentThread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode \- the event queue and notifier interfaces
+Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrentThread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode, Tcl_ServiceModeHook, Tcl_SetNotifier \- the event queue and notifier interfaces
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
diff --git a/doc/OOInitStubs.3 b/doc/OOInitStubs.3
new file mode 100644
index 0000000..bc42453
--- /dev/null
+++ b/doc/OOInitStubs.3
@@ -0,0 +1,54 @@
+'\"
+'\" Copyright (c) 2012 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_OOInitStubs 3 1.0 TclOO "TclOO Library Functions"
+.so man.macros
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_OOInitStubs \- initialize library access to TclOO functionality
+.SH SYNOPSIS
+.nf
+\fB#include <tclOO.h>\fR
+.sp
+const char *
+\fBTcl_OOInitStubs\fR(\fIinterp\fR)
+.fi
+.SH ARGUMENTS
+.AS Tcl_Interp *interp in
+.AP Tcl_Interp *interp in
+The Tcl interpreter that the TclOO API is integrated with and whose C
+interface is going to be used.
+.BE
+.SH DESCRIPTION
+.PP
+When an extension library is going to use the C interface exposed by TclOO, it
+should use \fBTcl_OOInitStubs\fR to initialize its access to that interface
+from within its \fI*\fB_Init\fR (or \fI*\fB_SafeInit\fR) function, passing in
+the \fIinterp\fR that was passed into that routine as context. If the result
+of calling \fBTcl_OOInitStubs\fR is NULL, the initialization failed and an
+error message will have been left in the interpreter's result. Otherwise, the
+initialization succeeded and the TclOO API may thereafter be used; the
+version of the TclOO API is returned.
+.PP
+When using this function, either the C #define symbol \fBUSE_TCLOO_STUBS\fR
+should be defined and your library code linked against the Tcl stub library,
+or that #define symbol should \fInot\fR be defined and your library code
+linked against the Tcl main library directly.
+.SH "BACKWARD COMPATIBILITY NOTE"
+.PP
+If you are linking against the Tcl 8.5 forward compatibility package for
+TclOO, \fIonly\fR the stub-enabled configuration is supported and you should
+also link against the TclOO independent stub library; that library is an
+integrated part of the main Tcl stub library in Tcl 8.6.
+.SH KEYWORDS
+stubs
+.SH "SEE ALSO"
+Tcl_InitStubs(3)
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/doc/Object.3 b/doc/Object.3
index 1c60449..55451ab 100644
--- a/doc/Object.3
+++ b/doc/Object.3
@@ -4,11 +4,11 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Obj 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
-Tcl_NewObj, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_IsShared, Tcl_InvalidateStringRep \- manipulate Tcl objects
+Tcl_NewObj, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_IsShared, Tcl_InvalidateStringRep \- manipulate Tcl values
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -30,35 +30,36 @@ int
.SH ARGUMENTS
.AS Tcl_Obj *objPtr
.AP Tcl_Obj *objPtr in
-Points to an object;
+Points to a value;
must have been the result of a previous call to \fBTcl_NewObj\fR.
.BE
.SH INTRODUCTION
.PP
-This man page presents an overview of Tcl objects and how they are used.
-It also describes generic procedures for managing Tcl objects.
-These procedures are used to create and copy objects,
-and increment and decrement the count of references (pointers) to objects.
+This man page presents an overview of Tcl values (called \fBTcl_Obj\fRs for
+historical reasons) and how they are used.
+It also describes generic procedures for managing Tcl values.
+These procedures are used to create and copy values,
+and increment and decrement the count of references (pointers) to values.
The procedures are used in conjunction with ones
-that operate on specific types of objects such as
+that operate on specific types of values such as
\fBTcl_GetIntFromObj\fR and \fBTcl_ListObjAppendElement\fR.
The individual procedures are described along with the data structures
they manipulate.
.PP
-Tcl's \fIdual-ported\fR objects provide a general-purpose mechanism
+Tcl's \fIdual-ported\fR values provide a general-purpose mechanism
for storing and exchanging Tcl values.
They largely replace the use of strings in Tcl.
For example, they are used to store variable values,
command arguments, command results, and scripts.
-Tcl objects behave like strings but also hold an internal representation
+Tcl values behave like strings but also hold an internal representation
that can be manipulated more efficiently.
-For example, a Tcl list is now represented as an object
+For example, a Tcl list is now represented as a value
that holds the list's string representation
-as well as an array of pointers to the objects for each list element.
-Dual-ported objects avoid most runtime type conversions.
+as well as an array of pointers to the values for each list element.
+Dual-ported values avoid most runtime type conversions.
They also improve the speed of many operations
since an appropriate representation is immediately available.
-The compiler itself uses Tcl objects to
+The compiler itself uses Tcl values to
cache the instruction bytecodes resulting from compiling scripts.
.PP
The two representations are a cache of each other and are computed lazily.
@@ -73,39 +74,39 @@ between integers and strings.
Only when it needs a string representing the variable's value,
say to print it,
will the program regenerate the string representation from the integer.
-Although objects contain an internal representation,
+Although values contain an internal representation,
their semantics are defined in terms of strings:
an up-to-date string can always be obtained,
-and any change to the object will be reflected in that string
-when the object's string representation is fetched.
+and any change to the value will be reflected in that string
+when the value's string representation is fetched.
Because of this representation invalidation and regeneration,
it is dangerous for extension writers to access
\fBTcl_Obj\fR fields directly.
It is better to access Tcl_Obj information using
procedures like \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR.
.PP
-Objects are allocated on the heap
+Values are allocated on the heap
and are referenced using a pointer to their \fBTcl_Obj\fR structure.
-Objects are shared as much as possible.
+Values are shared as much as possible.
This significantly reduces storage requirements
-because some objects such as long lists are very large.
+because some values such as long lists are very large.
Also, most Tcl values are only read and never modified.
This is especially true for procedure arguments,
which can be shared between the caller and the called procedure.
Assignment and argument binding is done by
simply assigning a pointer to the value.
Reference counting is used to determine when it is safe to
-reclaim an object's storage.
+reclaim a value's storage.
.PP
-Tcl objects are typed.
-An object's internal representation is controlled by its type.
+Tcl values are typed.
+A value's internal representation is controlled by its type.
Several types are predefined in the Tcl core
including integer, double, list, and bytecode.
Extension writers can extend the set of types
by defining their own \fBTcl_ObjType\fR structs.
.SH "THE TCL_OBJ STRUCTURE"
.PP
-Each Tcl object is represented by a \fBTcl_Obj\fR structure
+Each Tcl value is represented by a \fBTcl_Obj\fR structure
which is defined as follows.
.PP
.CS
@@ -132,7 +133,7 @@ typedef struct Tcl_Obj {
.CE
.PP
The \fIbytes\fR and the \fIlength\fR members together hold
-an object's UTF-8 string representation,
+a value's UTF-8 string representation,
which is a \fIcounted string\fR not containing null bytes (UTF-8 null
characters should be encoded as a two byte sequence: 192, 128.)
\fIbytes\fR points to the first byte of the string representation.
@@ -142,31 +143,31 @@ at offset \fIlength\fR;
this allows string representations
to be treated as conventional null-terminated C strings.
C programs use \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR to get
-an object's string representation.
+a value's string representation.
If \fIbytes\fR is NULL,
the string representation is invalid.
.PP
-An object's type manages its internal representation.
+A value's type manages its internal representation.
The member \fItypePtr\fR points to the Tcl_ObjType structure
that describes the type.
If \fItypePtr\fR is NULL,
the internal representation is invalid.
.PP
The \fIinternalRep\fR union member holds
-an object's internal representation.
+a value's internal representation.
This is either a (long) integer, a double-precision floating-point number,
a pointer to a value containing additional information
-needed by the object's type to represent the object, a Tcl_WideInt
+needed by the value's type to represent the value, a Tcl_WideInt
integer, two arbitrary pointers, or a pair made up of an unsigned long
integer and a pointer.
.PP
The \fIrefCount\fR member is used to tell when it is safe to free
-an object's storage.
-It holds the count of active references to the object.
+a value's storage.
+It holds the count of active references to the value.
Maintaining the correct reference count is a key responsibility
of extension writers.
Reference counting is discussed below
-in the section \fBSTORAGE MANAGEMENT OF OBJECTS\fR.
+in the section \fBSTORAGE MANAGEMENT OF VALUES\fR.
.PP
Although extension writers can directly access
the members of a Tcl_Obj structure,
@@ -176,21 +177,21 @@ read or update \fIrefCount\fR directly;
they should use macros such as
\fBTcl_IncrRefCount\fR and \fBTcl_IsShared\fR instead.
.PP
-A key property of Tcl objects is that they hold two representations.
-An object typically starts out containing only a string representation:
+A key property of Tcl values is that they hold two representations.
+A value typically starts out containing only a string representation:
it is untyped and has a NULL \fItypePtr\fR.
-An object containing an empty string or a copy of a specified string
+A value containing an empty string or a copy of a specified string
is created using \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR respectively.
-An object's string value is gotten with
+A value's string value is gotten with
\fBTcl_GetStringFromObj\fR or \fBTcl_GetString\fR
and changed with \fBTcl_SetStringObj\fR.
-If the object is later passed to a procedure like \fBTcl_GetIntFromObj\fR
+If the value is later passed to a procedure like \fBTcl_GetIntFromObj\fR
that requires a specific internal representation,
-the procedure will create one and set the object's \fItypePtr\fR.
+the procedure will create one and set the value's \fItypePtr\fR.
The internal representation is computed from the string representation.
-An object's two representations are duals of each other:
+A value's two representations are duals of each other:
changes made to one are reflected in the other.
-For example, \fBTcl_ListObjReplace\fR will modify an object's
+For example, \fBTcl_ListObjReplace\fR will modify a value's
internal representation and the next call to \fBTcl_GetStringFromObj\fR
or \fBTcl_GetString\fR will reflect that change.
.PP
@@ -203,43 +204,43 @@ so that it is only regenerated if it is needed later.
Most C programmers never have to be concerned with how this is done
and simply use procedures such as \fBTcl_GetBooleanFromObj\fR or
\fBTcl_ListObjIndex\fR.
-Programmers that implement their own object types
+Programmers that implement their own value types
must check for invalid representations
and mark representations invalid when necessary.
The procedure \fBTcl_InvalidateStringRep\fR is used
-to mark an object's string representation invalid and to
+to mark a value's string representation invalid and to
free any storage associated with the old string representation.
.PP
-Objects usually remain one type over their life,
-but occasionally an object must be converted from one type to another.
-For example, a C program might build up a string in an object
+Values usually remain one type over their life,
+but occasionally a value must be converted from one type to another.
+For example, a C program might build up a string in a value
with repeated calls to \fBTcl_AppendToObj\fR,
and then call \fBTcl_ListObjIndex\fR to extract a list element from
-the object.
-The same object holding the same string value
+the value.
+The same value holding the same string value
can have several different internal representations
at different times.
-Extension writers can also force an object to be converted from one type
+Extension writers can also force a value to be converted from one type
to another using the \fBTcl_ConvertToType\fR procedure.
-Only programmers that create new object types need to be concerned
+Only programmers that create new value types need to be concerned
about how this is done.
-A procedure defined as part of the object type's implementation
-creates a new internal representation for an object
+A procedure defined as part of the value type's implementation
+creates a new internal representation for a value
and changes its \fItypePtr\fR.
See the man page for \fBTcl_RegisterObjType\fR
-to see how to create a new object type.
-.SH "EXAMPLE OF THE LIFETIME OF AN OBJECT"
+to see how to create a new value type.
+.SH "EXAMPLE OF THE LIFETIME OF A VALUE"
.PP
-As an example of the lifetime of an object,
+As an example of the lifetime of a value,
consider the following sequence of commands:
.PP
.CS
\fBset x 123\fR
.CE
.PP
-This assigns to \fIx\fR an untyped object whose
+This assigns to \fIx\fR an untyped value whose
\fIbytes\fR member points to \fB123\fR and \fIlength\fR member contains 3.
-The object's \fItypePtr\fR member is NULL.
+The value's \fItypePtr\fR member is NULL.
.PP
.CS
\fBputs "x is $x"\fR
@@ -252,16 +253,16 @@ and is fetched for the command.
\fBincr x\fR
.CE
.PP
-The \fBincr\fR command first gets an integer from \fIx\fR's object
+The \fBincr\fR command first gets an integer from \fIx\fR's value
by calling \fBTcl_GetIntFromObj\fR.
-This procedure checks whether the object is already an integer object.
-Since it is not, it converts the object
-by setting the object's \fIinternalRep.longValue\fR member
+This procedure checks whether the value is already an integer value.
+Since it is not, it converts the value
+by setting the value's \fIinternalRep.longValue\fR member
to the integer \fB123\fR
-and setting the object's \fItypePtr\fR
+and setting the value's \fItypePtr\fR
to point to the integer Tcl_ObjType structure.
Both representations are now valid.
-\fBincr\fR increments the object's integer internal representation
+\fBincr\fR increments the value's integer internal representation
then invalidates its string representation
(by calling \fBTcl_InvalidateStringRep\fR)
since the string representation
@@ -271,31 +272,31 @@ no longer corresponds to the internal representation.
\fBputs "x is now $x"\fR
.CE
.PP
-The string representation of \fIx\fR's object is needed
+The string representation of \fIx\fR's value is needed
and is recomputed.
The string representation is now \fB124\fR
and both representations are again valid.
-.SH "STORAGE MANAGEMENT OF OBJECTS"
+.SH "STORAGE MANAGEMENT OF VALUES"
.PP
-Tcl objects are allocated on the heap and are shared as much as possible
+Tcl values are allocated on the heap and are shared as much as possible
to reduce storage requirements.
-Reference counting is used to determine when an object is
+Reference counting is used to determine when a value is
no longer needed and can safely be freed.
-An object just created by \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR
+A value just created by \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR
has \fIrefCount\fR 0.
The macro \fBTcl_IncrRefCount\fR increments the reference count
-when a new reference to the object is created.
+when a new reference to the value is created.
The macro \fBTcl_DecrRefCount\fR decrements the count
when a reference is no longer needed and,
-if the object's reference count drops to zero, frees its storage.
-An object shared by different code or data structures has
+if the value's reference count drops to zero, frees its storage.
+A value shared by different code or data structures has
\fIrefCount\fR greater than 1.
-Incrementing an object's reference count ensures that
+Incrementing a value's reference count ensures that
it will not be freed too early or have its value change accidentally.
.PP
-As an example, the bytecode interpreter shares argument objects
-between calling and called Tcl procedures to avoid having to copy objects.
-It assigns the call's argument objects to the procedure's
+As an example, the bytecode interpreter shares argument values
+between calling and called Tcl procedures to avoid having to copy values.
+It assigns the call's argument values to the procedure's
formal parameter variables.
In doing so, it calls \fBTcl_IncrRefCount\fR to increment
the reference count of each argument since there is now a new
@@ -303,31 +304,31 @@ reference to it from the formal parameter.
When the called procedure returns,
the interpreter calls \fBTcl_DecrRefCount\fR to decrement
each argument's reference count.
-When an object's reference count drops less than or equal to zero,
+When a value's reference count drops less than or equal to zero,
\fBTcl_DecrRefCount\fR reclaims its storage.
Most command procedures do not have to be concerned about
-reference counting since they use an object's value immediately
-and do not retain a pointer to the object after they return.
-However, if they do retain a pointer to an object in a data structure,
+reference counting since they use a value's value immediately
+and do not retain a pointer to the value after they return.
+However, if they do retain a pointer to a value in a data structure,
they must be careful to increment its reference count
since the retained pointer is a new reference.
.PP
-Command procedures that directly modify objects
+Command procedures that directly modify values
such as those for \fBlappend\fR and \fBlinsert\fR must be careful to
-copy a shared object before changing it.
-They must first check whether the object is shared
+copy a shared value before changing it.
+They must first check whether the value is shared
by calling \fBTcl_IsShared\fR.
-If the object is shared they must copy the object
+If the value is shared they must copy the value
by using \fBTcl_DuplicateObj\fR;
-this returns a new duplicate of the original object
+this returns a new duplicate of the original value
that has \fIrefCount\fR 0.
-If the object is not shared,
+If the value is not shared,
the command procedure
.QW "owns"
-the object and can safely modify it directly.
+the value and can safely modify it directly.
For example, the following code appears in the command procedure
that implements \fBlinsert\fR.
-This procedure modifies the list object passed to it in \fIobjv[1]\fR
+This procedure modifies the list value passed to it in \fIobjv[1]\fR
by inserting \fIobjc-3\fR new elements before \fIindex\fR.
.PP
.CS
@@ -340,11 +341,12 @@ result = Tcl_ListObjReplace(interp, listPtr, index, 0,
.CE
.PP
As another example, \fBincr\fR's command procedure
-must check whether the variable's object is shared before
+must check whether the variable's value is shared before
incrementing the integer in its internal representation.
-If it is shared, it needs to duplicate the object
+If it is shared, it needs to duplicate the value
in order to avoid accidentally changing values in other data structures.
.SH "SEE ALSO"
Tcl_ConvertToType(3), Tcl_GetIntFromObj(3), Tcl_ListObjAppendElement(3), Tcl_ListObjIndex(3), Tcl_ListObjReplace(3), Tcl_RegisterObjType(3)
.SH KEYWORDS
-internal representation, object, object creation, object type, reference counting, string representation, type conversion
+internal representation, value, value creation, value type,
+reference counting, string representation, type conversion
diff --git a/doc/ObjectType.3 b/doc/ObjectType.3
index 0c11187..424d560 100644
--- a/doc/ObjectType.3
+++ b/doc/ObjectType.3
@@ -4,11 +4,11 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_ObjType 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
-Tcl_RegisterObjType, Tcl_GetObjType, Tcl_AppendAllObjTypes, Tcl_ConvertToType \- manipulate Tcl object types
+Tcl_RegisterObjType, Tcl_GetObjType, Tcl_AppendAllObjTypes, Tcl_ConvertToType \- manipulate Tcl value types
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -26,31 +26,32 @@ int
.SH ARGUMENTS
.AS "const char" *typeName
.AP "const Tcl_ObjType" *typePtr in
-Points to the structure containing information about the Tcl object type.
+Points to the structure containing information about the Tcl value type.
This storage must live forever,
typically by being statically allocated.
.AP "const char" *typeName in
-The name of a Tcl object type that \fBTcl_GetObjType\fR should look up.
+The name of a Tcl value type that \fBTcl_GetObjType\fR should look up.
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tcl_Obj *objPtr in
-For \fBTcl_AppendAllObjTypes\fR, this points to the object onto which
-it appends the name of each object type as a list element.
-For \fBTcl_ConvertToType\fR, this points to an object that
+For \fBTcl_AppendAllObjTypes\fR, this points to the value onto which
+it appends the name of each value type as a list element.
+For \fBTcl_ConvertToType\fR, this points to a value that
must have been the result of a previous call to \fBTcl_NewObj\fR.
.BE
.SH DESCRIPTION
.PP
-The procedures in this man page manage Tcl object types.
-They are used to register new object types, look up types,
+The procedures in this man page manage Tcl value types (sometimes
+referred to as object types or \fBTcl_ObjType\fRs for historical reasons).
+They are used to register new value types, look up types,
and force conversions from one type to another.
.PP
-\fBTcl_RegisterObjType\fR registers a new Tcl object type
-in the table of all object types that \fBTcl_GetObjType\fR
-can look up by name. There are other object types supported by Tcl
+\fBTcl_RegisterObjType\fR registers a new Tcl value type
+in the table of all value types that \fBTcl_GetObjType\fR
+can look up by name. There are other value types supported by Tcl
as well, which Tcl chooses not to register. Extensions can likewise
-choose to register the object types they create or not.
+choose to register the value types they create or not.
The argument \fItypePtr\fR points to a Tcl_ObjType structure that
describes the new type by giving its name
and by supplying pointers to four procedures
@@ -65,13 +66,13 @@ in the section \fBTHE TCL_OBJTYPE STRUCTURE\fR below.
with name \fItypeName\fR.
It returns NULL if no type with that name is registered.
.PP
-\fBTcl_AppendAllObjTypes\fR appends the name of each registered object type
-as a list element onto the Tcl object referenced by \fIobjPtr\fR.
+\fBTcl_AppendAllObjTypes\fR appends the name of each registered value type
+as a list element onto the Tcl value referenced by \fIobjPtr\fR.
The return value is \fBTCL_OK\fR unless there was an error
-converting \fIobjPtr\fR to a list object;
+converting \fIobjPtr\fR to a list value;
in that case \fBTCL_ERROR\fR is returned.
.PP
-\fBTcl_ConvertToType\fR converts an object from one type to another
+\fBTcl_ConvertToType\fR converts a value from one type to another
if possible.
It creates a new internal representation for \fIobjPtr\fR
appropriate for the target type \fItypePtr\fR
@@ -79,7 +80,7 @@ and sets its \fItypePtr\fR member as determined by calling the
\fItypePtr->setFromAnyProc\fR routine.
Any internal representation for \fIobjPtr\fR's old type is freed.
If an error occurs during conversion, it returns \fBTCL_ERROR\fR
-and leaves an error message in the result object for \fIinterp\fR
+and leaves an error message in the result value for \fIinterp\fR
unless \fIinterp\fR is NULL.
Otherwise, it returns \fBTCL_OK\fR.
Passing a NULL \fIinterp\fR allows this procedure to be used
@@ -94,7 +95,7 @@ use of another related Tcl_ObjType, if it sees fit.
.VE 8.5
.SH "THE TCL_OBJTYPE STRUCTURE"
.PP
-Extension writers can define new object types by defining four
+Extension writers can define new value types by defining four
procedures and
initializing a Tcl_ObjType structure to describe the type.
Extension writers may also pass a pointer to their Tcl_ObjType
@@ -119,12 +120,12 @@ When a type is registered, this is the name used by callers
of \fBTcl_GetObjType\fR to lookup the type. For unregistered
types, the \fIname\fR field is primarily of value for debugging.
The remaining four members are pointers to procedures
-called by the generic Tcl object code:
+called by the generic Tcl value code:
.SS "THE SETFROMANYPROC FIELD"
.PP
The \fIsetFromAnyProc\fR member contains the address of a function
called to create a valid internal representation
-from an object's string representation.
+from a value's string representation.
.PP
.CS
typedef int \fBTcl_SetFromAnyProc\fR(
@@ -134,7 +135,7 @@ typedef int \fBTcl_SetFromAnyProc\fR(
.PP
If an internal representation cannot be created from the string,
it returns \fBTCL_ERROR\fR and puts a message
-describing the error in the result object for \fIinterp\fR
+describing the error in the result value for \fIinterp\fR
unless \fIinterp\fR is NULL.
If \fIsetFromAnyProc\fR is successful,
it stores the new internal representation,
@@ -169,7 +170,7 @@ should \fInot\fR be registered.
.PP
The \fIupdateStringProc\fR member contains the address of a function
called to create a valid string representation
-from an object's internal representation.
+from a value's internal representation.
.PP
.CS
typedef void \fBTcl_UpdateStringProc\fR(
@@ -203,7 +204,7 @@ or other similar routines ask for the string representation.
.SS "THE DUPINTREPPROC FIELD"
.PP
The \fIdupIntRepProc\fR member contains the address of a function
-called to copy an internal representation from one object to another.
+called to copy an internal representation from one value to another.
.PP
.CS
typedef void \fBTcl_DupInternalRepProc\fR(
@@ -215,7 +216,7 @@ typedef void \fBTcl_DupInternalRepProc\fR(
internal representation.
Before the call,
\fIsrcPtr\fR's internal representation is valid and \fIdupPtr\fR's is not.
-\fIsrcPtr\fR's object type determines what
+\fIsrcPtr\fR's value type determines what
copying its internal representation means.
.PP
For example, the \fIdupIntRepProc\fR for the Tcl integer type
@@ -226,7 +227,7 @@ reasonably can.
.SS "THE FREEINTREPPROC FIELD"
.PP
The \fIfreeIntRepProc\fR member contains the address of a function
-that is called when an object is freed.
+that is called when a value is freed.
.PP
.CS
typedef void \fBTcl_FreeInternalRepProc\fR(
@@ -234,22 +235,22 @@ typedef void \fBTcl_FreeInternalRepProc\fR(
.CE
.PP
The \fIfreeIntRepProc\fR function can deallocate the storage
-for the object's internal representation
-and do other type-specific processing necessary when an object is freed.
+for the value's internal representation
+and do other type-specific processing necessary when a value is freed.
.PP
For example, the list type's \fIfreeIntRepProc\fR respects
the storage sharing scheme established by the \fIdupIntRepProc\fR
-so that it only frees storage when the last object sharing it
+so that it only frees storage when the last value sharing it
is being freed.
.PP
The \fIfreeIntRepProc\fR member can be set to NULL
to indicate that the internal representation does not require freeing.
The \fIfreeIntRepProc\fR implementation must not access the
-\fIbytes\fR member of the object, since Tcl makes its own internal
-uses of that field during object deletion. The defined tasks for
+\fIbytes\fR member of the value, since Tcl makes its own internal
+uses of that field during value deletion. The defined tasks for
the \fIfreeIntRepProc\fR have no need to consult the \fIbytes\fR
member.
.SH "SEE ALSO"
Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3)
.SH KEYWORDS
-internal representation, object, object type, string representation, type conversion
+internal representation, value, value type, string representation, type conversion
diff --git a/doc/OpenFileChnl.3 b/doc/OpenFileChnl.3
index 337a9a9..cca76c2 100644
--- a/doc/OpenFileChnl.3
+++ b/doc/OpenFileChnl.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_OpenFileChannel 3 8.3 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -152,24 +152,24 @@ The pattern to match on, passed to Tcl_StringMatch, or NULL.
A Tcl channel for input or output. Must have been the return value
from a procedure such as \fBTcl_OpenFileChannel\fR.
.AP Tcl_Obj *readObjPtr in/out
-A pointer to a Tcl Object in which to store the characters read from the
+A pointer to a Tcl value in which to store the characters read from the
channel.
.AP int charsToRead in
The number of characters to read from the channel. If the channel's encoding
is \fBbinary\fR, this is equivalent to the number of bytes to read from the
channel.
.AP int appendFlag in
-If non-zero, data read from the channel will be appended to the object.
-Otherwise, the data will replace the existing contents of the object.
+If non-zero, data read from the channel will be appended to the value.
+Otherwise, the data will replace the existing contents of the value.
.AP char *readBuf out
A buffer in which to store the bytes read from the channel.
.AP int bytesToRead in
The number of bytes to read from the channel. The buffer \fIreadBuf\fR must
be large enough to hold this many bytes.
.AP Tcl_Obj *lineObjPtr in/out
-A pointer to a Tcl object in which to store the line read from the
+A pointer to a Tcl value in which to store the line read from the
channel. The line read will be appended to the current value of the
-object.
+value.
.AP Tcl_DString *lineRead in/out
A pointer to a Tcl dynamic string in which to store the line read from the
channel. Must have been initialized by the caller. The line read will be
@@ -182,7 +182,7 @@ Length of the input
Flag indicating whether the input should be added to the end or
beginning of the channel buffer.
.AP Tcl_Obj *writeObjPtr in
-A pointer to a Tcl Object whose contents will be output to the channel.
+A pointer to a Tcl value whose contents will be output to the channel.
.AP "const char" *charBuf in
A buffer containing the characters to output to the channel.
.AP "const char" *byteBuf in
@@ -239,7 +239,7 @@ returns NULL and records a POSIX error code that can be
retrieved with \fBTcl_GetErrno\fR.
In addition, if \fIinterp\fR is non-NULL, \fBTcl_OpenFileChannel\fR
leaves an error message in \fIinterp\fR's result after any error.
-As of Tcl 8.4, the object-based API \fBTcl_FSOpenFileChannel\fR should
+As of Tcl 8.4, the value-based API \fBTcl_FSOpenFileChannel\fR should
be used in preference to \fBTcl_OpenFileChannel\fR wherever possible.
.PP
The newly created channel is not registered in the supplied interpreter; to
@@ -305,7 +305,7 @@ open for reading and writing.
.PP
\fBTcl_GetChannelNames\fR and \fBTcl_GetChannelNamesEx\fR write the
names of the registered channels to the interpreter's result as a
-list object. \fBTcl_GetChannelNamesEx\fR will filter these names
+list value. \fBTcl_GetChannelNamesEx\fR will filter these names
according to the \fIpattern\fR. If \fIpattern\fR is NULL, then it
will not do any filtering. The return value is \fBTCL_OK\fR if no
errors occurred writing to the result, otherwise it is \fBTCL_ERROR\fR,
@@ -332,7 +332,7 @@ This procedure interacts with the code managing the standard
channels. If no standard channels were initialized before the first
call to \fBTcl_RegisterChannel\fR, they will get initialized by that
call. See \fBTcl_StandardChannels\fR for a general treatise about
-standard channels and the behaviour of the Tcl library with regard to
+standard channels and the behavior of the Tcl library with regard to
them.
.SH TCL_UNREGISTERCHANNEL
.PP
@@ -435,7 +435,7 @@ platform-specific modes are described in the manual entry for the Tcl
As a performance optimization, when reading from a channel with the encoding
\fBbinary\fR, the bytes are not converted to UTF-8 as they are read.
Instead, they are stored in \fIreadObjPtr\fR's internal representation as a
-byte-array object. The string representation of this object will only be
+byte-array value. The string representation of this value will only be
constructed if it is needed (e.g., because of a call to
\fBTcl_GetStringFromObj\fR). In this way, byte-oriented data can be read
from a channel, manipulated by calling \fBTcl_GetByteArrayFromObj\fR and
@@ -484,7 +484,7 @@ of input unavailability.
.PP
\fBTcl_Gets\fR is the same as \fBTcl_GetsObj\fR except the resulting
characters are appended to the dynamic string given by
-\fIlineRead\fR rather than a Tcl object.
+\fIlineRead\fR rather than a Tcl value.
.SH "TCL_UNGETS"
.PP
\fBTcl_Ungets\fR is used to add data to the input queue of a channel,
@@ -523,14 +523,14 @@ end-of-line sequences according to the \fB\-translation\fR option for the
channel. This is done even if the channel has no encoding.
.PP
\fBTcl_WriteObj\fR is similar to \fBTcl_WriteChars\fR except it
-accepts a Tcl object whose contents will be output to the channel. The
+accepts a Tcl value whose contents will be output to the channel. The
UTF-8 characters in \fIwriteObjPtr\fR's string representation are converted
to the channel's encoding and queued for output to \fIchannel\fR.
As a performance optimization, when writing to a channel with the encoding
\fBbinary\fR, UTF-8 characters are not converted as they are written.
Instead, the bytes in \fIwriteObjPtr\fR's internal representation as a
-byte-array object are written to the channel. The byte-array representation
-of the object will be constructed if it is needed. In this way,
+byte-array value are written to the channel. The byte-array representation
+of the value will be constructed if it is needed. In this way,
byte-oriented data can be read from a channel, manipulated by calling
\fBTcl_GetByteArrayFromObj\fR and related functions, and then written to a
channel without the expense of ever converting to or from UTF-8.
diff --git a/doc/OpenTcp.3 b/doc/OpenTcp.3
index 78ac70b..9fe2615 100644
--- a/doc/OpenTcp.3
+++ b/doc/OpenTcp.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_OpenTcpClient 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/Panic.3 b/doc/Panic.3
index 48aed2b..28d56fa 100644
--- a/doc/Panic.3
+++ b/doc/Panic.3
@@ -2,8 +2,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Panic 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/ParseArgs.3 b/doc/ParseArgs.3
index dd33830..df0ad33 100644
--- a/doc/ParseArgs.3
+++ b/doc/ParseArgs.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_ParseArgsObjv 3 8.6 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_ParseArgsObjv \- parse arguments according to a tabular description
@@ -134,7 +134,7 @@ typedef int (\fBTcl_ArgvFuncProc\fR)(
.PP
The result is a boolean value indicating whether to consume the following
argument. The \fIclientData\fR is the value from the table entry, the
-\fIobjPtr\fR is the object that represents the following argument or NULL if
+\fIobjPtr\fR is the value that represents the following argument or NULL if
there are no following arguments at all, and the \fIdstPtr\fR argument to the
\fBTcl_ArgvFuncProc\fR is the location to write the parsed value to.
.RE
@@ -186,7 +186,7 @@ marks all following arguments to be left unprocessed. The \fIsrcPtr\fR,
.
This argument takes a following string value argument. A pointer to the string
will be stored at \fIdstPtr\fR; the string inside will have a lifetime linked
-to the lifetime of the string representation of the argument object that it
+to the lifetime of the string representation of the argument value that it
came from, and so should be copied if it needs to be retained. The
\fIsrcPtr\fR and \fIclientData\fR fields are ignored.
.SH "SEE ALSO"
diff --git a/doc/ParseCmd.3 b/doc/ParseCmd.3
index f3b3aeb..7090dd3 100644
--- a/doc/ParseCmd.3
+++ b/doc/ParseCmd.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_ParseCommand 3 8.3 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_ParseCommand, Tcl_ParseExpr, Tcl_ParseBraces, Tcl_ParseQuotedString, Tcl_ParseVarName, Tcl_ParseVar, Tcl_FreeParse, Tcl_EvalTokens, Tcl_EvalTokensStandard \- parse Tcl scripts and expressions
@@ -194,9 +194,9 @@ result; it can be retrieved using \fBTcl_GetObjResult\fR.
.PP
\fBTcl_EvalTokens\fR differs from \fBTcl_EvalTokensStandard\fR only in
the return convention used: it returns the result in a new Tcl_Obj.
-The reference count of the object returned as result has been
+The reference count of the value returned as result has been
incremented, so the caller must
-invoke \fBTcl_DecrRefCount\fR when it is finished with the object.
+invoke \fBTcl_DecrRefCount\fR when it is finished with the value.
If an error or other exception occurs while evaluating the tokens
(such as a reference to a non-existent variable) then the return value
is NULL and an error message is left in \fIinterp\fR's result. The use
diff --git a/doc/PkgRequire.3 b/doc/PkgRequire.3
index d54d7af..5c9fdca 100644
--- a/doc/PkgRequire.3
+++ b/doc/PkgRequire.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_PkgRequire 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_PkgRequire, Tcl_PkgRequireEx, Tcl_PkgRequireProc, Tcl_PkgPresent, Tcl_PkgPresentEx, Tcl_PkgProvide, Tcl_PkgProvideEx \- package version control
diff --git a/doc/Preserve.3 b/doc/Preserve.3
index 905a31d..970bded 100644
--- a/doc/Preserve.3
+++ b/doc/Preserve.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Preserve 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_Preserve, Tcl_Release, Tcl_EventuallyFree \- avoid freeing storage while it is being used
diff --git a/doc/PrintDbl.3 b/doc/PrintDbl.3
index 99b0113..730794f 100644
--- a/doc/PrintDbl.3
+++ b/doc/PrintDbl.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_PrintDouble 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_PrintDouble \- Convert floating value to string
diff --git a/doc/RecEvalObj.3 b/doc/RecEvalObj.3
index 2eed471..387cc44 100644
--- a/doc/RecEvalObj.3
+++ b/doc/RecEvalObj.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_RecordAndEvalObj 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_RecordAndEvalObj \- save command on history list before evaluating
@@ -20,7 +20,7 @@ int
.AP Tcl_Interp *interp in
Tcl interpreter in which to evaluate command.
.AP Tcl_Obj *cmdPtr in
-Points to a Tcl object containing a command (or sequence of commands)
+Points to a Tcl value containing a command (or sequence of commands)
to execute.
.AP int flags in
An OR'ed combination of flag bits. \fBTCL_NO_EVAL\fR means record the
@@ -35,7 +35,7 @@ on the history list and then execute it using \fBTcl_EvalObjEx\fR
(or \fBTcl_GlobalEvalObj\fR if the \fBTCL_EVAL_GLOBAL\fR bit is set
in \fIflags\fR).
It returns a completion code such as \fBTCL_OK\fR just like \fBTcl_EvalObjEx\fR,
-as well as a result object containing additional information
+as well as a result value containing additional information
(a result value or error message)
that can be retrieved using \fBTcl_GetObjResult\fR.
If you do not want the command recorded on the history list then
@@ -50,4 +50,4 @@ the command is recorded without being evaluated.
Tcl_EvalObjEx, Tcl_GetObjResult
.SH KEYWORDS
-command, event, execute, history, interpreter, object, record
+command, event, execute, history, interpreter, value, record
diff --git a/doc/RecordEval.3 b/doc/RecordEval.3
index a8f3087..e1625ff 100644
--- a/doc/RecordEval.3
+++ b/doc/RecordEval.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_RecordAndEval 3 7.4 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_RecordAndEval \- save command on history list before evaluating
@@ -44,9 +44,9 @@ If the \fIflags\fR argument contains the \fBTCL_NO_EVAL\fR bit then
the command is recorded without being evaluated.
.PP
Note that \fBTcl_RecordAndEval\fR has been largely replaced by the
-object-based procedure \fBTcl_RecordAndEvalObj\fR.
-That object-based procedure records and optionally executes
-a command held in a Tcl object instead of a string.
+value-based procedure \fBTcl_RecordAndEvalObj\fR.
+That value-based procedure records and optionally executes
+a command held in a Tcl value instead of a string.
.SH "SEE ALSO"
Tcl_RecordAndEvalObj
diff --git a/doc/RegConfig.3 b/doc/RegConfig.3
index 7c41350..d73e3d7 100644
--- a/doc/RegConfig.3
+++ b/doc/RegConfig.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_RegisterConfig 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -80,7 +80,7 @@ create a namespace having the provided \fIpkgName\fR, if not yet
existing.
.IP (2)
create the command \fBpkgconfig\fR in that namespace and link it to
-the provided information so that the keys from _configuration_ and
+the provided information so that the keys from \fIconfiguration\fR and
their associated values can be retrieved through calls to
\fBpkgconfig\fR.
.PP
diff --git a/doc/RegExp.3 b/doc/RegExp.3
index e10314a..63f650b 100644
--- a/doc/RegExp.3
+++ b/doc/RegExp.3
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_RegExpMatch 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_RegExpMatch, Tcl_RegExpCompile, Tcl_RegExpExec, Tcl_RegExpRange, Tcl_GetRegExpFromObj, Tcl_RegExpMatchObj, Tcl_RegExpExecObj, Tcl_RegExpGetInfo \- Pattern matching with regular expressions
@@ -45,12 +45,12 @@ void
Tcl interpreter to use for error reporting. The interpreter may be
NULL if no error reporting is desired.
.AP Tcl_Obj *textObj in/out
-Refers to the object from which to get the text to search. The
-internal representation of the object may be converted to a form that
+Refers to the value from which to get the text to search. The
+internal representation of the value may be converted to a form that
can be efficiently searched.
.AP Tcl_Obj *patObj in/out
-Refers to the object from which to get a regular expression. The
-compiled regular expression is cached in the object.
+Refers to the value from which to get a regular expression. The
+compiled regular expression is cached in the value.
.AP char *text in
Text to search for a match with a regular expression.
.AP "const char" *pattern in
@@ -110,7 +110,7 @@ If an error occurs in the matching process (e.g. \fIpattern\fR
is not a valid regular expression) then \fBTcl_RegExpMatch\fR
returns \-1 and leaves an error message in the interpreter result.
\fBTcl_RegExpMatchObj\fR is similar to \fBTcl_RegExpMatch\fR except it
-operates on the Tcl objects \fItextObj\fR and \fIpatObj\fR instead of
+operates on the Tcl values \fItextObj\fR and \fIpatObj\fR instead of
UTF strings.
\fBTcl_RegExpMatchObj\fR is generally more efficient than
\fBTcl_RegExpMatch\fR, so it is the preferred interface.
@@ -164,18 +164,18 @@ If there is no range corresponding to \fIindex\fR then NULL
is stored in \fI*startPtr\fR and \fI*endPtr\fR.
.PP
\fBTcl_GetRegExpFromObj\fR, \fBTcl_RegExpExecObj\fR, and
-\fBTcl_RegExpGetInfo\fR are object interfaces that provide the most
+\fBTcl_RegExpGetInfo\fR are value interfaces that provide the most
direct control of Henry Spencer's regular expression library. For
users that need to modify compilation and execution options directly,
it is recommended that you use these interfaces instead of calling the
internal regexp functions. These interfaces handle the details of UTF
to Unicode translations as well as providing improved performance
-through caching in the pattern and string objects.
+through caching in the pattern and string values.
.PP
\fBTcl_GetRegExpFromObj\fR attempts to return a compiled regular
-expression from the \fIpatObj\fR. If the object does not already
+expression from the \fIpatObj\fR. If the value does not already
contain a compiled regular expression it will attempt to create one
-from the string in the object and assign it to the internal
+from the string in the value and assign it to the internal
representation of the \fIpatObj\fR. The return value of this function
is of type \fBTcl_RegExp\fR. The return value is a token for this
compiled form, which can be used in subsequent calls to
diff --git a/doc/SaveResult.3 b/doc/SaveResult.3
index d6ea48d..557391d 100644
--- a/doc/SaveResult.3
+++ b/doc/SaveResult.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_SaveResult 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_SaveInterpState, Tcl_RestoreInterpState, Tcl_DiscardInterpState, Tcl_SaveResult, Tcl_RestoreResult, Tcl_DiscardResult \- save and restore an interpreter's state
@@ -96,12 +96,12 @@ or \fBTcl_DiscardInterpState\fR to avoid a memory leak. Once
the \fBTcl_InterpState\fR token is passed to one of them, the
token is no longer valid and should not be used anymore.
.PP
-\fBTcl_SaveResult\fR moves the string and object results
+\fBTcl_SaveResult\fR moves the string and value results
of \fIinterp\fR into the location specified by \fIstatePtr\fR.
\fBTcl_SaveResult\fR clears the result for \fIinterp\fR and
leaves the result in its normal empty initialized state.
.PP
-\fBTcl_RestoreResult\fR moves the string and object results from
+\fBTcl_RestoreResult\fR moves the string and value results from
\fIstatePtr\fR back into \fIinterp\fR. Any result or error that was
already in the interpreter will be cleared. The \fIstatePtr\fR is left
in an uninitialized state and cannot be used until another call to
diff --git a/doc/SetChanErr.3 b/doc/SetChanErr.3
index b6c1975..5bb86be 100644
--- a/doc/SetChanErr.3
+++ b/doc/SetChanErr.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_SetChannelError 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -51,16 +51,16 @@ allowed to use \fBTcl_SetChannelError\fR and \fBTcl_SetChannelErrorInterp\fR
to place arbitrary error messages in \fBbypass areas\fR defined for channels
and interpreters. And the generic I/O layer uses \fBTcl_GetChannelError\fR and
\fBTcl_GetChannelErrorInterp\fR to look for messages in the bypass areas and
-arrange for their return as errors. The posix error codes set by a driver are
+arrange for their return as errors. The POSIX error codes set by a driver are
used now if and only if no messages are present.
.PP
\fBTcl_SetChannelError\fR stores error information in the bypass area of the
-specified channel. The number of references to the \fBmsg\fR object goes up by
+specified channel. The number of references to the \fBmsg\fR value goes up by
one. Previously stored information will be discarded, by releasing the
reference held by the channel. The channel reference must not be NULL.
.PP
\fBTcl_SetChannelErrorInterp\fR stores error information in the bypass area of
-the specified interpreter. The number of references to the \fBmsg\fR object
+the specified interpreter. The number of references to the \fBmsg\fR value
goes up by one. Previously stored information will be discarded, by releasing
the reference held by the interpreter. The interpreter reference must not be
NULL.
@@ -72,7 +72,7 @@ NULL, until an intervening invocation of \fBTcl_SetChannelError\fR with a
non-NULL message. The \fImsgPtr\fR must not be NULL. The reference count of
the message is not touched. The reference previously held by the channel is
now held by the caller of the function and it is its responsibility to release
-that reference when it is done with the object.
+that reference when it is done with the value.
.PP
\fBTcl_GetChannelErrorInterp\fR places either the error message held in the
bypass area of the specified interpreter into \fImsgPtr\fR, or NULL; and
@@ -82,7 +82,7 @@ return NULL, until an intervening invocation of
not be NULL. The reference count of the message is not touched. The reference
previously held by the interpreter is now held by the caller of the function
and it is its responsibility to release that reference when it is done with
-the object.
+the value.
.PP
Which functions of a channel driver are allowed to use which bypass function
is listed below, as is which functions of the public channel API may leave a
diff --git a/doc/SetErrno.3 b/doc/SetErrno.3
index 1735952..21648b1 100644
--- a/doc/SetErrno.3
+++ b/doc/SetErrno.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_SetErrno 3 8.3 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_SetErrno, Tcl_GetErrno, Tcl_ErrnoId, Tcl_ErrnoMsg \- manipulate errno to store and retrieve error codes
diff --git a/doc/SetRecLmt.3 b/doc/SetRecLmt.3
index e38ba2f..904d4ab 100644
--- a/doc/SetRecLmt.3
+++ b/doc/SetRecLmt.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_SetRecursionLimit 3 7.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_SetRecursionLimit \- set maximum allowable nesting depth in interpreter
diff --git a/doc/SetResult.3 b/doc/SetResult.3
index c308193..1f86340 100644
--- a/doc/SetResult.3
+++ b/doc/SetResult.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_SetResult 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_SetObjResult, Tcl_GetObjResult, Tcl_SetResult, Tcl_GetStringResult, Tcl_AppendResult, Tcl_AppendResultVA, Tcl_AppendElement, Tcl_ResetResult, Tcl_TransferResult, Tcl_FreeResult \- manipulate Tcl result
@@ -42,7 +42,7 @@ const char *
.AP Tcl_Interp *interp out
Interpreter whose result is to be modified or read.
.AP Tcl_Obj *objPtr in
-Object value to become result for \fIinterp\fR.
+Tcl value to become result for \fIinterp\fR.
.AP char *result in
String value to become result for \fIinterp\fR or to be
appended to the existing result.
@@ -74,32 +74,32 @@ information as well.
.PP
The procedures described here are utilities for manipulating the
result value in a Tcl interpreter.
-The interpreter result may be either a Tcl object or a string.
+The interpreter result may be either a Tcl value or a string.
For example, \fBTcl_SetObjResult\fR and \fBTcl_SetResult\fR
-set the interpreter result to, respectively, an object and a string.
+set the interpreter result to, respectively, a value and a string.
Similarly, \fBTcl_GetObjResult\fR and \fBTcl_GetStringResult\fR
-return the interpreter result as an object and as a string.
-The procedures always keep the string and object forms
+return the interpreter result as a value and as a string.
+The procedures always keep the string and value forms
of the interpreter result consistent.
For example, if \fBTcl_SetObjResult\fR is called to set
-the result to an object,
+the result to a value,
then \fBTcl_GetStringResult\fR is called,
-it will return the object's string value.
+it will return the value's string representation.
.PP
\fBTcl_SetObjResult\fR
arranges for \fIobjPtr\fR to be the result for \fIinterp\fR,
replacing any existing result.
-The result is left pointing to the object
+The result is left pointing to the value
referenced by \fIobjPtr\fR.
\fIobjPtr\fR's reference count is incremented
since there is now a new reference to it from \fIinterp\fR.
-The reference count for any old result object
-is decremented and the old result object is freed if no
+The reference count for any old result value
+is decremented and the old result value is freed if no
references to it remain.
.PP
-\fBTcl_GetObjResult\fR returns the result for \fIinterp\fR as an object.
-The object's reference count is not incremented;
-if the caller needs to retain a long-term pointer to the object
+\fBTcl_GetObjResult\fR returns the result for \fIinterp\fR as a value.
+The value's reference count is not incremented;
+if the caller needs to retain a long-term pointer to the value
they should use \fBTcl_IncrRefCount\fR to increment its reference count
in order to keep it from being freed too early or accidentally changed.
.PP
@@ -115,19 +115,19 @@ and \fBTcl_SetResult\fR
re-initializes \fIinterp\fR's result to point to an empty string.
.PP
\fBTcl_GetStringResult\fR returns the result for \fIinterp\fR as a string.
-If the result was set to an object by a \fBTcl_SetObjResult\fR call,
-the object form will be converted to a string and returned.
-If the object's string representation contains null bytes,
+If the result was set to a value by a \fBTcl_SetObjResult\fR call,
+the value form will be converted to a string and returned.
+If the value's string representation contains null bytes,
this conversion will lose information.
For this reason, programmers are encouraged to
-write their code to use the new object API procedures
+write their code to use the new value API procedures
and to call \fBTcl_GetObjResult\fR instead.
.PP
\fBTcl_ResetResult\fR clears the result for \fIinterp\fR
and leaves the result in its normal empty initialized state.
-If the result is an object,
+If the result is a value,
its reference count is decremented and the result is left
-pointing to an unshared object representing an empty string.
+pointing to an unshared value representing an empty string.
If the result is a dynamically allocated string, its memory is free*d
and the result is left as a empty string.
\fBTcl_ResetResult\fR also clears the error state managed by
@@ -167,7 +167,7 @@ The source interpreter will have its result reset by this operation.
Use of the following procedures (is deprecated
since they manipulate the Tcl result as a string.
Procedures such as \fBTcl_SetObjResult\fR
-that manipulate the result as an object
+that manipulate the result as a value
can be significantly more efficient.
.PP
\fBTcl_AppendElement\fR is similar to \fBTcl_AppendResult\fR in
@@ -252,4 +252,4 @@ the value of \fIresult\fR passed to \fBTcl_SetResult\fR.
.SH "SEE ALSO"
Tcl_AddErrorInfo, Tcl_CreateObjCommand, Tcl_SetErrorCode, Tcl_Interp
.SH KEYWORDS
-append, command, element, list, object, result, return value, interpreter
+append, command, element, list, value, result, return value, interpreter
diff --git a/doc/SetVar.3 b/doc/SetVar.3
index ce47a73..1bef20b 100644
--- a/doc/SetVar.3
+++ b/doc/SetVar.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_SetVar 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_SetVar2Ex, Tcl_SetVar, Tcl_SetVar2, Tcl_ObjSetVar2, Tcl_GetVar2Ex, Tcl_GetVar, Tcl_GetVar2, Tcl_ObjGetVar2, Tcl_UnsetVar, Tcl_UnsetVar2 \- manipulate Tcl variables
@@ -57,7 +57,7 @@ to specify a variable in a particular namespace.
If non-NULL, gives name of element within array; in this
case \fIname1\fR must refer to an array variable.
.AP Tcl_Obj *newValuePtr in
-Points to a Tcl object containing the new value for the variable.
+Points to a Tcl value containing the new value for the variable.
.AP int flags in
OR-ed combination of bits providing additional information. See below
for valid values.
@@ -71,12 +71,12 @@ an array.
New value for variable, specified as a null-terminated string.
A copy of this value is stored in the variable.
.AP Tcl_Obj *part1Ptr in
-Points to a Tcl object containing the variable's name.
+Points to a Tcl value containing the variable's name.
The name may include a series of \fB::\fR namespace qualifiers
to specify a variable in a particular namespace.
May refer to a scalar variable or an element of an array variable.
.AP Tcl_Obj *part2Ptr in
-If non-NULL, points to an object containing the name of an element
+If non-NULL, points to a value containing the name of an element
within an array and \fIpart1Ptr\fR must refer to an array variable.
.BE
@@ -246,4 +246,4 @@ array is removed.
Tcl_GetObjResult, Tcl_GetStringResult, Tcl_TraceVar
.SH KEYWORDS
-array, get variable, interpreter, object, scalar, set, unset, variable
+array, get variable, interpreter, scalar, set, unset, value, variable
diff --git a/doc/Signal.3 b/doc/Signal.3
index 5b12654..70b9d91 100644
--- a/doc/Signal.3
+++ b/doc/Signal.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_SignalId 3 8.3 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_SignalId, Tcl_SignalMsg \- Convert signal codes
diff --git a/doc/Sleep.3 b/doc/Sleep.3
index 2423ba1..2d36697 100644
--- a/doc/Sleep.3
+++ b/doc/Sleep.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Sleep 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_Sleep \- delay execution for a given number of milliseconds
diff --git a/doc/SourceRCFile.3 b/doc/SourceRCFile.3
index eabc47c..0afb66b 100644
--- a/doc/SourceRCFile.3
+++ b/doc/SourceRCFile.3
@@ -2,8 +2,8 @@
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
-.so man.macros
.TH Tcl_SourceRCFile 3 8.3 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_SourceRCFile \- source the Tcl rc file
diff --git a/doc/SplitList.3 b/doc/SplitList.3
index 219dfc7..3439f2e 100644
--- a/doc/SplitList.3
+++ b/doc/SplitList.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_SplitList 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_SplitList, Tcl_Merge, Tcl_ScanElement, Tcl_ConvertElement, Tcl_ScanCountedElement, Tcl_ConvertCountedElement \- manipulate Tcl lists
diff --git a/doc/SplitPath.3 b/doc/SplitPath.3
index ec8f96b..19cee05 100644
--- a/doc/SplitPath.3
+++ b/doc/SplitPath.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_SplitPath 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_SplitPath, Tcl_JoinPath, Tcl_GetPathType \- manipulate platform-dependent file paths
@@ -43,7 +43,7 @@ A pointer to an initialized \fBTcl_DString\fR to which the result of
.SH DESCRIPTION
.PP
-These procedures have been superceded by the objectified procedures in
+These procedures have been superseded by the Tcl-value-aware procedures in
the \fBFileSystem\fR man page, which are more efficient.
.PP
These procedures may be used to disassemble and reassemble file
diff --git a/doc/StaticPkg.3 b/doc/StaticPkg.3
index fa6c32f..5700ea7 100644
--- a/doc/StaticPkg.3
+++ b/doc/StaticPkg.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_StaticPackage 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_StaticPackage \- make a statically linked package available via the 'load' command
diff --git a/doc/StdChannels.3 b/doc/StdChannels.3
index b5b020e..651ad7d 100644
--- a/doc/StdChannels.3
+++ b/doc/StdChannels.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH "Standard Channels" 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/StrMatch.3 b/doc/StrMatch.3
index 5adaf6e..f9c2be3 100644
--- a/doc/StrMatch.3
+++ b/doc/StrMatch.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_StringMatch 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_StringMatch, Tcl_StringCaseMatch \- test whether a string matches a pattern
diff --git a/doc/StringObj.3 b/doc/StringObj.3
index 371cdff..d81f23d 100644
--- a/doc/StringObj.3
+++ b/doc/StringObj.3
@@ -4,11 +4,11 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_StringObj 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
-Tcl_NewStringObj, Tcl_NewUnicodeObj, Tcl_SetStringObj, Tcl_SetUnicodeObj, Tcl_GetStringFromObj, Tcl_GetString, Tcl_GetUnicodeFromObj, Tcl_GetUnicode, Tcl_GetUniChar, Tcl_GetCharLength, Tcl_GetRange, Tcl_AppendToObj, Tcl_AppendUnicodeToObj, Tcl_AppendObjToObj, Tcl_AppendStringsToObj, Tcl_AppendStringsToObjVA, Tcl_AppendLimitedToObj, Tcl_Format, Tcl_AppendFormatToObj, Tcl_ObjPrintf, Tcl_AppendPrintfToObj, Tcl_SetObjLength, Tcl_AttemptSetObjLength, Tcl_ConcatObj \- manipulate Tcl objects as strings
+Tcl_NewStringObj, Tcl_NewUnicodeObj, Tcl_SetStringObj, Tcl_SetUnicodeObj, Tcl_GetStringFromObj, Tcl_GetString, Tcl_GetUnicodeFromObj, Tcl_GetUnicode, Tcl_GetUniChar, Tcl_GetCharLength, Tcl_GetRange, Tcl_AppendToObj, Tcl_AppendUnicodeToObj, Tcl_AppendObjToObj, Tcl_AppendStringsToObj, Tcl_AppendStringsToObjVA, Tcl_AppendLimitedToObj, Tcl_Format, Tcl_AppendFormatToObj, Tcl_ObjPrintf, Tcl_AppendPrintfToObj, Tcl_SetObjLength, Tcl_AttemptSetObjLength, Tcl_ConcatObj \- manipulate Tcl values as strings
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -88,7 +88,7 @@ Tcl_Obj *
.AS "const Tcl_UniChar" *appendObjPtr in/out
.AP "const char" *bytes in
Points to the first byte of an array of UTF-8-encoded bytes
-used to set or append to a string object.
+used to set or append to a string value.
This byte array may contain embedded null characters
unless \fInumChars\fR is negative. (Applications needing null bytes
should represent them as the two-byte sequence \fI\e700\e600\fR, use
@@ -96,36 +96,36 @@ should represent them as the two-byte sequence \fI\e700\e600\fR, use
the string is a collection of uninterpreted bytes.)
.AP int length in
The number of bytes to copy from \fIbytes\fR when
-initializing, setting, or appending to a string object.
+initializing, setting, or appending to a string value.
If negative, all bytes up to the first null are used.
.AP "const Tcl_UniChar" *unicode in
Points to the first byte of an array of Unicode characters
-used to set or append to a string object.
+used to set or append to a string value.
This byte array may contain embedded null characters
unless \fInumChars\fR is negative.
.AP int numChars in
The number of Unicode characters to copy from \fIunicode\fR when
-initializing, setting, or appending to a string object.
+initializing, setting, or appending to a string value.
If negative, all characters up to the first null character are used.
.AP int index in
The index of the Unicode character to return.
.AP int first in
The index of the first Unicode character in the Unicode range to be
-returned as a new object.
+returned as a new value.
.AP int last in
The index of the last Unicode character in the Unicode range to be
-returned as a new object.
+returned as a new value.
.AP Tcl_Obj *objPtr in/out
-Points to an object to manipulate.
+Points to a value to manipulate.
.AP Tcl_Obj *appendObjPtr in
-The object to append to \fIobjPtr\fR in \fBTcl_AppendObjToObj\fR.
+The value to append to \fIobjPtr\fR in \fBTcl_AppendObjToObj\fR.
.AP int *lengthPtr out
If non-NULL, the location where \fBTcl_GetStringFromObj\fR will store
-the length of an object's string representation.
+the length of a value's string representation.
.AP "const char" *string in
Null-terminated string value to append to \fIobjPtr\fR.
.AP va_list argList in
-An argument list which must have been initialised using
+An argument list which must have been initialized using
\fBva_start\fR, and cleared using \fBva_end\fR.
.AP int limit in
Maximum number of bytes to be appended.
@@ -139,46 +139,46 @@ Format control string including % conversion specifiers.
.AP int objc in
The number of elements to format or concatenate.
.AP Tcl_Obj *objv[] in
-The array of objects to format or concatenate.
+The array of values to format or concatenate.
.AP int newLength in
New length for the string value of \fIobjPtr\fR, not including the
final null character.
.BE
.SH DESCRIPTION
.PP
-The procedures described in this manual entry allow Tcl objects to
+The procedures described in this manual entry allow Tcl values to
be manipulated as string values. They use the internal representation
-of the object to store additional information to make the string
+of the value to store additional information to make the string
manipulations more efficient. In particular, they make a series of
append operations efficient by allocating extra storage space for the
string so that it does not have to be copied for each append.
Also, indexing and length computations are optimized because the
Unicode string representation is calculated and cached as needed.
When using the \fBTcl_Append*\fR family of functions where the
-interpreter's result is the object being appended to, it is important
+interpreter's result is the value being appended to, it is important
to call Tcl_ResetResult first to ensure you are not unintentionally
-appending to existing data in the result object.
+appending to existing data in the result value.
.PP
-\fBTcl_NewStringObj\fR and \fBTcl_SetStringObj\fR create a new object
-or modify an existing object to hold a copy of the string given by
+\fBTcl_NewStringObj\fR and \fBTcl_SetStringObj\fR create a new value
+or modify an existing value to hold a copy of the string given by
\fIbytes\fR and \fIlength\fR. \fBTcl_NewUnicodeObj\fR and
-\fBTcl_SetUnicodeObj\fR create a new object or modify an existing
-object to hold a copy of the Unicode string given by \fIunicode\fR and
+\fBTcl_SetUnicodeObj\fR create a new value or modify an existing
+value to hold a copy of the Unicode string given by \fIunicode\fR and
\fInumChars\fR. \fBTcl_NewStringObj\fR and \fBTcl_NewUnicodeObj\fR
-return a pointer to a newly created object with reference count zero.
-All four procedures set the object to hold a copy of the specified
+return a pointer to a newly created value with reference count zero.
+All four procedures set the value to hold a copy of the specified
string. \fBTcl_SetStringObj\fR and \fBTcl_SetUnicodeObj\fR free any
old string representation as well as any old internal representation
-of the object.
+of the value.
.PP
-\fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR return an object's
+\fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR return a value's
string representation. This is given by the returned byte pointer and
(for \fBTcl_GetStringFromObj\fR) length, which is stored in
-\fIlengthPtr\fR if it is non-NULL. If the object's UTF string
+\fIlengthPtr\fR if it is non-NULL. If the value's UTF string
representation is invalid (its byte pointer is NULL), the string
-representation is regenerated from the object's internal
+representation is regenerated from the value's internal
representation. The storage referenced by the returned byte pointer
-is owned by the object manager. It is passed back as a writable
+is owned by the value manager. It is passed back as a writable
pointer so that extension author creating their own \fBTcl_ObjType\fR
will be able to modify the string representation within the
\fBTcl_UpdateStringProc\fR of their \fBTcl_ObjType\fR. Except for that
@@ -194,45 +194,45 @@ The procedure \fBTcl_GetString\fR is used in the common case
where the caller does not need the length of the string
representation.
.PP
-\fBTcl_GetUnicodeFromObj\fR and \fBTcl_GetUnicode\fR return an object's
+\fBTcl_GetUnicodeFromObj\fR and \fBTcl_GetUnicode\fR return a value's
value as a Unicode string. This is given by the returned pointer and
(for \fBTcl_GetUnicodeFromObj\fR) length, which is stored in
\fIlengthPtr\fR if it is non-NULL. The storage referenced by the returned
-byte pointer is owned by the object manager and should not be modified by
+byte pointer is owned by the value manager and should not be modified by
the caller. The procedure \fBTcl_GetUnicode\fR is used in the common case
where the caller does not need the length of the unicode string
representation.
.PP
\fBTcl_GetUniChar\fR returns the \fIindex\fR'th character in the
-object's Unicode representation.
+value's Unicode representation.
.PP
-\fBTcl_GetRange\fR returns a newly created object comprised of the
+\fBTcl_GetRange\fR returns a newly created value comprised of the
characters between \fIfirst\fR and \fIlast\fR (inclusive) in the
-object's Unicode representation. If the object's Unicode
+value's Unicode representation. If the value's Unicode
representation is invalid, the Unicode representation is regenerated
-from the object's string representation.
+from the value's string representation.
.PP
\fBTcl_GetCharLength\fR returns the number of characters (as opposed
-to bytes) in the string object.
+to bytes) in the string value.
.PP
\fBTcl_AppendToObj\fR appends the data given by \fIbytes\fR and
-\fIlength\fR to the string representation of the object specified by
-\fIobjPtr\fR. If the object has an invalid string representation,
+\fIlength\fR to the string representation of the value specified by
+\fIobjPtr\fR. If the value has an invalid string representation,
then an attempt is made to convert \fIbytes\fR is to the Unicode
format. If the conversion is successful, then the converted form of
-\fIbytes\fR is appended to the object's Unicode representation.
-Otherwise, the object's Unicode representation is invalidated and
+\fIbytes\fR is appended to the value's Unicode representation.
+Otherwise, the value's Unicode representation is invalidated and
converted to the UTF format, and \fIbytes\fR is appended to the
-object's new string representation.
+value's new string representation.
.PP
\fBTcl_AppendUnicodeToObj\fR appends the Unicode string given by
-\fIunicode\fR and \fInumChars\fR to the object specified by
-\fIobjPtr\fR. If the object has an invalid Unicode representation,
+\fIunicode\fR and \fInumChars\fR to the value specified by
+\fIobjPtr\fR. If the value has an invalid Unicode representation,
then \fIunicode\fR is converted to the UTF format and appended to the
-object's string representation. Appends are optimized to handle
-repeated appends relatively efficiently (it overallocates the string
+value's string representation. Appends are optimized to handle
+repeated appends relatively efficiently (it over-allocates the string
or Unicode space to avoid repeated reallocations and copies of
-object's string value).
+value's string value).
.PP
\fBTcl_AppendObjToObj\fR is similar to \fBTcl_AppendToObj\fR, but it
appends the string or Unicode value (whichever exists and is best
@@ -345,14 +345,14 @@ functionality is needed.
.PP
The \fBTcl_SetObjLength\fR procedure changes the length of the
string value of its \fIobjPtr\fR argument. If the \fInewLength\fR
-argument is greater than the space allocated for the object's
+argument is greater than the space allocated for the value's
string, then the string space is reallocated and the old value
is copied to the new space; the bytes between the old length of
the string and the new length may have arbitrary values.
If the \fInewLength\fR argument is less than the current length
-of the object's string, with \fIobjPtr->length\fR is reduced without
+of the value's string, with \fIobjPtr->length\fR is reduced without
reallocating the string space; the original allocated size for the
-string is recorded in the object, so that the string length can be
+string is recorded in the value, so that the string length can be
enlarged in a subsequent call to \fBTcl_SetObjLength\fR without
reallocating storage. In all cases \fBTcl_SetObjLength\fR leaves
a null character at \fIobjPtr->bytes[newLength]\fR.
@@ -361,24 +361,24 @@ a null character at \fIobjPtr->bytes[newLength]\fR.
\fBTcl_SetObjLength\fR except that if sufficient memory to satisfy the
request cannot be allocated, it does not cause the Tcl interpreter to
\fBpanic\fR. Thus, if \fInewLength\fR is greater than the space
-allocated for the object's string, and there is not enough memory
+allocated for the value's string, and there is not enough memory
available to satisfy the request, \fBTcl_AttemptSetObjLength\fR will take
no action and return 0 to indicate failure. If there is enough memory
to satisfy the request, \fBTcl_AttemptSetObjLength\fR behaves just like
\fBTcl_SetObjLength\fR and returns 1 to indicate success.
.PP
-The \fBTcl_ConcatObj\fR function returns a new string object whose
+The \fBTcl_ConcatObj\fR function returns a new string value whose
value is the space-separated concatenation of the string
-representations of all of the objects in the \fIobjv\fR
+representations of all of the values in the \fIobjv\fR
array. \fBTcl_ConcatObj\fR eliminates leading and trailing white space
as it copies the string representations of the \fIobjv\fR array to the
result. If an element of the \fIobjv\fR array consists of nothing but
-white space, then that object is ignored entirely. This white-space
+white space, then that value is ignored entirely. This white-space
removal was added to make the output of the \fBconcat\fR command
cleaner-looking. \fBTcl_ConcatObj\fR returns a pointer to a
-newly-created object whose ref count is zero.
+newly-created value whose ref count is zero.
.SH "SEE ALSO"
Tcl_NewObj(3), Tcl_IncrRefCount(3), Tcl_DecrRefCount(3), format(n), sprintf(3)
.SH KEYWORDS
-append, internal representation, object, object type, string object,
+append, internal representation, value, value type, string value,
string type, string representation, concat, concatenate, unicode
diff --git a/doc/SubstObj.3 b/doc/SubstObj.3
index 786b595..f582c5a 100644
--- a/doc/SubstObj.3
+++ b/doc/SubstObj.3
@@ -4,11 +4,11 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_SubstObj 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
-Tcl_SubstObj \- perform substitutions on Tcl objects
+Tcl_SubstObj \- perform substitutions on Tcl values
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -22,7 +22,7 @@ Interpreter in which to execute Tcl scripts and lookup variables. If
an error occurs, the interpreter's result is modified to hold an error
message.
.AP Tcl_Obj *objPtr in
-A Tcl object containing the string to perform substitutions on.
+A Tcl value containing the string to perform substitutions on.
.AP int flags in
ORed combination of flag bits that specify which substitutions to
perform. The flags \fBTCL_SUBST_COMMANDS\fR,
@@ -36,7 +36,7 @@ The \fBTcl_SubstObj\fR function is used to perform substitutions on
strings in the fashion of the \fBsubst\fR command. It gets the value
of the string contained in \fIobjPtr\fR and scans it, copying
characters and performing the chosen substitutions as it goes to an
-output object which is returned as the result of the function. In the
+output value which is returned as the result of the function. In the
event of an error occurring during the execution of a command or
variable substitution, the function returns NULL and an error message
is left in \fIinterp\fR's result.
diff --git a/doc/TCL_MEM_DEBUG.3 b/doc/TCL_MEM_DEBUG.3
index 05d4564..e3a6809 100644
--- a/doc/TCL_MEM_DEBUG.3
+++ b/doc/TCL_MEM_DEBUG.3
@@ -3,8 +3,8 @@
'\" Copyright (c) 2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
-.so man.macros
.TH TCL_MEM_DEBUG 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
TCL_MEM_DEBUG \- Compile-time flag to enable Tcl memory debugging
@@ -26,7 +26,7 @@ version of \fBTcl_InitMemory\fR to add the \fBmemory\fR command to Tcl.
\fBTCL_MEM_DEBUG\fR must be either left defined for all modules or undefined
for all modules that are going to be linked together. If they are not, link
errors will occur, with either \fBTcl_DbCkfree\fR and \fBTcl_DbCkalloc\fR or
-\fBTcl_Ckalloc\fR and \fBTcl_Ckfree\fR being undefined.
+\fBTcl_Alloc\fR and \fBTcl_Free\fR being undefined.
.PP
Once memory debugging support has been compiled into Tcl, the C
functions \fBTcl_ValidateAllMemory\fR, and \fBTcl_DumpActiveMemory\fR,
diff --git a/doc/Tcl.n b/doc/Tcl.n
index f56c82c..c7fa9f6 100644
--- a/doc/Tcl.n
+++ b/doc/Tcl.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
+.TH Tcl n "8.6" Tcl "Tcl Built-In Commands"
.so man.macros
-.TH Tcl n "8.5" Tcl "Tcl Built-In Commands"
.BS
.SH NAME
Tcl \- Tool Command Language
@@ -28,7 +28,7 @@ First, the Tcl interpreter breaks the command into \fIwords\fR
and performs substitutions as described below.
These substitutions are performed in the same way for all
commands.
-The first word is used to locate a command procedure to
+Secondly, the first word is used to locate a command procedure to
carry out the command, then all of the words of the command are
passed to the command procedure.
The command procedure is free to interpret each of its words
@@ -108,8 +108,8 @@ Variable substitution may take any of the following forms:
\fIName\fR is the name of a scalar variable; the name is a sequence
of one or more characters that are a letter, digit, underscore,
or namespace separators (two or more colons).
-Letters and digits are \fIonly\fR the standard ASCII ones (\fB0\fR\-\fB9\fR,
-\fBA\fR\-\fBZ\fR and \fBa\fR\-\fBz\fR).
+Letters and digits are \fIonly\fR the standard ASCII ones (\fB0\fR\(en\fB9\fR,
+\fBA\fR\(en\fBZ\fR and \fBa\fR\(en\fBz\fR).
.TP 15
\fB$\fIname\fB(\fIindex\fB)\fR
.
@@ -117,8 +117,8 @@ Letters and digits are \fIonly\fR the standard ASCII ones (\fB0\fR\-\fB9\fR,
the name of an element within that array.
\fIName\fR must contain only letters, digits, underscores, and
namespace separators, and may be an empty string.
-Letters and digits are \fIonly\fR the standard ASCII ones (\fB0\fR\-\fB9\fR,
-\fBA\fR\-\fBZ\fR and \fBa\fR\-\fBz\fR).
+Letters and digits are \fIonly\fR the standard ASCII ones (\fB0\fR\(en\fB9\fR,
+\fBA\fR\(en\fBZ\fR and \fBa\fR\(en\fBz\fR).
Command substitutions, variable substitutions, and backslash
substitutions are performed on the characters of \fIindex\fR.
.TP 15
@@ -158,25 +158,25 @@ handled specially, along with the value that replaces each sequence.
.RS
.TP 7
\e\fBa\fR
-Audible alert (bell) (0x7).
+Audible alert (bell) (Unicode U+000007).
.TP 7
\e\fBb\fR
-Backspace (0x8).
+Backspace (Unicode U+000008).
.TP 7
\e\fBf\fR
-Form feed (0xc).
+Form feed (Unicode U+00000C).
.TP 7
\e\fBn\fR
-Newline (0xa).
+Newline (Unicode U+00000A).
.TP 7
\e\fBr\fR
-Carriage-return (0xd).
+Carriage-return (Unicode U+00000D).
.TP 7
\e\fBt\fR
-Tab (0x9).
+Tab (Unicode U+000009).
.TP 7
\e\fBv\fR
-Vertical tab (0xb).
+Vertical tab (Unicode U+00000B).
.TP 7
\e\fB<newline>\fIwhiteSpace\fR
.
@@ -193,23 +193,38 @@ Backslash
.TP 7
\e\fIooo\fR
.
-The digits \fIooo\fR (one, two, or three of them) give an eight-bit octal
-value for the Unicode character that will be inserted. The upper bits of the
-Unicode character will be 0.
+The digits \fIooo\fR (one, two, or three of them) give a eight-bit octal
+value for the Unicode character that will be inserted, in the range
+\fI000\fR\(en\fI377\fR (i.e., the range U+000000\(enU+0000FF).
+The parser will stop just before this range overflows, or when
+the maximum of three digits is reached. The upper bits of the Unicode
+character will be 0.
.TP 7
\e\fBx\fIhh\fR
.
-The hexadecimal digits \fIhh\fR give an eight-bit hexadecimal value for the
-Unicode character that will be inserted. Any number of hexadecimal digits
-may be present; however, all but the last two are ignored (the result is
-always a one-byte quantity). The upper bits of the Unicode character will
-be 0.
+The hexadecimal digits \fIhh\fR (one or two of them) give an eight-bit
+hexadecimal value for the Unicode character that will be inserted. The upper
+bits of the Unicode character will be 0 (i.e., the character will be in the
+range U+000000\(enU+0000FF).
.TP 7
\e\fBu\fIhhhh\fR
.
The hexadecimal digits \fIhhhh\fR (one, two, three, or four of them) give a
sixteen-bit hexadecimal value for the Unicode character that will be
-inserted.
+inserted. The upper bits of the Unicode character will be 0 (i.e., the
+character will be in the range U+000000\(enU+00FFFF).
+.TP 7
+\e\fBU\fIhhhhhhhh\fR
+.
+The hexadecimal digits \fIhhhhhhhh\fR (one up to eight of them) give a
+twenty-one-bit hexadecimal value for the Unicode character that will be
+inserted, in the range U+000000\(enU+10FFFF. The parser will stop just
+before this range overflows, or when the maximum of eight digits
+is reached. The upper bits of the Unicode character will be 0.
+.RS
+.PP
+The range U+010000\(enU+10FFFD is reserved for the future.
+.RE
.PP
Backslash substitution is not performed on words enclosed in braces,
except for backslash-newline as described above.
diff --git a/doc/TclZlib.3 b/doc/TclZlib.3
index 1b5e892..c6a6417 100644
--- a/doc/TclZlib.3
+++ b/doc/TclZlib.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH TclZlib 3 8.6 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -49,9 +49,11 @@ int
.sp
int
\fBTcl_ZlibStreamGet\fR(\fIzshandle, dataObj, count\fR)
+.sp
+\fBTcl_ZlibStreamSetCompressionDictionary\fR(\fIzshandle, compDict\fR)
.fi
.SH ARGUMENTS
-.AS Tcl_ZlibStream *zshandlePtr out
+.AS Tcl_ZlibStream zshandle in
.AP Tcl_Interp *interp in
The interpreter to store resulting compressed or uncompressed data in. Also
where any error messages are written. For \fBTcl_ZlibStreamInit\fR, this can
@@ -64,7 +66,7 @@ addition, for decompression only, \fBTCL_ZLIB_FORMAT_AUTO\fR may also be
chosen which can automatically detect whether the compressed data was in zlib
or gzip format.
.AP Tcl_Obj *dataObj in/out
-A byte-array object containing the data to be compressed or decompressed, or
+A byte-array value containing the data to be compressed or decompressed, or
to which the data extracted from the stream is appended when passed to
\fBTcl_ZlibStreamGet\fR.
.AP int level in
@@ -108,6 +110,13 @@ trailer demanded by the format is written.
.AP int count in
The maximum number of bytes to get from the stream, or -1 to get all remaining
bytes from the stream's buffers.
+.AP Tcl_Obj *compDict in
+A byte array value that is the compression dictionary to use with the stream.
+Note that this is \fInot a Tcl dictionary\fR, and it is recommended that this
+only ever be used with streams that were created with their \fIformat\fR set
+to \fBTCL_ZLIB_FORMAT_ZLIB\fR because the other formats have no mechanism to
+indicate whether a compression dictionary was present other than to fail on
+decompression.
.BE
.SH DESCRIPTION
These functions form the interface from the Tcl library to the Zlib
@@ -122,7 +131,7 @@ the dictionary is only used when the \fIformat\fR parameter is
\fBTCL_ZLIB_FORMAT_GZIP\fR or \fBTCL_ZLIB_FORMAT_AUTO\fR. For details of the
contents of the dictionary, see the \fBGZIP OPTIONS DICTIONARY\fR section
below. Upon success, both functions leave the resulting compressed or
-decompressed data in a byte-array object that is the Tcl interpreter's result;
+decompressed data in a byte-array value that is the Tcl interpreter's result;
the returned value is a standard Tcl result code.
.PP
\fBTcl_ZlibAdler32\fR and \fBTcl_ZlibCRC32\fR compute checksums on arrays of
@@ -154,7 +163,7 @@ the \fBGZIP OPTIONS DICTIONARY\fR section below) can be given via the
headers, and on decompression allows discovery of the existing headers. Note
that the dictionary will be written to on decompression once sufficient data
has been read to have a complete header. This means that the dictionary must
-be an unshared object in that case; a blank object created with
+be an unshared value in that case; a blank value created with
\fBTcl_NewObj\fR is suggested.
.PP
Once a stream has been constructed, \fBTcl_ZlibStreamPut\fR is used to add
@@ -162,8 +171,8 @@ data to the stream and \fBTcl_ZlibStreamGet\fR is used to retrieve data from
the stream after processing. Both return normal Tcl result codes and leave an
error message in the result of the interpreter that the stream is registered
with in the error case (if such a registration has been performed). With
-\fBTcl_ZlibStreamPut\fR, the data buffer object passed to it should not be
-modified afterwards. With \fBTcl_ZlibStreamGet\fR, the data buffer object
+\fBTcl_ZlibStreamPut\fR, the data buffer value passed to it should not be
+modified afterwards. With \fBTcl_ZlibStreamGet\fR, the data buffer value
passed to it will have the data bytes appended to it. Internally to the
stream, data is kept compressed so as to minimize the cost of buffer space.
.PP
@@ -172,6 +181,25 @@ uncompressed data according to the format, and \fBTcl_ZlibStreamEof\fR returns
a boolean value indicating whether the end of the uncompressed data has been
reached.
.PP
+\fBTcl_ZlibStreamSetCompressionDictionary\fR is used to control the
+compression dictionary used with the stream, a compression dictionary being an
+array of bytes (such as might be created with \fBTcl_NewByteArrayObj\fR) that
+is used to initialize the compression engine rather than leaving it to create
+it on the fly from the data being compressed. Setting a compression dictionary
+allows for more efficient compression in the case where the start of the data
+is highly regular, but it does require both the compressor and the
+decompressor to agreee on the value to use. Compression dictionaries are only
+fully supported for zlib-format data; on compression, they must be set before
+any data is sent in with \fBTcl_ZlibStreamPut\fR, and on decompression they
+should be set when \fBTcl_ZlibStreamGet\fR produces an \fBerror\fR with its
+\fB\-errorcode\fR set to
+.QW "\fBZLIB NEED_DICT\fI code\fR" ;
+the \fIcode\fR will be the Adler-32 checksum (see \fBTcl_ZlibAdler32\fR) of
+the compression dictionary sought. (Note that this is only true for
+zlib-format streams; gzip streams ignore compression dictionaries as the
+format specification doesn't permit them, and raw streams just produce a data
+error if the compression dictionary is missing or incorrect.)
+.PP
If you wish to clear a stream and reuse it for a new compression or
decompression action, \fBTcl_ZlibStreamReset\fR will do this and return a
normal Tcl result code to indicate whether it was successful; if the stream is
@@ -187,9 +215,9 @@ and \fBTcl_ZlibStreamInit\fR is used to pass a dictionary of options about
that is used to describe the gzip header in the compressed data. When creating
compressed data, the dictionary is read and when unpacking compressed data the
dictionary is written (in which case the \fIdictObj\fR parameter must refer to
-an unshared dictionary object).
+an unshared dictionary value).
.PP
-The following fields in the dictionary object are understood. All other fields
+The following fields in the dictionary value are understood. All other fields
are ignored. No field is required when creating a gzip-format stream.
.TP
\fBcomment\fR
diff --git a/doc/Tcl_Main.3 b/doc/Tcl_Main.3
index 0a69835..5fd5002 100644
--- a/doc/Tcl_Main.3
+++ b/doc/Tcl_Main.3
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_Main 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_Main, Tcl_SetStartupScript, Tcl_GetStartupScript, Tcl_SetMainLoop \- main program, startup script, and event loop definition for Tcl-based applications
diff --git a/doc/Thread.3 b/doc/Thread.3
index 4b5e7c3..ac5f2ba 100644
--- a/doc/Thread.3
+++ b/doc/Thread.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Threads 3 "8.1" Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_ConditionNotify, Tcl_ConditionWait, Tcl_ConditionFinalize, Tcl_GetThreadData, Tcl_MutexLock, Tcl_MutexUnlock, Tcl_MutexFinalize, Tcl_CreateThread, Tcl_JoinThread \- Tcl thread support
@@ -70,7 +70,7 @@ Arbitrary information. Passed as sole argument to the \fIproc\fR.
.AP int stackSize in
The size of the stack given to the new thread.
.AP int flags in
-Bitmask containing flags allowing the caller to modify behaviour of
+Bitmask containing flags allowing the caller to modify behavior of
the new thread.
.AP int *result out
The referred storage is used to place the exit code of the thread
@@ -91,15 +91,15 @@ and use multiple interpreters.)
.SH DESCRIPTION
Tcl provides \fBTcl_CreateThread\fR for creating threads. The
caller can determine the size of the stack given to the new thread and
-modify the behaviour through the supplied \fIflags\fR. The value
+modify the behavior through the supplied \fIflags\fR. The value
\fBTCL_THREAD_STACK_DEFAULT\fR for the \fIstackSize\fR indicates that
the default size as specified by the operating system is to be used
for the new thread. As for the flags, currently only the values
\fBTCL_THREAD_NOFLAGS\fR and \fBTCL_THREAD_JOINABLE\fR are defined. The
-first of them invokes the default behaviour with no
-specialties. Using the second value marks the new thread as
-\fIjoinable\fR. This means that another thread can wait for the such
-marked thread to exit and join it.
+first of them invokes the default behavior with no special settings.
+Using the second value marks the new thread as \fIjoinable\fR. This
+means that another thread can wait for the such marked thread to exit
+and join it.
.PP
Restrictions: On some UNIX systems the pthread-library does not
contain the functionality to specify the stack size of a thread. The
diff --git a/doc/ToUpper.3 b/doc/ToUpper.3
index d6b3006..587e76b 100644
--- a/doc/ToUpper.3
+++ b/doc/ToUpper.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_UtfToUpper 3 "8.1" Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_UniCharToUpper, Tcl_UniCharToLower, Tcl_UniCharToTitle, Tcl_UtfToUpper, Tcl_UtfToLower, Tcl_UtfToTitle \- routines for manipulating the case of Unicode characters and UTF-8 strings
diff --git a/doc/TraceCmd.3 b/doc/TraceCmd.3
index 5cc1337..1244576 100644
--- a/doc/TraceCmd.3
+++ b/doc/TraceCmd.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_TraceCommand 3 7.4 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_CommandTraceInfo, Tcl_TraceCommand, Tcl_UntraceCommand \- monitor renames and deletes of a command
diff --git a/doc/TraceVar.3 b/doc/TraceVar.3
index 6201a4f..97d035b 100644
--- a/doc/TraceVar.3
+++ b/doc/TraceVar.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_TraceVar 3 7.4 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_TraceVar, Tcl_TraceVar2, Tcl_UntraceVar, Tcl_UntraceVar2, Tcl_VarTraceInfo, Tcl_VarTraceInfo2 \- monitor accesses to a variable
diff --git a/doc/Translate.3 b/doc/Translate.3
index 55233c3..0f223e4 100644
--- a/doc/Translate.3
+++ b/doc/Translate.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_TranslateFileName 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_TranslateFileName \- convert file name to native form and replace tilde with home directory
diff --git a/doc/UniCharIsAlpha.3 b/doc/UniCharIsAlpha.3
index 6029b2d..ea6fc5b 100644
--- a/doc/UniCharIsAlpha.3
+++ b/doc/UniCharIsAlpha.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_UniCharIsAlpha 3 "8.1" Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_UniCharIsAlnum, Tcl_UniCharIsAlpha, Tcl_UniCharIsControl, Tcl_UniCharIsDigit, Tcl_UniCharIsGraph, Tcl_UniCharIsLower, Tcl_UniCharIsPrint, Tcl_UniCharIsPunct, Tcl_UniCharIsSpace, Tcl_UniCharIsUpper, Tcl_UniCharIsWordChar \- routines for classification of Tcl_UniChar characters
diff --git a/doc/UpVar.3 b/doc/UpVar.3
index f1e6fe4..8e7ba08 100644
--- a/doc/UpVar.3
+++ b/doc/UpVar.3
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_UpVar 3 7.4 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_UpVar, Tcl_UpVar2 \- link one variable to another
diff --git a/doc/Utf.3 b/doc/Utf.3
index 55906e7..3b2ef91 100644
--- a/doc/Utf.3
+++ b/doc/Utf.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Utf 3 "8.1" Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_UniChar, Tcl_UniCharCaseMatch, Tcl_UniCharNcasecmp, Tcl_UniCharToUtf, Tcl_UtfToUniChar, Tcl_UniCharToUtfDString, Tcl_UtfToUniCharDString, Tcl_UniCharLen, Tcl_UniCharNcmp, Tcl_UtfCharComplete, Tcl_NumUtfChars, Tcl_UtfFindFirst, Tcl_UtfFindLast, Tcl_UtfNext, Tcl_UtfPrev, Tcl_UniCharAtIndex, Tcl_UtfAtIndex, Tcl_UtfBackslash \- routines for manipulating UTF-8 strings
diff --git a/doc/WrongNumArgs.3 b/doc/WrongNumArgs.3
index a2908e9..33807d5 100644
--- a/doc/WrongNumArgs.3
+++ b/doc/WrongNumArgs.3
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH Tcl_WrongNumArgs 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
.BS
.SH NAME
Tcl_WrongNumArgs \- generate standard error message for wrong number of arguments
@@ -18,7 +18,7 @@ Tcl_WrongNumArgs \- generate standard error message for wrong number of argument
.AS "Tcl_Obj *const" *message
.AP Tcl_Interp interp in
Interpreter in which error will be reported: error message gets stored
-in its result object.
+in its result value.
.AP int objc in
Number of leading arguments from \fIobjv\fR to include in error
message.
@@ -34,13 +34,13 @@ of the command. This argument may be NULL.
\fBTcl_WrongNumArgs\fR is a utility procedure that is invoked by
command procedures when they discover that they have received the
wrong number of arguments. \fBTcl_WrongNumArgs\fR generates a
-standard error message and stores it in the result object of
+standard error message and stores it in the result value of
\fIinterp\fR. The message includes the \fIobjc\fR initial
elements of \fIobjv\fR plus \fImessage\fR. For example, if
\fIobjv\fR consists of the values \fBfoo\fR and \fBbar\fR,
\fIobjc\fR is 1, and \fImessage\fR is
.QW "\fBfileName count\fR"
-then \fIinterp\fR's result object will be set to the following
+then \fIinterp\fR's result value will be set to the following
string:
.PP
.CS
@@ -57,17 +57,17 @@ wrong # args: should be "foo bar fileName count"
\fBstring\fR and the Tk widget commands, which use the first argument
as a subcommand.
.PP
-Some of the objects in the \fIobjv\fR array may be abbreviations for
+Some of the values in the \fIobjv\fR array may be abbreviations for
a subcommand. The command
-\fBTcl_GetIndexFromObj\fR will convert the abbreviated string object
+\fBTcl_GetIndexFromObj\fR will convert the abbreviated string value
into an \fIindexObject\fR. If an error occurs in the parsing of the
subcommand we would like to use the full subcommand name rather than
the abbreviation. If the \fBTcl_WrongNumArgs\fR command finds any
\fIindexObjects\fR in the \fIobjv\fR array it will use the full subcommand
name in the error message instead of the abbreviated name that was
originally passed in. Using the above example, let us assume that
-\fIbar\fR is actually an abbreviation for \fIbarfly\fR and the object
-is now an indexObject because it was passed to
+\fIbar\fR is actually an abbreviation for \fIbarfly\fR and the value
+is now an \fIindexObject\fR because it was passed to
\fBTcl_GetIndexFromObj\fR. In this case the error message would be:
.PP
.CS
diff --git a/doc/after.n b/doc/after.n
index d6181c6..e61bb88 100644
--- a/doc/after.n
+++ b/doc/after.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH after n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/append.n b/doc/append.n
index 034068d..4b3cfd0 100644
--- a/doc/append.n
+++ b/doc/append.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH append n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/apply.n b/doc/apply.n
index 9d373e1..4b730ff 100644
--- a/doc/apply.n
+++ b/doc/apply.n
@@ -2,8 +2,8 @@
'\" Copyright (c) 2006 Miguel Sofer
'\" Copyright (c) 2006 Donal K. Fellows
'\"
-.so man.macros
.TH apply n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/array.n b/doc/array.n
index 47f9624..e253a37 100644
--- a/doc/array.n
+++ b/doc/array.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH array n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/bgerror.n b/doc/bgerror.n
index ac53eca..ea8fe2a 100644
--- a/doc/bgerror.n
+++ b/doc/bgerror.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH bgerror n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -85,6 +85,9 @@ proc bgerror {message} {
}
.CE
.SH "SEE ALSO"
-after(n), interp(n), tclvars(n)
+after(n), errorCode(n), errorInfo(n), interp(n)
.SH KEYWORDS
background error, reporting
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/binary.n b/doc/binary.n
index 8133829..014704d 100644
--- a/doc/binary.n
+++ b/doc/binary.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH binary n 8.0 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -36,6 +36,13 @@ The \fBbinary encode\fR and \fBbinary decode\fR subcommands convert
binary data to or from string encodings such as base64 (used in MIME
messages for example).
.VE 8.6
+.PP
+Note that other operations on binary data, such as taking a subsequence of it,
+getting its length, or reinterpreting it as a string in some encoding, are
+done by other Tcl commands (respectively \fBstring range\fR,
+\fBstring length\fR and \fBencoding convertfrom\fR in the example cases). A
+binary string in Tcl is merely one where all the characters it contains are in
+the range \eu0000\-\eu00FF.
.SH "BINARY ENCODE AND DECODE"
.VS 8.6
.PP
@@ -92,16 +99,17 @@ Instructs the decoder to throw an error if it encounters whitespace characters.
.
The \fBuuencode\fR binary encoding used to be common for transfer of data
between Unix systems and on USENET, but is less common these days, having been
-largely superceded by the \fBbase64\fR binary encoding.
+largely superseded by the \fBbase64\fR binary encoding.
.RS
.PP
-During encoding, the following options are supported:
-'\" This is wrong! The uuencode format had more complexity than this!
+During encoding, the following options are supported (though changing them may
+produce files that other implementations of decoders cannot process):
.TP
\fB\-maxlen \fIlength\fR
.
Indicates that the output should be split into lines of no more than
-\fIlength\fR characters. By default, lines are not split.
+\fIlength\fR characters. By default, lines are split every 61 characters, and
+this must be in the range 3 to 85 due to limitations in the encoding.
.TP
\fB\-wrapchar \fIcharacter\fR
.
@@ -114,7 +122,11 @@ During decoding, the following options are supported:
.TP
\fB\-strict\fR
.
-Instructs the decoder to throw an error if it encounters whitespace characters. Otherwise it ignores them.
+Instructs the decoder to throw an error if it encounters unexpected whitespace
+characters. Otherwise it ignores them.
+.PP
+Note that neither the encoder nor the decoder handle the header and footer of
+the uuencode format.
.RE
.VE 8.6
.SH "BINARY FORMAT"
@@ -135,7 +147,7 @@ is a non-negative decimal integer or \fB*\fR, which normally indicates
that all of the items in the value are to be used. If the number of
arguments does not match the number of fields in the format string
that consume arguments, then an error is generated. The flag character
-is ignored for for \fBbinary format\fR.
+is ignored for \fBbinary format\fR.
.PP
Here is a small example to clarify the relation between the field
specifiers and the arguments:
@@ -855,6 +867,7 @@ architectures, use their textual representation (as produced by
.PP
This is a procedure to write a Tcl string to a binary-encoded channel as
UTF-8 data preceded by a length word:
+.PP
.CS
proc \fIwriteString\fR {channel string} {
set data [encoding convertto utf-8 $string]
@@ -865,6 +878,7 @@ proc \fIwriteString\fR {channel string} {
.PP
This procedure reads a string from a channel that was written by the
previously presented \fIwriteString\fR procedure:
+.PP
.CS
proc \fIreadString\fR {channel} {
if {![\fBbinary scan\fR [read $channel 4] I length]} {
@@ -877,6 +891,7 @@ proc \fIreadString\fR {channel} {
.PP
This converts the contents of a file (named in the variable \fIfilename\fR) to
base64 and prints them:
+.PP
.CS
set f [open $filename rb]
set data [read $f]
@@ -884,9 +899,10 @@ close $f
puts [\fBbinary encode\fR base64 \-maxlen 64 $data]
.CE
.SH "SEE ALSO"
-format(n), scan(n), tclvars(n)
+encoding(n), format(n), scan(n), string(n), tcl_platform(n)
.SH KEYWORDS
binary, format, scan
'\" Local Variables:
'\" mode: nroff
+'\" fill-column: 78
'\" End:
diff --git a/doc/break.n b/doc/break.n
index cef37c6..3e4ce5f 100644
--- a/doc/break.n
+++ b/doc/break.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH break n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/case.n b/doc/case.n
index 0155a61..54d5bf4 100644
--- a/doc/case.n
+++ b/doc/case.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH case n 7.0 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/catch.n b/doc/catch.n
index 1da163d..94fa5dd 100644
--- a/doc/catch.n
+++ b/doc/catch.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH catch n "8.5" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -77,7 +77,7 @@ the corresponding level; or it may be
.QW \fBUP\fR ,
in which case the parameter is
the relative level (as in \fBuplevel\fR) of the previous \fBCALL\fR. The
-salient differences wrt \fB\-errorinfo\fR are that:
+salient differences with respect to \fB\-errorinfo\fR are that:
.IP [1]
it is a machine-readable form that is amenable to processing with
[\fBforeach\fR {tok prm} ...],
@@ -115,7 +115,8 @@ if { [\fBcatch\fR {open $someFile w} fid] } {
There are more complex examples of \fBcatch\fR usage in the
documentation for the \fBreturn\fR command.
.SH "SEE ALSO"
-break(n), continue(n), dict(n), error(n), info(n), return(n), tclvars(n)
+break(n), continue(n), dict(n), error(n), errorCode(n), errorInfo(n), info(n),
+return(n)
.SH KEYWORDS
catch, error, exception
'\" Local Variables:
diff --git a/doc/cd.n b/doc/cd.n
index eb3854c..67cdd17 100644
--- a/doc/cd.n
+++ b/doc/cd.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH cd n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/chan.n b/doc/chan.n
index 16c51b0..12b2c81 100644
--- a/doc/chan.n
+++ b/doc/chan.n
@@ -3,8 +3,8 @@
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-.so man.macros
.TH chan n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -57,7 +57,7 @@ closed).
.PP
If the channel is blocking and the channel is ceasing to be writable, the
command does not return until all output is flushed. If the channel is
-nonblocking and there is unflushed output, the channel remains open and the
+non-blocking and there is unflushed output, the channel remains open and the
command returns immediately; output will be flushed in the background and the
channel will be closed when all the flushing is complete.
.PP
@@ -107,8 +107,8 @@ the command sets each of the named options to the corresponding
.PP
The options described below are supported for all channels. In
addition, each channel type may add options that only it supports. See
-the manual entry for the command that creates each type of channels
-for the options that that specific type of channel supports. For
+the manual entry for the command that creates each type of channel
+for the options supported by that specific type of channel. For
example, see the manual entry for the \fBsocket\fR command for additional
options for sockets, and the \fBopen\fR command for additional options for
serial devices.
@@ -118,10 +118,10 @@ serial devices.
The \fB\-blocking\fR option determines whether I/O operations on the
channel can cause the process to block indefinitely. The value of the
option must be a proper boolean value. Channels are normally in
-blocking mode; if a channel is placed into nonblocking mode it will
+blocking mode; if a channel is placed into non-blocking mode it will
affect the operation of the \fBchan gets\fR, \fBchan read\fR, \fBchan
puts\fR, \fBchan flush\fR, and \fBchan close\fR commands; see the
-documentation for those commands for details. For nonblocking mode to
+documentation for those commands for details. For non-blocking mode to
work correctly, the application must be using the Tcl event loop
(e.g. by calling \fBTcl_DoOneEvent\fR or invoking the \fBvwait\fR
command).
@@ -399,7 +399,7 @@ commands.
When a thread or interpreter is deleted, all channels created with
this subcommand and using this thread/interpreter as their computing
base are deleted as well, in all interpreters they have been shared
-with or moved into, and in whatever thread they have been transfered
+with or moved into, and in whatever thread they have been transferred
to. While this pulls the rug out under the other thread(s) and/or
interpreter(s), this cannot be avoided. Trying to use such a channel
will cause the generation of a regular error about unknown channel
@@ -453,7 +453,7 @@ be readable if there is unread data in an input buffer, except in the
special case where the most recent attempt to read from the channel
was a \fBchan gets\fR call that could not find a complete line in the
input buffer. This feature allows a file to be read a line at a time
-in nonblocking mode using events. A channel is also considered to be
+in non-blocking mode using events. A channel is also considered to be
readable if an end of file or error condition is present on the
underlying file or device. It is important for \fIscript\fR to check
for these conditions and handle them appropriately; for example, if
@@ -468,12 +468,12 @@ Note that client sockets opened in asynchronous mode become writable
when they become connected or if the connection fails.
.PP
Event-driven I/O works best for channels that have been placed into
-nonblocking mode with the \fBchan configure\fR command. In blocking
+non-blocking mode with the \fBchan configure\fR command. In blocking
mode, a \fBchan puts\fR command may block if you give it more data
than the underlying file or device can accept, and a \fBchan gets\fR
or \fBchan read\fR command will block if you attempt to read more data
than is ready; no events will be processed while the commands block.
-In nonblocking mode \fBchan puts\fR, \fBchan read\fR, and \fBchan
+In non-blocking mode \fBchan puts\fR, \fBchan read\fR, and \fBchan
gets\fR never block.
.PP
The script for a file event is executed at global level (outside the
@@ -493,7 +493,7 @@ is written.
.PP
If the channel is in blocking mode the command does not return until
all the buffered output has been flushed to the channel. If the
-channel is in nonblocking mode, the command may return before all
+channel is in non-blocking mode, the command may return before all
buffered output has been flushed; the remainder will be flushed in the
background as fast as the underlying file or device is able to absorb
it.
@@ -516,7 +516,7 @@ If an end-of-file occurs while part way through reading a line, the
partial line will be returned (or written into \fIvarName\fR). When
\fIvarName\fR is not specified, the end-of-file case can be
distinguished from an empty line using the \fBchan eof\fR command, and
-the partial-line-but-nonblocking case can be distinguished with the
+the partial-line-but-non-blocking case can be distinguished with the
\fBchan blocked\fR command.
.RE
.TP
@@ -630,16 +630,16 @@ flush\fR command.
.PP
When the output buffer fills up, the \fBchan puts\fR command will
normally block until all the buffered data has been accepted for
-output by the operating system. If \fIchannelId\fR is in nonblocking
+output by the operating system. If \fIchannelId\fR is in non-blocking
mode then the \fBchan puts\fR command will not block even if the
operating system cannot accept the data. Instead, Tcl continues to
buffer the data and writes it in the background as fast as the
underlying file or device can accept it. The application must use the
-Tcl event loop for nonblocking output to work; otherwise Tcl never
+Tcl event loop for non-blocking output to work; otherwise Tcl never
finds out that the file or device is ready for more output data. It
is possible for an arbitrarily large amount of data to be buffered for
-a channel in nonblocking mode, which could consume a large amount of
-memory. To avoid wasting memory, nonblocking I/O should normally be
+a channel in non-blocking mode, which could consume a large amount of
+memory. To avoid wasting memory, non-blocking I/O should normally be
used in an event-driven fashion with the \fBchan event\fR command
(do not invoke \fBchan puts\fR unless you have recently been notified
via a file event that the channel is ready for more output data).
@@ -659,7 +659,7 @@ given to indicate that any trailing newline in the string that has
been read should be trimmed.
.RS
.PP
-If \fIchannelId\fR is in nonblocking mode, \fBchan read\fR may not
+If \fIchannelId\fR is in non-blocking mode, \fBchan read\fR may not
read as many characters as requested: once all available input has
been read, the command will return the data that is available rather
than blocking for more input. If the channel is configured to use a
@@ -675,7 +675,7 @@ channel (see \fBchan configure\fR above for a discussion on the ways
in which \fBchan configure\fR will alter input).
.PP
When reading from a serial port, most applications should configure
-the serial port channel to be nonblocking, like this:
+the serial port channel to be non-blocking, like this:
.PP
.CS
\fBchan configure \fIchannelId \fB\-blocking \fI0\fR.
@@ -728,7 +728,7 @@ position after the end of file.
The \fIorigin\fR argument defaults to \fBstart\fR.
.PP
\fBChan seek\fR flushes all buffered output for the channel before the
-command returns, even if the channel is in nonblocking mode. It also
+command returns, even if the channel is in non-blocking mode. It also
discards any buffered and unread input. This command returns an empty
string. An error occurs if this command is applied to channels whose
underlying file or device does not support seeking.
diff --git a/doc/class.n b/doc/class.n
index 88d1b44..198ae41 100644
--- a/doc/class.n
+++ b/doc/class.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH class n 0.1 TclOO "TclOO Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/clock.n b/doc/clock.n
index 8708029..42dca80 100644
--- a/doc/clock.n
+++ b/doc/clock.n
@@ -2,8 +2,8 @@
'\" Generated from file './doc/clock.dt' by tcllib/doctools with format 'nroff'
'\" Copyright (c) 2004 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
'\"
-.so man.macros
.TH "clock" n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
.SH NAME
clock \- Obtain and manipulate dates and times
diff --git a/doc/close.n b/doc/close.n
index 2577cc5..63da75b 100644
--- a/doc/close.n
+++ b/doc/close.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH close n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -23,7 +23,8 @@ Tcl standard channel (\fBstdin\fR, \fBstdout\fR, or \fBstderr\fR),
the return value from an invocation of \fBopen\fR or \fBsocket\fR, or
the result of a channel creation command provided by a Tcl extension.
.PP
-The single-argument form is a simple "full-close":
+The single-argument form is a simple
+.QW "full-close" :
all buffered output is flushed to the channel's output device,
any buffered input is discarded, the underlying file or device is closed,
and \fIchannelId\fR becomes unavailable for use.
@@ -47,8 +48,10 @@ When the last interpreter in which the channel is registered invokes
\fBinterp\fR command for a description of channel sharing.
.PP
Channels are automatically closed when an interpreter is destroyed and
-when the process exits. Channels are switched to blocking mode, to ensure
-that all output is correctly flushed before the process exits.
+when the process exits.
+.VS 8.6
+From 8.6 on (TIP#398), nonblocking channels are no longer switched to blocking mode when exiting; this guarantees a timely exit even when the peer or a communication channel is stalled. To ensure proper flushing of stalled nonblocking channels on exit, one must now either (a) actively switch them back to blocking or (b) use the environment variable TCL_FLUSH_NONBLOCKING_ON_EXIT, which when set and not equal to "0" restores the previous behavior.
+.VE 8.6
.PP
The command returns an empty string, and may generate an error if
an error occurs while flushing output. If a command in a command
@@ -56,16 +59,20 @@ pipeline created with \fBopen\fR returns an error, \fBclose\fR
generates an error (similar to the \fBexec\fR command.)
.PP
.VS 8.6
-The two-argument form is a "half-close": given a bidirectional channel like a
+The two-argument form is a
+.QW "half-close" :
+given a bidirectional channel like a
socket or command pipeline and a (possibly abbreviated) direction, it closes
-only the substream going in that direction. This means a shutdown() on a
+only the sub-stream going in that direction. This means a shutdown() on a
socket, and a close() of one end of a pipe for a command pipeline. Then, the
Tcl-level channel data structure is either kept or freed depending on whether
the other direction is still open.
.PP
-A single-argument close on an already half-closed bi-channel is defined to
-just "finish the job. A half-close on an already closed half, or on a
-wrong-sided unidirectional channel, raises an error.
+A single-argument close on an already half-closed bidirectional channel is
+defined to just
+.QW "finish the job" .
+A half-close on an already closed half, or on a wrong-sided unidirectional
+channel, raises an error.
.PP
In the case of a command pipeline, the child-reaping duty falls upon the
shoulders of the last close or half-close, which is thus allowed to report an
diff --git a/doc/concat.n b/doc/concat.n
index b079b30..575b9df 100644
--- a/doc/concat.n
+++ b/doc/concat.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH concat n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/continue.n b/doc/continue.n
index de2f07c..17d16b4 100644
--- a/doc/continue.n
+++ b/doc/continue.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH continue n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/copy.n b/doc/copy.n
index 51ec844..100d564 100644
--- a/doc/copy.n
+++ b/doc/copy.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH copy n 0.1 TclOO "TclOO Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -26,10 +26,23 @@ resolved relative to the current namespace if not an absolute qualified name.
If \fItargetObject\fR is omitted, a new name is chosen. The copied object will
be of the same class as the source object, and will have all its per-object
methods copied. If it is a class, it will also have all the class methods in
-the class copied, but it will not have any of its instances copied. The
-contents of the source object's private namespace \fIwill not\fR be copied; it
-is up to the caller to do this. The result of this command will be the
-fully-qualified name of the new object or class.
+the class copied, but it will not have any of its instances copied.
+.PP
+.VS
+After the \fItargetObject\fR has been created and all definitions of its
+configuration (e.g., methods, filters, mixins) copied, the \fB<cloned>\fR
+method of \fItargetObject\fR will be invoked, to allow for customization of
+the created object such as installing related variable traces. The only
+argument given will be \fIsourceObject\fR. The default implementation of this
+method (in \fBoo::object\fR) just copies the procedures and variables in the
+namespace of \fIsourceObject\fR to the namespace of \fItargetObject\fR. If
+this method call does not return a result that is successful (i.e., an error
+or other kind of exception) then the \fItargetObject\fR will be deleted and an
+error returned.
+.VE
+.PP
+The result of the \fBoo::copy\fR command will be the fully-qualified name of
+the new object or class.
.SH EXAMPLES
.PP
This example creates an object, copies it, modifies the source object, and
diff --git a/doc/coroutine.n b/doc/coroutine.n
index f4b5d5b..c99f8d3 100644
--- a/doc/coroutine.n
+++ b/doc/coroutine.n
@@ -4,17 +4,20 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH coroutine n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-coroutine, yield \- Create and produce values from coroutines
+coroutine, yield, yieldto \- Create and produce values from coroutines
.SH SYNOPSIS
.nf
\fBcoroutine \fIname command\fR ?\fIarg...\fR?
\fByield\fR ?\fIvalue\fR?
-\fIname\fR ?\fIvalue\fR?
+.VS TIP396
+\fByieldto\fR \fIcommand\fR ?\fIarg...\fR?
+\fIname\fR ?\fIvalue...\fR?
+.VE TIP396
.fi
.BE
.SH DESCRIPTION
@@ -30,11 +33,37 @@ Within the context, values may be generated as results by using the
When that is called, the context will suspend execution and the
\fBcoroutine\fR command will return the argument to \fByield\fR. The execution
of the context can then be resumed by calling the context command, optionally
-passing in the value to use as the result of the \fByield\fR call that caused
+passing in the \fIsingle\fR value to use as the result of the \fByield\fR call
+that caused
the context to be suspended. If the coroutine context never yields and instead
returns conventionally, the result of the \fBcoroutine\fR command will be the
result of the evaluation of the context.
.PP
+.VS TIP396
+The coroutine may also suspend its execution by use of the \fByieldto\fR
+command, which instead of returning, cedes execution to some command called
+\fIcommand\fR (resolved in the context of the coroutine) and to which \fIany
+number\fR of arguments may be passed. Since every coroutine has a context
+command, \fByieldto\fR can be used to transfer control directly from one
+coroutine to another (this is only advisable if the two coroutines are
+expecting this to happen) but \fIany\fR command may be the target. If a
+coroutine is suspended by this mechanism, the coroutine processing can be
+resumed by calling the context command optionally passing in an arbitrary
+number of arguments. The return value of the \fByieldto\fR call will be the
+list of arguments passed to the context command; it is up to the caller to
+decide what to do with those values.
+.PP
+The recommended way of writing a version of \fByield\fR that allows resumption
+with multiple arguments is by using \fByieldto\fR and the \fBreturn\fR
+command, like this:
+.PP
+.CS
+proc yieldm {value} {
+ \fByieldto\fR return -level 0 $value
+}
+.CE
+.VE TIP396
+.PP
The coroutine can also be deleted by destroying the command \fIname\fR, and
the name of the current coroutine can be retrieved by using
\fBinfo coroutine\fR.
@@ -108,6 +137,27 @@ for {set i 1} {$i <= 20} {incr i} {
puts "prime#$i = [\fIeratosthenes\fR]"
}
.CE
+.PP
+.VS TIP396
+This example shows how a value can be passed around a group of three
+coroutines that yield to each other:
+.PP
+.CS
+proc juggler {name target {value ""}} {
+ if {$value eq ""} {
+ set value [\fByield\fR [info coroutine]]
+ }
+ while {$value ne ""} {
+ puts "$name : $value"
+ set value [string range $value 0 end-1]
+ lassign [\fByieldto\fR $target $value] value
+ }
+}
+\fBcoroutine\fR j1 juggler Larry [
+ \fBcoroutine\fR j2 juggler Curly [
+ \fBcoroutine\fR j3 juggler Moe j1]] "Nyuck!Nyuck!Nyuck!"
+.CE
+.VE TIP396
.SS "DETAILED SEMANTICS"
.PP
This example demonstrates that coroutines start from the global namespace, and
diff --git a/doc/dde.n b/doc/dde.n
index a02c582..37d491b 100644
--- a/doc/dde.n
+++ b/doc/dde.n
@@ -5,21 +5,23 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
+.TH dde n 1.4 dde "Tcl Bundled Packages"
.so man.macros
-.TH dde n 1.3 dde "Tcl Bundled Packages"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
dde \- Execute a Dynamic Data Exchange command
.SH SYNOPSIS
.sp
-\fBpackage require dde 1.3\fR
+\fBpackage require dde 1.4\fR
.sp
\fBdde servername\fR ?\fB\-force\fR? ?\fB\-handler \fIproc\fR? ?\fB\-\|\-\fR? ?\fItopic\fR?
.sp
-\fBdde execute\fR ?\fB\-async\fR? \fIservice topic data\fR
+.VS 8.6
+\fBdde execute\fR ?\fB\-async\fR? ?\fB\-binary\fR? \fIservice topic data\fR
.sp
-\fBdde poke\fR \fIservice topic item data\fR
+\fBdde poke\fR ?\fB\-binary\fR? \fIservice topic item data\fR
+.VE 8.6
.sp
\fBdde request\fR ?\fB\-binary\fR? \fIservice topic item\fR
.sp
@@ -69,7 +71,7 @@ procedure is called with all the arguments provided by the remote
call.
.RE
.TP
-\fBdde execute\fR ?\fB\-async\fR? \fIservice topic data\fR
+\fBdde execute\fR ?\fB\-async\fR? ?\fB\-binary\fR? \fIservice topic data\fR
.
\fBdde execute\fR takes the \fIdata\fR and sends it to the server indicated
by \fIservice\fR with the topic indicated by \fItopic\fR. Typically,
@@ -80,8 +82,15 @@ script is run in the application. The \fB\-async\fR option requests
asynchronous invocation. The command returns an error message if the
script did not run, unless the \fB\-async\fR flag was used, in which case
the command returns immediately with no error.
+.VS 8.6
+Without the \fB\-binary\fR option all data will be sent in unicode. For
+dde clients which don't implement the CF_UNICODE clipboard format, this
+will automatically be translated to the system encoding. You can use
+the \fB\-binary\fR option in combination with the result of
+\fBencoding convertto\fR to send data in any other encoding.
+.VE 8.6
.TP
-\fBdde poke \fIservice topic item data\fR
+\fBdde poke\fR ?\fB\-binary\fR? \fIservice topic item data\fR
.
\fBdde poke\fR passes the \fIdata\fR to the server indicated by
\fIservice\fR using the \fItopic\fR and \fIitem\fR specified. Typically,
@@ -90,6 +99,13 @@ specific but can be a command to the server or the name of a file to work
on. The \fIitem\fR is also application specific and is often not used, but
it must always be non-null. The \fIdata\fR field is given to the remote
application.
+.VS 8.6
+Without the \fB\-binary\fR option all data will be sent in unicode. For
+dde clients which don't implement the CF_UNICODE clipboard format, this
+will automatically be translated to the system encoding. You can use
+the \fB\-binary\fR option in combination with the result of
+\fBencoding convertto\fR to send data in any other encoding.
+.VE 8.6
.TP
\fBdde request\fR ?\fB\-binary\fR? \fIservice topic item\fR
.
@@ -145,7 +161,7 @@ unpredictable results.
.PP
An external application which wishes to run a script in Tcl should have
that script store its result in a variable, run the \fBdde execute\fR
-command, and the run \fBdde request\fR to get the value of the
+command, and then run \fBdde request\fR to get the value of the
variable.
.PP
When using DDE, be careful to ensure that the event queue is flushed
@@ -162,9 +178,12 @@ particularly important website:
.PP
.CS
package require dde
-\fBdde execute\fR iexplore WWW_OpenURL http://www.tcl.tk/
+\fBdde execute\fR -async iexplore WWW_OpenURL http://www.tcl.tk/
.CE
.SH "SEE ALSO"
tk(n), winfo(n), send(n)
.SH KEYWORDS
application, dde, name, remote execution
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/doc/define.n b/doc/define.n
index 58bc4cd..7599ec0 100644
--- a/doc/define.n
+++ b/doc/define.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH define n 0.3 TclOO "TclOO Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -81,14 +81,18 @@ class being defined. Note that the methods themselves may be actually defined
by a superclass; subclass exports override superclass visibility, and may in
turn be overridden by instances.
.TP
-\fBfilter\fR ?\fImethodName ...\fR?
-.
-This sets or updates the list of method names that are used to guard whether a
+\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates the list of method names that are used to guard whether
method call to instances of the class may be called and what the method's
results are. Each \fImethodName\fR names a single filtering method (which may
be exposed or not exposed); it is not an error for a non-existent method to be
-named since they may be defined by subclasses. If no \fImethodName\fR
-arguments are present, the list of filter names is set to empty.
+named since they may be defined by subclasses.
+.VS
+By default, this slot works by appending.
+.VE
.TP
\fBforward\fI name cmdName \fR?\fIarg ...\fR?
.
@@ -114,12 +118,16 @@ exported if \fIname\fR starts with a lower-case letter, and non-exported
otherwise; this behavior can be overridden via \fBexport\fR and
\fBunexport\fR.
.TP
-\fBmixin\fR ?\fIclassName ...\fR?
-.
-This sets or updates the list of additional classes that are to be mixed into
+\fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates the list of additional classes that are to be mixed into
all the instances of the class being defined. Each \fIclassName\fR argument
-names a single class that is to be mixed in; if no classes are present, the
-list of mixed-in classes is set to be empty.
+names a single class that is to be mixed in.
+.VS
+By default, this slot works by replacement.
+.VE
.TP
\fBrenamemethod\fI fromName toName\fR
.
@@ -144,12 +152,19 @@ and
operates identically to
.QW "\fBoo::objdefine \fIcls subcommand ...\fR" .
.TP
-\fBsuperclass\fI className \fR?\fIclassName ...\fR?
-.
-This allows the alteration of the superclasses of the class being defined.
+\fBsuperclass\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+allows the alteration of the superclasses of the class being defined.
Each \fIclassName\fR argument names one class that is to be a superclass of
the defined class. Note that objects must not be changed from being classes to
-being non-classes or vice-versa.
+being non-classes or vice-versa, that an empty parent class is equivalent to
+\fBoo::object\fR, and that the parent classes of \fBoo::object\fR and
+\fBoo::class\fR may not be modified.
+.VS
+By default, this slot works by replacement.
+.VE
.TP
\fBunexport\fI name \fR?\fIname ...\fR?
.
@@ -160,18 +175,18 @@ context) by the class being defined. Note that the methods themselves may be
actually defined by a superclass; subclass unexports override superclass
visibility, and may be overridden by instance unexports.
.TP
-\fBvariable\fR ?\fIname ...\fR?
+\fBvariable\fR ?\fI\-slotOperation\fR? ?\fIname ...\fR?
.VS
-This arranges for each of the named variables to be automatically made
+This slot (see \fBSLOTTED DEFINITIONS\fR below) arranges for each of the named
+variables to be automatically made
available in the methods, constructor and destructor declared by the class
-being defined. Note that the list of variable names is the whole list of
-variable names for the class. Each variable name must not have any namespace
+being defined. Each variable name must not have any namespace
separators and must not look like an array access. All variables will be
actually present in the instance object on which the method is executed. Note
that the variable lists declared by a superclass or subclass are completely
disjoint, as are variable lists declared by instances; the list of variable
names is just for methods (and constructors and destructors) declared by this
-class.
+class. By default, this slot works by appending.
.VE
.SS "CONFIGURING OBJECTS"
.PP
@@ -198,15 +213,19 @@ This arranges for each of the named methods, \fIname\fR, to be exported
being defined. Note that the methods themselves may be actually defined by a
class or superclass; object exports override class visibility.
.TP
-\fBfilter\fR ?\fImethodName ...\fR?
-.
-This sets or updates the list of method names that are used to guard whether a
+\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates the list of method names that are used to guard whether a
method call to the object may be called and what the method's results are.
Each \fImethodName\fR names a single filtering method (which may be exposed or
-not exposed); it is not an error for a non-existent method to be named. If no
-\fImethodName\fR arguments are present, the list of filter names is set to
-empty. Note that the actual list of filters also depends on the filters set
-upon any classes that the object is an instance of.
+not exposed); it is not an error for a non-existent method to be named. Note
+that the actual list of filters also depends on the filters set upon any
+classes that the object is an instance of.
+.VS
+By default, this slot works by appending.
+.VE
.TP
\fBforward\fI name cmdName \fR?\fIarg ...\fR?
.
@@ -227,12 +246,16 @@ current namespace of the method will be a namespace that is unique to the
object. The method will be exported if \fIname\fR starts with a lower-case
letter, and non-exported otherwise.
.TP
-\fBmixin\fR ?\fIclassName ...\fR?
-.
-This sets or updates a per-object list of additional classes that are to be
+\fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates a per-object list of additional classes that are to be
mixed into the object. Each argument, \fIclassName\fR, names a single class
-that is to be mixed in; if no classes are present, the list of mixed-in
-classes is set to be empty.
+that is to be mixed in.
+.VS
+By default, this slot works by replacement.
+.VE
.TP
\fBrenamemethod\fI fromName toName\fR
.
@@ -250,16 +273,70 @@ just through the \fBmy\fR command visible in the object's context) by the
object being defined. Note that the methods themselves may be actually defined
by a class; instance unexports override class visibility.
.TP
-\fBvariable\fR ?\fIname ...\fR?
+\fBvariable\fR ?\fI\-slotOperation\fR? ?\fIname ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below) arranges for each of the named
+variables to be automatically made available in the methods declared by the
+object being defined. Each variable name must not have any namespace
+separators and must not look like an array access. All variables will be
+actually present in the object on which the method is executed. Note that the
+variable lists declared by the classes and mixins of which the object is an
+instance are completely disjoint; the list of variable names is just for
+methods declared by this object. By default, this slot works by appending.
+.SH "SLOTTED DEFINITIONS"
+Some of the configurable definitions of a class or object are \fIslotted
+definitions\fR. This means that the configuration is implemented by a slot
+object, that is an instance of the class \fBoo::Slot\fR, which manages a list
+of values (class names, variable names, etc.) that comprises the contents of
+the slot. The class defines three operations (as methods) that may be done on
+the slot:
+.VE
+.TP
+\fIslot\fR \fB\-append\fR ?\fImember ...\fR?
+.VS
+This appends the given \fImember\fR elements to the slot definition.
+.VE
+.TP
+\fIslot\fR \fB\-clear\fR
.VS
-This arranges for each of the named variables to be automatically made
-available in the methods declared by the object being defined. Note that the
-list of variable names is the whole list of variable names for the object.
-Each variable name must not have any namespace separators and must not look
-like an array access. All variables will be actually present in the object on
-which the method is executed. Note that the variable lists declared by the
-classes and mixins of which the object is an instance are completely disjoint;
-the list of variable names is just for methods declared by this object.
+This sets the slot definition to the empty list.
+.VE
+.TP
+\fIslot\fR \fB\-set\fR ?\fImember ...\fR?
+.VS
+This replaces the slot definition with the given \fImember\fR elements.
+.PP
+A consequence of this is that any use of a slot's default operation where the
+first member argument begins with a hyphen will be an error. One of the above
+operations should be used explicitly in those circumstances.
+.SS "SLOT IMPLEMENTATION"
+Internally, slot objects also define a method \fB\-\-default\-operation\fR
+which is forwarded to the default operation of the slot (thus, for the class
+.QW \fBvariable\fR
+slot, this is forwarded to
+.QW "\fBmy \-append\fR" ),
+and these methods which provide the implementation interface:
+.VE
+.TP
+\fIslot\fR \fBGet\fR
+.VS
+Returns a list that is the current contents of the slot. This method must
+always be called from a stack frame created by a call to \fBoo::define\fR or
+\fBoo::objdefine\fR.
+.VE
+.TP
+\fIslot\fR \fBSet \fIelementList\fR
+.VS
+Sets the contents of the slot to the list \fIelementList\fR and returns the
+empty string. This method must always be called from a stack frame created by
+a call to \fBoo::define\fR or \fBoo::objdefine\fR.
+.PP
+The implementation of these methods is slot-dependent (and responsible for
+accessing the correct part of the class or object definition). Slots also have
+an unknown method handler to tie all these pieces together, and they hide
+their \fBdestroy\fR method so that it is not invoked inadvertently. It is
+\fIrecommended\fR that any user changes to the slot mechanism be restricted to
+defining new operations whose names start with a hyphen.
.VE
.SH EXAMPLES
This example demonstrates how to use both forms of the \fBoo::define\fR and
@@ -286,11 +363,41 @@ o Foo Bar \fI\(-> error "unknown method Foo"\fR
\fBoo::objdefine\fR o \fBrenamemethod\fR bar lollipop
o lollipop \fI\(-> prints "hello world"\fR
.CE
+.PP
+This example shows how additional classes can be mixed into an object. It also
+shows how \fBmixin\fR is a slot that supports appending:
+.PP
+.CS
+oo::object create inst
+inst m1 \fI\(-> error "unknown method m1"\fR
+inst m2 \fI\(-> error "unknown method m2"\fR
+
+oo::class create A {
+ \fBmethod\fR m1 {} {
+ puts "red brick"
+ }
+}
+\fBoo::objdefine\fR inst {
+ \fBmixin\fR A
+}
+inst m1 \fI\(-> prints "red brick"\fR
+inst m2 \fI\(-> error "unknown method m2"\fR
+
+oo::class create B {
+ \fBmethod\fR m2 {} {
+ puts "blue brick"
+ }
+}
+\fBoo::objdefine\fR inst {
+ \fBmixin -append\fR B
+}
+inst m1 \fI\(-> prints "red brick"\fR
+inst m2 \fI\(-> prints "blue brick"\fR
+.CE
.SH "SEE ALSO"
next(n), oo::class(n), oo::object(n)
.SH KEYWORDS
-class, definition, method, object
-
+class, definition, method, object, slot
.\" Local variables:
.\" mode: nroff
.\" fill-column: 78
diff --git a/doc/dict.n b/doc/dict.n
index b8386f2..77c460b 100644
--- a/doc/dict.n
+++ b/doc/dict.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH dict n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -147,6 +147,31 @@ keys are treated as if they map to an empty list, and it is legal for
there to be no items to append to the list. It is an error for the
value that the key maps to to not be representable as a list.
.TP
+\fBdict map \fR{\fIkeyVar valueVar\fR} \fIdictionaryValue body\fR
+.
+This command applies a transformation to each element of a dictionary,
+returning a new dictionary. It takes three arguments: the first is a
+two-element list of variable names (for the key and value respectively of each
+mapping in the dictionary), the second the dictionary value to iterate across,
+and the third a script to be evaluated for each mapping with the key and value
+variables set appropriately (in the manner of \fBlmap\fR). In an iteration
+where the evaluated script completes normally (\fBTCL_OK\fR, as opposed to an
+\fBerror\fR, etc.) the result of the script is put into an accumulator
+dictionary using the key that is the current contents of the \fIkeyVar\fR
+variable at that point. The result of the \fBdict map\fR command is the
+accumulator dictionary after all keys have been iterated over.
+.RS
+.PP
+If the evaluation of the body for any particular step generates a \fBbreak\fR,
+no further pairs from the dictionary will be iterated over and the \fBdict
+map\fR command will terminate successfully immediately. If the evaluation of
+the body for a particular step generates a \fBcontinue\fR result, the current
+iteration is aborted and the accumulator dictionary is not modified. The order
+of iteration is the natural order of the dictionary (typically the order in
+which the keys were added to the dictionary; the order is the same as that
+used in \fBdict for\fR).
+.RE
+.TP
\fBdict merge \fR?\fIdictionaryValue ...\fR?
.
Return a dictionary that contains the contents of each of the
@@ -251,6 +276,15 @@ exist after the command finishes (unless explicitly \fBunset\fR).
Note that the mapping of values to variables does not use
traces; changes to the \fIdictionaryVariable\fR's contents only happen
when \fIbody\fR terminates.
+.PP
+If the \fIdictionaryVariable\fR contains a value that is not a dictionary at
+the point when the \fIbody\fR terminates (which can easily happen if the name
+is the same as any of the keys in dictionary) then an error occurs at that
+point. This command is thus not recommended for use when the keys in the
+dictionary are expected to clash with the \fIdictionaryVariable\fR name
+itself. Where the contained key does map to a dictionary, the net effect is to
+combine that inner dictionary into the outer dictionary; see the
+\fBEXAMPLES\fR below for an illustration of this.
.RE
.SH "DICTIONARY VALUES"
.PP
@@ -388,10 +422,20 @@ sumDictionary myDict
puts "dictionary is now \\"$myDict\\""
# prints: \fIdictionary is now "a {total 6} b {total 15}"\fR
.CE
+.PP
+When \fBdict with\fR is used with a key that clashes with the name of the
+dictionary variable:
+.PP
+.CS
+set foo {foo {a b} bar 2 baz 3}
+\fBdict with\fR foo {}
+puts $foo
+# prints: \fIa b foo {a b} bar 2 baz 3\fR
+.CE
.SH "SEE ALSO"
-append(n), array(n), foreach(n), incr(n), list(n), lappend(n), set(n)
+append(n), array(n), foreach(n), mapeach(n), incr(n), list(n), lappend(n), set(n)
.SH KEYWORDS
-dictionary, create, update, lookup, iterate, filter
+dictionary, create, update, lookup, iterate, filter, map
'\" Local Variables:
'\" mode: nroff
'\" End:
diff --git a/doc/encoding.n b/doc/encoding.n
index 5269a18..5782199 100644
--- a/doc/encoding.n
+++ b/doc/encoding.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH encoding n "8.1" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
.SH NAME
encoding \- Manipulate encodings
@@ -14,10 +14,21 @@ encoding \- Manipulate encodings
.BE
.SH INTRODUCTION
.PP
-Strings in Tcl are encoded using 16-bit Unicode characters. Different
-operating system interfaces or applications may generate strings in
-other encodings such as Shift-JIS. The \fBencoding\fR command helps
-to bridge the gap between Unicode and these other formats.
+Strings in Tcl are logically a sequence of 16-bit Unicode characters.
+These strings are represented in memory as a sequence of bytes that
+may be in one of several encodings: modified UTF\-8 (which uses 1 to 3
+bytes per character), 16-bit
+.QW Unicode
+(which uses 2 bytes per character, with an endianness that is
+dependent on the host architecture), and binary (which uses a single
+byte per character but only handles a restricted range of characters).
+Tcl does not guarantee to always use the same encoding for the same
+string.
+.PP
+Different operating system interfaces or applications may generate
+strings in other encodings such as Shift\-JIS. The \fBencoding\fR
+command helps to bridge the gap between Unicode and these other
+formats.
.SH DESCRIPTION
.PP
Performs one of several encoding related operations, depending on
@@ -37,8 +48,9 @@ system encoding is used.
Convert \fIstring\fR from Unicode to the specified \fIencoding\fR.
The result is a sequence of bytes that represents the converted
string. Each byte is stored in the lower 8-bits of a Unicode
-character. If \fIencoding\fR is not specified, the current
-system encoding is used.
+character (indeed, the resulting string is a binary string as far as
+Tcl is concerned, at least initially). If \fIencoding\fR is not
+specified, the current system encoding is used.
.TP
\fBencoding dirs\fR ?\fIdirectoryList\fR?
.
@@ -56,6 +68,11 @@ searchable directory, that element is ignored.
.
Returns a list containing the names of all of the encodings that are
currently available.
+The encodings
+.QW utf-8
+and
+.QW iso8859-1
+are guaranteed to be present in the list.
.TP
\fBencoding system\fR ?\fIencoding\fR?
.
@@ -73,7 +90,7 @@ However, because the \fBsource\fR command always reads files using the
current system encoding, Tcl will only source such files correctly
when the encoding used to write the file is the same. This tends not
to be true in an internationalized setting. For example, if such a
-file was sourced in North America (where the ISO8859-1 is normally
+file was sourced in North America (where the ISO8859\-1 is normally
used), each byte in the file would be treated as a separate character
that maps to the 00 page in Unicode. The resulting Tcl strings will
not contain the expected Japanese characters. Instead, they will
@@ -93,3 +110,6 @@ which is the Hiragana letter HA.
Tcl_GetEncoding(3)
.SH KEYWORDS
encoding, unicode
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/eof.n b/doc/eof.n
index 017b10e..75f3c48 100644
--- a/doc/eof.n
+++ b/doc/eof.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH eof n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/error.n b/doc/error.n
index d61bd7b..a95c691 100644
--- a/doc/error.n
+++ b/doc/error.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH error n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/eval.n b/doc/eval.n
index da88757..3ef5023 100644
--- a/doc/eval.n
+++ b/doc/eval.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH eval n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -75,7 +75,8 @@ However, the last line would now normally be written without
set var [linsert $var 0 {*}$args]
.CE
.SH "SEE ALSO"
-catch(n), concat(n), error(n), interp(n), list(n), namespace(n), subst(n), tclvars(n), uplevel(n)
+catch(n), concat(n), error(n), errorCode(n), errorInfo(n), interp(n), list(n),
+namespace(n), subst(n), uplevel(n)
.SH KEYWORDS
concatenate, evaluate, script
'\" Local Variables:
diff --git a/doc/exec.n b/doc/exec.n
index 5072d61..c3f316b 100644
--- a/doc/exec.n
+++ b/doc/exec.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH exec n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/exit.n b/doc/exit.n
index ceb0529..ab5c87d 100644
--- a/doc/exit.n
+++ b/doc/exit.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH exit n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/expr.n b/doc/expr.n
index 2ecd501..a595207 100644
--- a/doc/expr.n
+++ b/doc/expr.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH expr n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -39,9 +39,9 @@ additional operators not found in C.
.SS OPERANDS
.PP
A Tcl expression consists of a combination of operands, operators,
-and parentheses.
+parentheses and commas.
White space may be used between the operands and operators and
-parentheses; it is ignored by the expression's instructions.
+parentheses (or commas); it is ignored by the expression's instructions.
Where possible, operands are interpreted as integer values.
Integer values may be specified in decimal (the normal case), in binary
(if the first two characters of the operand are \fB0b\fR), in octal
@@ -134,7 +134,20 @@ Multiply, divide, remainder. None of these operators may be
applied to string operands, and remainder may be applied only
to integers.
The remainder will always have the same sign as the divisor and
-an absolute value smaller than the divisor.
+an absolute value smaller than the absolute value of the divisor.
+.RS
+.PP
+When applied to integers, the division and remainder operators can be
+considered to partition the number line into a sequence of equal-sized
+adjacent non-overlapping pieces where each piece is the size of the divisor;
+the division result identifies which piece the divisor lay within, and the
+remainder result identifies where within that piece the divisor lay. A
+consequence of this is that the result of
+.QW "-57 \fB/\fR 10"
+is always -6, and the result of
+.QW "-57 \fB%\fR 10"
+is always 3.
+.RE
.TP 20
\fB+\0\0\-\fR
.
@@ -270,6 +283,18 @@ rules for resolving functions in namespaces. Either
current]::tcl::mathfunc::sin\fR will satisfy the request, and others
may as well (depending on the current \fBnamespace path\fR setting).
.PP
+Some mathematical functions have several arguments, separated by commas like in C. Thus:
+.PP
+.CS
+\fBexpr\fR {hypot($x,$y)}
+.CE
+.PP
+ends up as
+.PP
+.CS
+tcl::mathfunc::hypot $x $y
+.CE
+.PP
See the \fBmathfunc\fR(n) manual page for the math functions that are
available by default.
.SS "TYPES, OVERFLOW, AND PRECISION"
@@ -326,6 +351,7 @@ returns \fB4.0\fR, not \fB4\fR.
String values may be used as operands of the comparison operators,
although the expression evaluator tries to do comparisons as integer
or floating-point when it can,
+i.e., when all arguments to the operator allow numeric interpretations,
except in the case of the \fBeq\fR and \fBne\fR operators.
If one of the operands of a comparison is a string and the other
has a numeric value, a canonical string representation of the numeric
@@ -337,12 +363,11 @@ is that produced by the \fB%g\fR format specifier of Tcl's
.PP
.CS
\fBexpr\fR {"0x03" > "2"}
-\fBexpr\fR {"0y" < "0x12"}
+\fBexpr\fR {"0y" > "0x12"}
.CE
.PP
both return 1. The first comparison is done using integer
-comparison, and the second is done using string comparison after
-the second operand is converted to the string \fB18\fR.
+comparison, and the second is done using string comparison.
Because of Tcl's tendency to treat values as numbers whenever
possible, it is not generally a good idea to use operators like \fB==\fR
when you really want string comparison and the values of the
diff --git a/doc/fconfigure.n b/doc/fconfigure.n
index ac0366c..ca23314 100644
--- a/doc/fconfigure.n
+++ b/doc/fconfigure.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH fconfigure n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -72,8 +72,8 @@ initially set to \fBline\fR, and \fBstderr\fR is set to \fBnone\fR.
.
\fINewvalue\fR must be an integer; its value is used to set the size of
buffers, in bytes, subsequently allocated for this channel to store input
-or output. \fINewvalue\fR must be between ten and one million, allowing
-buffers of ten to one million bytes in size.
+or output. \fINewvalue\fR must be between one and one million, allowing
+buffers of one to one million bytes in size.
.TP
\fB\-encoding\fR \fIname\fR
.
diff --git a/doc/fcopy.n b/doc/fcopy.n
index 6a4bf1a..071896c 100644
--- a/doc/fcopy.n
+++ b/doc/fcopy.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH fcopy n 8.0 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -46,8 +46,11 @@ non-blocking mode; the \fBfcopy\fR command takes care of that automatically.
However, it is necessary to enter the event loop by using
the \fBvwait\fR command or by using Tk.
.PP
-You are not allowed to do other I/O operations with
-\fIinchan\fR or \fIoutchan\fR during a background \fBfcopy\fR.
+You are not allowed to do other input operations with \fIinchan\fR, or
+output operations with \fIoutchan\fR, during a background
+\fBfcopy\fR. The converse is entirely legitimate, as exhibited by the
+bidirectional fcopy example below.
+.PP
If either \fIinchan\fR or \fIoutchan\fR get closed
while the copy is in progress, the current copy is stopped
and the command callback is \fInot\fR made.
@@ -57,7 +60,7 @@ then all data already queued for \fIoutchan\fR is written out.
Note that \fIinchan\fR can become readable during a background copy.
You should turn off any \fBfileevent\fR handlers during a background
copy so those handlers do not interfere with the copy.
-Any I/O attempted by a \fBfileevent\fR handler will get a
+Any wrong-sided I/O attempted (by a \fBfileevent\fR handler or otherwise) will get a
.QW "channel busy"
error.
.PP
@@ -149,6 +152,24 @@ set total 0
-command [list CopyMore $in $out $chunk]
vwait done
.CE
+.PP
+The fourth example starts an asynchronous, bidirectional fcopy between
+two sockets. Those could also be pipes from two [open "|hal 9000" r+]
+(though their conversation would remain secret to the script, since
+all four fileevent slots are busy).
+.PP
+.CS
+set flows 2
+proc Done {dir args} {
+ global flows done
+ puts "$dir is over."
+ incr flows -1
+ if {$flows<=0} {set done 1}
+}
+\fBfcopy\fR $sok1 $sok2 -command [list Done UP]
+\fBfcopy\fR $sok2 $sok1 -command [list Done DOWN]
+vwait done
+.CE
.SH "SEE ALSO"
eof(n), fblocked(n), fconfigure(n), file(n)
.SH KEYWORDS
diff --git a/doc/file.n b/doc/file.n
index eef4647..5ff45fd 100644
--- a/doc/file.n
+++ b/doc/file.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH file n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -481,6 +481,13 @@ Returns \fB1\fR if file \fIname\fR is writable by the current user,
.
These commands always operate using the real user and group identifiers,
not the effective ones.
+.TP
+\fBWindows\fR\0\0\0\0
+.
+The \fBfile owned\fR subcommand currently always reports that the current user
+is the owner of the file, without regard for what the operating system
+believes to be true, making an ownership test useless. This issue (#3613671)
+may be fixed in a future release of Tcl.
.SH EXAMPLES
.PP
This procedure shows how to search for C files in a given directory
diff --git a/doc/fileevent.n b/doc/fileevent.n
index df48d2a..8f6b880 100644
--- a/doc/fileevent.n
+++ b/doc/fileevent.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH fileevent n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -80,13 +80,16 @@ A channel is considered to be writable if at least one byte of data
can be written to the underlying file or device without blocking,
or if an error condition is present on the underlying file or device.
.PP
-Event-driven I/O works best for channels that have been
-placed into nonblocking mode with the \fBfconfigure\fR command.
-In blocking mode, a \fBputs\fR command may block if you give it
-more data than the underlying file or device can accept, and a
-\fBgets\fR or \fBread\fR command will block if you attempt to read
-more data than is ready; no events will be processed while the
-commands block.
+Event-driven I/O works best for channels that have been placed into
+nonblocking mode with the \fBfconfigure\fR command. In blocking mode,
+a \fBputs\fR command may block if you give it more data than the
+underlying file or device can accept, and a \fBgets\fR or \fBread\fR
+command will block if you attempt to read more data than is ready; a
+readable underlying file or device may not even guarantee that a
+blocking [read 1] will succeed (counter-examples being multi-byte
+encodings, compression or encryption transforms ). In all such cases,
+no events will be processed while the commands block.
+.PP
In nonblocking mode \fBputs\fR, \fBread\fR, and \fBgets\fR never block.
See the documentation for the individual commands for information
on how they handle blocking and nonblocking channels.
diff --git a/doc/filename.n b/doc/filename.n
index d481fc9..8b8b00b 100644
--- a/doc/filename.n
+++ b/doc/filename.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH filename n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/flush.n b/doc/flush.n
index b8bf3e9..d266d91 100644
--- a/doc/flush.n
+++ b/doc/flush.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH flush n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/for.n b/doc/for.n
index 4c65793..40c7cab 100644
--- a/doc/for.n
+++ b/doc/for.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH for n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/foreach.n b/doc/foreach.n
index fb075d3..89a11f6 100644
--- a/doc/foreach.n
+++ b/doc/foreach.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH foreach n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/format.n b/doc/format.n
index 23dfe60..076a820 100644
--- a/doc/format.n
+++ b/doc/format.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH format n 8.1 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/gets.n b/doc/gets.n
index bed7e32..0150f29 100644
--- a/doc/gets.n
+++ b/doc/gets.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH gets n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -35,12 +35,12 @@ returned.
.PP
If end of file occurs while scanning for an end of
line, the command returns whatever input is available up to the end of file.
-If \fIchannelId\fR is in nonblocking mode and there is not a full
+If \fIchannelId\fR is in non-blocking mode and there is not a full
line of input available, the command returns an empty string and
does not consume any input.
If \fIvarName\fR is specified and an empty string is returned in
\fIvarName\fR because of end-of-file or because of insufficient
-data in nonblocking mode, then the return count is -1.
+data in non-blocking mode, then the return count is -1.
Note that if \fIvarName\fR is not specified then the end-of-file
and no-full-line-available cases can
produce the same results as if there were an input line consisting
@@ -64,4 +64,8 @@ close $chan
file(n), eof(n), fblocked(n), Tcl_StandardChannels(3)
.SH KEYWORDS
-blocking, channel, end of file, end of line, line, nonblocking, read
+blocking, channel, end of file, end of line, line, non-blocking, read
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/glob.n b/doc/glob.n
index 7b71189..86e450b 100644
--- a/doc/glob.n
+++ b/doc/glob.n
@@ -4,8 +4,8 @@
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-.so man.macros
.TH glob n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/global.n b/doc/global.n
index c17c370..aa8f2e4 100644
--- a/doc/global.n
+++ b/doc/global.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH global n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/history.n b/doc/history.n
index ba507b4..e1f9781 100644
--- a/doc/history.n
+++ b/doc/history.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH history n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/http.n b/doc/http.n
index 631a141..26054cd 100644
--- a/doc/http.n
+++ b/doc/http.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH "http" n 2.7 http "Tcl Bundled Packages"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/if.n b/doc/if.n
index 700f325..776f811 100644
--- a/doc/if.n
+++ b/doc/if.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH if n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/incr.n b/doc/incr.n
index 595cc27..9052c5a 100644
--- a/doc/incr.n
+++ b/doc/incr.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH incr n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/info.n b/doc/info.n
index 0001ae9..1ad908d 100644
--- a/doc/info.n
+++ b/doc/info.n
@@ -3,13 +3,13 @@
'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
'\" Copyright (c) 1998-2000 Ajuba Solutions
-'\" Copyright (c) 2007-2008 Donal K. Fellows
+'\" Copyright (c) 2007-2012 Donal K. Fellows
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH info n 8.4 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -79,9 +79,9 @@ lines have been typed to complete the command.
.TP
\fBinfo coroutine\fR
.VS 8.6
-Returns the name of the currently executing coroutine, or the empty string if
-either no coroutine is currently executing, or the current coroutine has been
-deleted (but has not yet returned or yielded since deletion).
+Returns the name of the currently executing \fBcoroutine\fR, or the empty
+string if either no coroutine is currently executing, or the current coroutine
+has been deleted (but has not yet returned or yielded since deletion).
.VE 8.6
.TP
\fBinfo default \fIprocname arg varname\fR
@@ -97,23 +97,27 @@ into variable \fIvarname\fR.
Returns, in a form that is programmatically easy to parse, the function names
and arguments at each level from the call stack of the last error in the given
\fIinterp\fR, or in the current one if not specified.
-
+.RS
+.PP
This form is an even-sized list alternating tokens and parameters. Tokens are
currently either \fBCALL\fR, \fBUP\fR, or \fBINNER\fR, but other values may be
introduced in the future. \fBCALL\fR indicates a procedure call, and its
-parameter is the corresponding [info level 0]. \fBUP\fR indicates a shift in
-variable frames generated by uplevel or similar, and applies to the previous
-CALL item. Its parameter is the level offset. \fBINNER\fR identifies the
-"inner context", which is the innermost atomic command or bytecode instruction
-that raised the error, along with its arguments when available. While
-\fBCALL\fR and \fBUP\fR allow to follow complex call paths, \fBINNER\fR homes
-in on the offending operation in the innermost proc call, even going to
-sub-expr granularity.
-
-This information is also present in the
-\fB\-errorstack\fR entry of the options dictionary returned by 3-argument
-\fBcatch\fR; \fBinfo errorstack\fR is a convenient way of retrieving it for
-uncaught errors at toplevel in an interactive tclsh.
+parameter is the corresponding \fBinfo level\fR \fB0\fR. \fBUP\fR indicates a
+shift in variable frames generated by \fBuplevel\fR or similar, and applies to
+the previous \fBCALL\fR item. Its parameter is the level offset. \fBINNER\fR
+identifies the
+.QW "inner context" ,
+which is the innermost atomic command or bytecode instruction that raised the
+error, along with its arguments when available. While \fBCALL\fR and \fBUP\fR
+allow to follow complex call paths, \fBINNER\fR homes in on the offending
+operation in the innermost procedure call, even going to sub-expression
+granularity.
+.PP
+This information is also present in the \fB\-errorstack\fR entry of the
+options dictionary returned by 3-argument \fBcatch\fR; \fBinfo errorstack\fR
+is a convenient way of retrieving it for uncaught errors at top-level in an
+interactive \fBtclsh\fR.
+.RE
.VE 8.6
.TP
\fBinfo exists \fIvarName\fR
@@ -176,7 +180,7 @@ means that the command is executed by \fBeval\fR or \fBuplevel\fR.
.TP
\fBprecompiled\fR\0\0\0\0\0\0\0\0
.
-means that the command is found in a precompiled script (loadable by
+means that the command is found in a pre-compiled script (loadable by
the package \fBtbcload\fR), and no further information will be
available.
.RE
@@ -197,9 +201,10 @@ normalized path of the file the command is in.
\fBcmd\fR
.
This entry provides the string representation of the command. This is
-usually the unsubstituted form, however for commands which are a pure
-list executed by eval it is the substituted form as they have no other
-string representation. Care is taken that the pure-List property of
+usually the unsubstituted form, however for commands which are a
+canonically-constructed list (e.g., as produced by the \fBlist\fR command)
+executed by \fBeval\fR it is the substituted form as they have no other
+string representation. Care is taken that the canonicality property of
the latter is not spoiled.
.TP
\fBproc\fR
@@ -226,8 +231,8 @@ locations of commands in their bodies will be reported with type
defined procedures, and literal eval scripts in files or statically
defined procedures.
.PP
-In contrast, a procedure definition or \fBeval\fR within a dynamically
-\fBeval\fRuated environment count linenumbers relative to the start of
+In contrast, procedure definitions and \fBeval\fR within a dynamically
+\fBeval\fRuated environment count line numbers relative to the start of
their script, even if they would be able to count relative to the
start of the outer dynamic script. That type of number usually makes
more sense.
@@ -239,8 +244,8 @@ possible the lines are counted based on the smallest possible
than any dynamic outer scope.
.PP
The syntactic form \fB{*}\fR is handled like \fBeval\fR. I.e. if it
-is given a literal list argument the system tracks the linenumber
-within the list words as well, and otherwise all linenumbers are
+is given a literal list argument the system tracks the line number
+within the list words as well, and otherwise all line numbers are
counted relative to the start of each word (smallest scope)
.RE
.TP
@@ -291,7 +296,6 @@ Returns the name of the library directory in which standard Tcl
scripts are stored.
This is actually the value of the \fBtcl_library\fR
variable and may be changed by setting \fBtcl_library\fR.
-See the \fBtclvars\fR manual entry for more information.
.TP
\fBinfo loaded \fR?\fIinterp\fR?
.
@@ -331,8 +335,8 @@ described in \fBOBJECT INTROSPECTION\fR below.
.TP
\fBinfo patchlevel\fR
.
-Returns the value of the global variable \fBtcl_patchLevel\fR; see
-the \fBtclvars\fR manual entry for more information.
+Returns the value of the global variable \fBtcl_patchLevel\fR, which holds
+the exact version of the Tcl library by default.
.TP
\fBinfo procs \fR?\fIpattern\fR?
.
@@ -369,8 +373,8 @@ string is returned.
.TP
\fBinfo tclversion\fR
.
-Returns the value of the global variable \fBtcl_version\fR; see
-the \fBtclvars\fR manual entry for more information.
+Returns the value of the global variable \fBtcl_version\fR, which holds the
+major and minor version of the Tcl library by default.
.TP
\fBinfo vars\fR ?\fIpattern\fR?
.
@@ -425,9 +429,9 @@ actually use \fBnext\fR to transfer control along the call chain.
\fBinfo class constructor\fI class\fR
.VS 8.6
This subcommand returns a description of the definition of the constructor of
-class \fIclass\fR. The defintion is described as a two element list; the first
+class \fIclass\fR. The definition is described as a two element list; the first
element is the list of arguments to the constructor in a form suitable for
-passing to another call to \fBproc\fR or a method defintion, and the second
+passing to another call to \fBproc\fR or a method definition, and the second
element is the body of the constructor. If no constructor is present, this
returns the empty list.
.VE 8.6
@@ -435,9 +439,9 @@ returns the empty list.
\fBinfo class definition\fI class method\fR
.VS 8.6
This subcommand returns a description of the definition of the method named
-\fImethod\fR of class \fIclass\fR. The defintion is described as a two element
+\fImethod\fR of class \fIclass\fR. The definition is described as a two element
list; the first element is the list of arguments to the method in a form
-suitable for passing to another call to \fBproc\fR or a method defintion, and
+suitable for passing to another call to \fBproc\fR or a method definition, and
the second element is the body of the method.
.VE 8.6
.TP
@@ -559,9 +563,9 @@ boolean value indicating whether the \fIobject\fR is of that class.
\fBinfo object definition\fI object method\fR
.VS 8.6
This subcommand returns a description of the definition of the method named
-\fImethod\fR of object \fIobject\fR. The defintion is described as a two
+\fImethod\fR of object \fIobject\fR. The definition is described as a two
element list; the first element is the list of arguments to the method in a
-form suitable for passing to another call to \fBproc\fR or a method defintion,
+form suitable for passing to another call to \fBproc\fR or a method definition,
and the second element is the body of the method.
.VE 8.6
.TP
@@ -671,7 +675,7 @@ This subcommand returns a list of all variables in the private namespace of
the object named \fIobject\fR. If the optional \fIpattern\fR argument is
given, it is a filter (in the syntax of a \fBstring match\fR glob pattern)
that constrains the list of variables returned. Note that this is different
-from the lit returned by \fBinfo object variables\fR; that can include
+from the list returned by \fBinfo object variables\fR; that can include
variables that are currently unset, whereas this can include variables that
are not automatically included by any of \fIobject\fR's methods (or those of
its class, superclasses or mixins).
@@ -731,10 +735,11 @@ proc getDef {obj method} {
}
.CE
.PP
-This is an alternate way of implementing the definition lookup is by manually
-scanning the list of methods up the inheritance tree. This code assumes that
-only single inheritance is in use, and that there is no complex use of
-mixed-in classes:
+This is an alternate way of looking up the definition; it is implemented by
+manually scanning the list of methods up the inheritance tree. This code
+assumes that only single inheritance is in use, and that there is no complex
+use of mixed-in classes (in such cases, using \fBinfo object call\fR as above
+is the simplest way of doing this by far):
.PP
.CS
proc getDef {obj method} {
@@ -746,7 +751,7 @@ proc getDef {obj method} {
while {$method ni [\fBinfo class methods\fR $cls]} {
# Assume the simple case
set cls [lindex [\fBinfo class superclass\fR $cls] 0]
- if {$cls eq {}} {
+ if {$cls eq ""} {
error "no definition for $method"
}
}
@@ -757,8 +762,9 @@ proc getDef {obj method} {
.VE 8.6
.SH "SEE ALSO"
.VS 8.6
-global(n), oo::class(n), oo::define(n), oo::object(n), proc(n), self(n)
+global(n), oo::class(n), oo::define(n), oo::object(n), proc(n), self(n),
.VE 8.6
+tcl_library(n), tcl_patchLevel(n), tcl_version(n)
.SH KEYWORDS
command, information, interpreter, introspection, level, namespace,
.VS 8.6
diff --git a/doc/interp.n b/doc/interp.n
index b261779..92113a6 100644
--- a/doc/interp.n
+++ b/doc/interp.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH interp n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -230,6 +230,10 @@ extends so far that the system will be able to determine the file and
absolute line number of this command, and return a frame of type
\fBsource\fR. This more exact information is paid for with slower
execution of all commands.
+.PP
+Note that once it is on, this flag cannot be switched back off: such
+attempts are silently ignored. This is needed to maintain the
+consistency of the underlying interpreter's state.
.RE
.TP
\fBinterp\fR \fBdelete \fR?\fIpath ...?\fR
diff --git a/doc/join.n b/doc/join.n
index 1b23667..c8179bb 100644
--- a/doc/join.n
+++ b/doc/join.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH join n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/lappend.n b/doc/lappend.n
index 9bfab72..a324ca3 100644
--- a/doc/lappend.n
+++ b/doc/lappend.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH lappend n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/lassign.n b/doc/lassign.n
index 6f5042b..e250729 100644
--- a/doc/lassign.n
+++ b/doc/lassign.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH lassign n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/library.n b/doc/library.n
index 2413692..775b7d9 100644
--- a/doc/library.n
+++ b/doc/library.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH library n "8.0" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
.SH NAME
auto_execok, auto_import, auto_load, auto_mkindex, auto_qualify, auto_reset, tcl_findLibrary, parray, tcl_endOfWord, tcl_startOfNextWord, tcl_startOfPreviousWord, tcl_wordBreakAfter, tcl_wordBreakBefore \- standard library of Tcl procedures
@@ -262,13 +262,17 @@ If set to any value, then \fBunknown\fR will not attempt to auto-load
any commands.
.TP
\fBauto_path\fR
+.
If set, then it must contain a valid Tcl list giving directories to
-search during auto-load operations.
+search during auto-load operations (including for package index
+files when using the default \fBpackage unknown\fR handler).
This variable is initialized during startup to contain, in order:
the directories listed in the \fBTCLLIBPATH\fR environment variable,
-the directory named by the \fBtcl_library\fR variable,
+the directory named by the \fBtcl_library\fR global variable,
the parent directory of \fBtcl_library\fR,
the directories listed in the \fBtcl_pkgPath\fR variable.
+Additional locations to look for files and package indices should
+normally be added to this variable using \fBlappend\fR.
.TP
\fBenv(TCL_LIBRARY)\fR
If set, then it specifies the location of the directory containing
@@ -306,7 +310,7 @@ considered to be a word character. On Windows platforms, words are
comprised of any character that is not a space, tab, or newline. Under
Unix, words are comprised of numbers, letters or underscores.
.SH "SEE ALSO"
-info(n), re_syntax(n), tclvars(n)
+env(n), info(n), re_syntax(n)
.SH KEYWORDS
auto-exec, auto-load, library, unknown, word, whitespace
'\"Local Variables:
diff --git a/doc/lindex.n b/doc/lindex.n
index bb272a6..b42904b 100644
--- a/doc/lindex.n
+++ b/doc/lindex.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH lindex n 8.4 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/linsert.n b/doc/linsert.n
index c722e4f..51b64cf 100644
--- a/doc/linsert.n
+++ b/doc/linsert.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH linsert n 8.2 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/list.n b/doc/list.n
index 5705254..c2797f3 100644
--- a/doc/list.n
+++ b/doc/list.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH list n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/llength.n b/doc/llength.n
index b0ee4d9..d3f9610 100644
--- a/doc/llength.n
+++ b/doc/llength.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH llength n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/lmap.n b/doc/lmap.n
new file mode 100644
index 0000000..2038fc2
--- /dev/null
+++ b/doc/lmap.n
@@ -0,0 +1,85 @@
+'\"
+'\" Copyright (c) 2012 Trevor Davel
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH lmap n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lmap \- Iterate over all elements in one or more lists and collect results
+.SH SYNOPSIS
+\fBlmap \fIvarname list body\fR
+.br
+\fBlmap \fIvarlist1 list1\fR ?\fIvarlist2 list2 ...\fR? \fIbody\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBlmap\fR command implements a loop where the loop variable(s) take on
+values from one or more lists, and the loop returns a list of results
+collected from each iteration.
+.PP
+In the simplest case there is one loop variable, \fIvarname\fR, and one list,
+\fIlist\fR, that is a list of values to assign to \fIvarname\fR. The
+\fIbody\fR argument is a Tcl script. For each element of \fIlist\fR (in order
+from first to last), \fBlmap\fR assigns the contents of the element to
+\fIvarname\fR as if the \fBlindex\fR command had been used to extract the
+element, then calls the Tcl interpreter to execute \fIbody\fR. If execution of
+the body completes normally then the result of the body is appended to an
+accumulator list. \fBlmap\fR returns the accumulator list.
+.PP
+In the general case there can be more than one value list (e.g., \fIlist1\fR
+and \fIlist2\fR), and each value list can be associated with a list of loop
+variables (e.g., \fIvarlist1\fR and \fIvarlist2\fR). During each iteration of
+the loop the variables of each \fIvarlist\fR are assigned consecutive values
+from the corresponding \fIlist\fR. Values in each \fIlist\fR are used in order
+from first to last, and each value is used exactly once. The total number of
+loop iterations is large enough to use up all the values from all the value
+lists. If a value list does not contain enough elements for each of its loop
+variables in each iteration, empty values are used for the missing elements.
+.PP
+The \fBbreak\fR and \fBcontinue\fR statements may be invoked inside
+\fIbody\fR, with the same effect as in the \fBfor\fR and \fBforeach\fR
+commands. In these cases the body does not complete normally and the result is
+not appended to the accumulator list.
+.SH EXAMPLES
+.PP
+Zip lists together:
+.PP
+.CS
+set list1 {a b c d}
+set list2 {1 2 3 4}
+set zipped [\fBlmap\fR a $list1 b $list2 {list $a $b}]
+# The value of zipped is "{a 1} {b 2} {c 3} {d 4}"
+.CE
+.PP
+Filter a list to remove odd values:
+.PP
+.CS
+set values {1 2 3 4 5 6 7 8}
+proc isEven {n} {expr {($n % 2) == 0}}
+set goodOnes [\fBlmap\fR x $values {expr {
+ [isEven $x] ? $x : [continue]
+}}]
+# The value of goodOnes is "2 4 6 8"
+.CE
+.PP
+Take a prefix from a list based on the contents of the list:
+.PP
+.CS
+set values {8 7 6 5 4 3 2 1}
+proc isGood {counter} {expr {$n > 3}}
+set prefix [\fBlmap\fR x $values {expr {
+ [isGood $x] ? $x : [break]
+}}]
+# The value of prefix is "8 7 6 5 4"
+.CE
+.SH "SEE ALSO"
+break(n), continue(n), for(n), foreach(n), while(n)
+.SH KEYWORDS
+foreach, iteration, list, loop, map
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/load.n b/doc/load.n
index c32cb65..2ab8f2e 100644
--- a/doc/load.n
+++ b/doc/load.n
@@ -4,18 +4,18 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH load n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
load \- Load machine code and initialize new commands
.SH SYNOPSIS
-\fBload \fIfileName\fR
+\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName\fR
.br
-\fBload \fIfileName packageName\fR
+\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName packageName\fR
.br
-\fBload \fIfileName packageName interp\fR
+\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName packageName interp\fR
.BE
.SH DESCRIPTION
.PP
@@ -104,6 +104,22 @@ Otherwise, the \fBload\fR command searches for a dynamically loaded
package by that name, and uses it if it is found. If several
different files have been \fBload\fRed with different versions of
the package, Tcl picks the file that was loaded first.
+.PP
+If \fB\-global\fR is specified preceding the filename, all symbols
+found in the shared library are exported for global use by other
+libraries. The option \fB\-lazy\fR delays the actual loading of
+symbols until their first actual use. The options may be abbreviated.
+The option \fB\-\-\fR indicates the end of the options, and should
+be used if you wish to use a filename which starts with \fB\-\fR
+and you provide a packageName to the \fBload\fR command.
+.PP
+On platforms which do not support the \fB\-global\fR or \fB\-lazy\fR
+options, the options still exist but have no effect. Note that use
+of the \fB\-global\fR or \fB\-lazy\fR option may lead to crashes
+in your application later (in case of symbol conflicts resp. missing
+symbols), which cannot be detected during the \fBload\fR. So, only
+use this when you know what you are doing, you will not get a nice
+error message when something is wrong with the loaded library.
.SH "PORTABILITY ISSUES"
.TP
\fBWindows\fR\0\0\0\0\0
diff --git a/doc/lrange.n b/doc/lrange.n
index 4f4816a..4e26a0f 100644
--- a/doc/lrange.n
+++ b/doc/lrange.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH lrange n 7.4 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/lrepeat.n b/doc/lrepeat.n
index 59a1edf..466339d 100644
--- a/doc/lrepeat.n
+++ b/doc/lrepeat.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH lrepeat n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/lreplace.n b/doc/lreplace.n
index 6e6c3ea..7bba543 100644
--- a/doc/lreplace.n
+++ b/doc/lreplace.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH lreplace n 7.4 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/lreverse.n b/doc/lreverse.n
index f52db9b..51a9e57 100644
--- a/doc/lreverse.n
+++ b/doc/lreverse.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH lreverse n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/lsearch.n b/doc/lsearch.n
index 7835352..44ebce4 100644
--- a/doc/lsearch.n
+++ b/doc/lsearch.n
@@ -7,8 +7,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH lsearch n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/lset.n b/doc/lset.n
index 805de16..954bd30 100755..100644
--- a/doc/lset.n
+++ b/doc/lset.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH lset n 8.4 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/lsort.n b/doc/lsort.n
index 312048e..48c62f0 100644
--- a/doc/lsort.n
+++ b/doc/lsort.n
@@ -7,8 +7,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH lsort n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/mathfunc.n b/doc/mathfunc.n
index 3da6d5a..84853d8 100644
--- a/doc/mathfunc.n
+++ b/doc/mathfunc.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH mathfunc n 8.5 Tcl "Tcl Mathematical Functions"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -299,3 +299,7 @@ Copyright (c) 1993 The Regents of the University of California.
Copyright (c) 1994-2000 Sun Microsystems Incorporated.
Copyright (c) 2005, 2006 by Kevin B. Kenny <kennykb@acm.org>.
.fi
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/mathop.n b/doc/mathop.n
index e359276..4c16d76 100644
--- a/doc/mathop.n
+++ b/doc/mathop.n
@@ -4,8 +4,8 @@
.\" See the file "license.terms" for information on usage and redistribution
.\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
.\"
-.so man.macros
.TH mathop n 8.5 Tcl "Tcl Mathematical Operator Commands"
+.so man.macros
.BS
.\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -126,14 +126,19 @@ will be an integer.
.TP
\fB%\fR \fInumber number\fR
.
-Returns the integral modulus of the first argument with respect to the second.
-Each \fInumber\fR must have an integral value. Note that Tcl defines this
-operation exactly even for negative numbers, so that the following equality
-holds true:
+Returns the integral modulus (i.e., remainder) of the first argument
+with respect to the second.
+Each \fInumber\fR must have an integral value.
+Also, the sign of the result will be the same as the sign of the second
+\fInumber\fR, which must not be zero.
.RS
.PP
+Note that Tcl defines this operation exactly even for negative numbers, so
+that the following command returns a true value (omitting the namespace for
+clarity):
+.PP
.CS
-(\fIx \fB/ \fIy\fR) \fB* \fIy \fB== \fIx \fB\-\fR (\fIx \fB% \fIy\fR)
+\fB==\fR [\fB*\fR [\fB/\fI x y\fR] \fIy\fR] [\fB\-\fI x\fR [\fB%\fI x y\fR]]
.CE
.RE
.TP
diff --git a/doc/memory.n b/doc/memory.n
index f82c5b4..5a1524b 100644
--- a/doc/memory.n
+++ b/doc/memory.n
@@ -3,8 +3,8 @@
'\" Copyright (c) 2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
-.so man.macros
.TH memory n 8.1 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
.SH NAME
memory \- Control Tcl memory debugging capabilities
diff --git a/doc/msgcat.n b/doc/msgcat.n
index d389757..bae6dbe 100644
--- a/doc/msgcat.n
+++ b/doc/msgcat.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
+.TH "msgcat" n 1.5 msgcat "Tcl Bundled Packages"
.so man.macros
-.TH "msgcat" n 1.4 msgcat "Tcl Bundled Packages"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -13,7 +13,7 @@ msgcat \- Tcl message catalog
.SH SYNOPSIS
\fBpackage require Tcl 8.5\fR
.sp
-\fBpackage require msgcat 1.4.2\fR
+\fBpackage require msgcat 1.5\fR
.sp
\fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR?
.sp
@@ -29,7 +29,13 @@ msgcat \- Tcl message catalog
.sp
\fB::msgcat::mcmset \fIlocale src-trans-list\fR
.sp
-\fB::msgcat::mcunknown \fIlocale src-string\fR
+.VS "TIP 404"
+\fB::msgcat::mcflset \fIsrc-string \fR?\fItranslate-string\fR?
+.sp
+\fB::msgcat::mcflmset \fIsrc-trans-list\fR
+.VE "TIP 404"
+.sp
+\fB::msgcat::mcunknown \fIlocale src-string\fR ?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
@@ -131,12 +137,33 @@ translate-string ...\fR?} \fB::msgcat::mcmset\fR can be significantly
faster than multiple invocations of \fB::msgcat::mcset\fR. The function
returns the number of translations set.
.TP
-\fB::msgcat::mcunknown \fIlocale src-string\fR
+\fB::msgcat::mcflset \fIsrc-string \fR?\fItranslate-string\fR?
+.VS "TIP 404"
+Sets the translation for \fIsrc-string\fR to \fItranslate-string\fR in the
+current namespace for the locale implied by the name of the message catalog
+being loaded via \fB::msgcat::mcload\fR. If \fItranslate-string\fR is not
+specified, \fIsrc-string\fR is used for both. The function returns
+\fItranslate-string\fR.
+.VE "TIP 404"
+.TP
+\fB::msgcat::mcflmset \fIsrc-trans-list\fR
+.VS "TIP 404"
+Sets the translation for multiple source strings in \fIsrc-trans-list\fR in
+the current namespace for the locale implied by the name of the message
+catalog being loaded via \fB::msgcat::mcload\fR. \fIsrc-trans-list\fR must
+have an even number of elements and is in the form {\fIsrc-string
+translate-string\fR ?\fIsrc-string translate-string ...\fR?}
+\fB::msgcat::mcflmset\fR can be significantly faster than multiple invocations
+of \fB::msgcat::mcflset\fR. The function returns the number of translations set.
+.VE "TIP 404"
+.TP
+\fB::msgcat::mcunknown \fIlocale src-string\fR ?\fIarg arg ...\fR?
.
This routine is called by \fB::msgcat::mc\fR in the case when
a translation for \fIsrc-string\fR is not defined in the
current locale. The default action is to return
-\fIsrc-string\fR. This procedure can be redefined by the
+\fIsrc-string\fR passed by format if there are any arguments. This
+procedure can be redefined by the
application, for example to log error messages for each unknown
string. The \fB::msgcat::mcunknown\fR procedure is invoked at the
same stack context as the call to \fB::msgcat::mc\fR. The return value
@@ -175,11 +202,14 @@ to extract its parts. The initial locale is then set by calling
language[_country][_modifier]
.CE
.PP
-On Windows, if none of those environment variables is set, msgcat will
-attempt to extract locale information from the
-registry. If all these attempts to discover an initial locale
-from the user's environment fail, msgcat defaults to an initial
-locale of
+On Windows and Cygwin, if none of those environment variables is set,
+msgcat will attempt to extract locale information from the registry.
+From Windows Vista on, the RFC4747 locale name "lang-script-country-options"
+is transformed to the locale as "lang_country_script" (Example:
+sr-Latn-CS -> sr_cs_latin). For Windows XP, the language id is
+transformed analoguously (Example: 0c1a -> sr_yu_cyrillic).
+If all these attempts to discover an initial locale from the user's
+environment fail, msgcat defaults to an initial locale of
.QW C .
.PP
When a locale is specified by the user, a
@@ -283,15 +313,15 @@ cause peculiar behavior, such as marking the message file as
.QW hidden
on Unix file systems.
.IP [3]
-The file contains a series of calls to \fBmcset\fR and
-\fBmcmset\fR, setting the necessary translation strings
+The file contains a series of calls to \fBmcflset\fR and
+\fBmcflmset\fR, setting the necessary translation strings
for the language, likely enclosed in a \fBnamespace eval\fR
so that all source strings are tied to the namespace of
the package. For example, a short \fBes.msg\fR might contain:
.PP
.CS
namespace eval ::mypackage {
- \fB::msgcat::mcset\fR es "Free Beer!" "Cerveza Gracias!"
+ \fB::msgcat::mcflset\fR "Free Beer!" "Cerveza Gracias!"
}
.CE
.SH "RECOMMENDED MESSAGE SETUP FOR PACKAGES"
diff --git a/doc/my.n b/doc/my.n
index b6a3a29..b91bc9a0 100644
--- a/doc/my.n
+++ b/doc/my.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH my n 0.1 TclOO "TclOO Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -31,7 +31,7 @@ Each object has its own \fBmy\fR command, contained in its instance namespace.
.SH EXAMPLES
.PP
This example shows basic use of \fBmy\fR to use the \fBvariables\fR method of
-the \fBoo::object\fR class, which is not publically visible by default:
+the \fBoo::object\fR class, which is not publicly visible by default:
.PP
.CS
oo::class create c {
diff --git a/doc/namespace.n b/doc/namespace.n
index a32c2f3..1f4e85f 100644
--- a/doc/namespace.n
+++ b/doc/namespace.n
@@ -7,8 +7,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH namespace n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -287,7 +287,7 @@ This command is the complement of the \fBnamespace qualifiers\fR command.
It does not check whether the namespace names are, in fact,
the names of currently defined namespaces.
.TP
-\fBnamespace upvar\fR \fInamespace\fR ?\fIotherVar myVar \fR...
+\fBnamespace upvar\fR \fInamespace\fR ?\fIotherVar myVar \fR...?
.
This command arranges for zero or more local variables in the current
procedure to refer to variables in \fInamespace\fR. The namespace name is
@@ -778,7 +778,10 @@ When non-empty, this option supplies a dictionary that provides a
mapping from subcommand names to a list of prefix words to substitute
in place of the ensemble command and subcommand words (in a manner
similar to an alias created with \fBinterp alias\fR; the words are not
-reparsed after substitution). When this option is empty, the mapping
+reparsed after substitution); if the first word of any target is not
+fully qualified when set, it is assumed to be relative to the
+\fIcurrent\fR namespace and changed to be exactly that (that is, it is
+always fully qualified when read). When this option is empty, the mapping
will be from the local name of the subcommand to its fully-qualified
name. Note that when this option is non-empty and the
\fB\-subcommands\fR option is empty, the ensemble subcommand names
diff --git a/doc/next.n b/doc/next.n
index 8eb2ba6..7dacac2 100644
--- a/doc/next.n
+++ b/doc/next.n
@@ -4,12 +4,12 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH next n 0.1 TclOO "TclOO Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-next \- invoke superclass method implementations
+next, nextto \- invoke superclass method implementations
.SH SYNOPSIS
.nf
package require TclOO
@@ -62,14 +62,14 @@ The method chain is cached for future use.
When constructing the method chain, method implementations are searched for in
the following order:
.IP [1]
-In the object.
-.IP [2]
In the classes mixed into the object, in class traversal order. The list of
mixins is checked in natural order.
-.IP [3]
+.IP [2]
In the classes mixed into the classes of the object, with sources of mixing in
being searched in class traversal order. Within each class, the list of mixins
is processed in natural order.
+.IP [3]
+In the object itself.
.IP [4]
In the object's class.
.IP [5]
@@ -77,12 +77,15 @@ In the superclasses of the class, following each superclass in a depth-first
fashion in the natural order of the superclass list.
.PP
Any particular method implementation always comes as \fIlate\fR in the
-resulting list of implementations as possible.
+resulting list of implementations as possible; this means that if some class,
+A, is both mixed into a class, B, and is also a superclass of B, the instances
+of B will always treat A as a superclass from the perspective of inheritance.
+This is true even when the multiple inheritance is processed indirectly.
.SS FILTERS
.PP
When an object has a list of filter names set upon it, or is an instance of a
class (or has mixed in a class) that has a list of filter names set upon it,
-before every invokation of any method the filters are processed. Filter
+before every invocation of any method the filters are processed. Filter
implementations are found in class traversal order, as are the lists of filter
names (each of which is traversed in natural list order). Explicitly invoking
a method used as a filter will cause that method to be invoked twice, once as
@@ -93,7 +96,7 @@ forward to the proper implementation of the method (which it does by invoking
the \fBnext\fR command as filters are inserted into the front of the method
call chain) and is responsible for returning the result of \fBnext\fR.
.PP
-Filters are not invoked when processing an invokation of the \fBunknown\fR
+Filters are not invoked when processing an invocation of the \fBunknown\fR
method because of a failure to locate a method implementation, or when
invoking either constructors or destructors.
.SH EXAMPLES
@@ -135,7 +138,7 @@ in the superclass, args = pureSynthesis
after chaining from subclass
before chaining from subclass, args =
in the superclass, args = a b
-in the superclassm args = pureSynthesis
+in the superclass, args = pureSynthesis
after chaining from subclass
.CE
.PP
@@ -165,7 +168,7 @@ oo::class create cache {
method flushCache {} {
my variable ValueCache
unset ValueCache
- \fI# Skip the cacheing\fR
+ \fI# Skip the caching\fR
return -level 2 ""
}
}
diff --git a/doc/object.n b/doc/object.n
index 0640580..df657a9 100644
--- a/doc/object.n
+++ b/doc/object.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH object n 0.1 TclOO "TclOO Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -40,7 +40,7 @@ current namespace whenever a method of the object is invoked (including a
method of the class of the object). When the object is destroyed, its instance
namespace is deleted. The instance namespace contains the object's \fBmy\fR
command, which may be used to invoke non-exported methods of the object or to
-create a reference to the object for the purpose of invokation which persists
+create a reference to the object for the purpose of invocation which persists
across renamings of the object.
.SS CONSTRUCTOR
The \fBoo::object\fR class does not define an explicit constructor.
@@ -65,14 +65,19 @@ This method concatenates the arguments, \fIarg\fR, as if with \fBconcat\fR,
and then evaluates the resulting script in the namespace that is uniquely
associated with \fIobj\fR, returning the result of the evaluation.
.TP
-\fIobj \fBunknown \fImethodName\fR ?\fIarg ...\fR?
+\fIobj \fBunknown ?\fImethodName\fR? ?\fIarg ...\fR?
.
This method is called when an attempt to invoke the method \fImethodName\fR on
object \fIobj\fR fails. The arguments that the user supplied to the method are
-given as \fIarg\fR argments. The default implementation (i.e. the one defined
-by the \fBoo::object\fR class) generates a suitable error, detailing what
-methods the object supports given whether the object was invoked by its public
-name or through the \fBmy\fR command.
+given as \fIarg\fR arguments.
+.VS
+If \fImethodName\fR is absent, the object was invoked with no method name at
+all (or any other arguments).
+.VE
+The default implementation (i.e., the one defined by the \fBoo::object\fR
+class) generates a suitable error, detailing what methods the object supports
+given whether the object was invoked by its public name or through the
+\fBmy\fR command.
.TP
\fIobj \fBvariable \fR?\fIvarName ...\fR?
.
@@ -86,6 +91,16 @@ must not have any namespace separators in it. The result is the empty string.
.
This method returns the globally qualified name of the variable \fIvarName\fR
in the unique namespace for the object \fIobj\fR.
+.TP
+\fIobj \fB<cloned> \fIsourceObjectName\fR
+.VS
+This method is used by the \fBoo::object\fR command to copy the state of one
+object to another. It is responsible for copying the procedures and variables
+of the namespace of the source object (\fIsourceObjectName\fR) to the current
+object. It does not copy any other types of commands or any traces on the
+variables; that can be added if desired by overriding this method in a
+subclass.
+.VE
.SH EXAMPLES
.PP
This example demonstrates basic use of an object.
diff --git a/doc/open.n b/doc/open.n
index d4842f2..0b1b83f 100644
--- a/doc/open.n
+++ b/doc/open.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH open n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/package.n b/doc/package.n
index 6cf8991..07a3d47 100644
--- a/doc/package.n
+++ b/doc/package.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH package n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/packagens.n b/doc/packagens.n
index 30617a3..61e7eca 100644
--- a/doc/packagens.n
+++ b/doc/packagens.n
@@ -2,8 +2,8 @@
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
-.so man.macros
.TH pkg::create n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/pid.n b/doc/pid.n
index 97a42a7..a4df2f3 100644
--- a/doc/pid.n
+++ b/doc/pid.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH pid n 7.0 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/pkgMkIndex.n b/doc/pkgMkIndex.n
index 2753208..c2f23ed 100644
--- a/doc/pkgMkIndex.n
+++ b/doc/pkgMkIndex.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH pkg_mkIndex n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/platform.n b/doc/platform.n
index 053448d..6abc289 100644
--- a/doc/platform.n
+++ b/doc/platform.n
@@ -4,15 +4,15 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH "platform" n 1.0.4 platform "Tcl Bundled Packages"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
platform \- System identification support code and utilities
.SH SYNOPSIS
.nf
-\fBpackage require platform ?1.0.4?\fR
+\fBpackage require platform ?1.0.10?\fR
.sp
\fBplatform::generic\fR
\fBplatform::identify\fR
@@ -45,6 +45,7 @@ architecture a Tcl program is running on.
.SH COMMANDS
.TP
\fBplatform::identify\fR
+.
This command returns an identifier describing the platform the Tcl
core is running on. The returned identifier has the general format
\fIOS\fR-\fICPU\fR. The \fIOS\fR part of the identifier may contain
@@ -53,14 +54,33 @@ may contain dashes as well. The \fICPU\fR part will not contain
dashes, making the preceding dash the last dash in the result.
.TP
\fBplatform::generic\fR
+.
This command returns a simplified identifier describing the platform
the Tcl core is running on. In contrast to \fBplatform::identify\fR it
leaves out details like kernel version, libc version, etc. The
returned identifier has the general format \fIOS\fR-\fICPU\fR.
.TP
-\fBplatform::patterns \fIidentifier\fR
+\fBplatform::patterns \fIidentifier\fR
+.
This command takes an identifier as returned by
\fBplatform::identify\fR and returns a list of identifiers describing
compatible architectures.
+.SH EXAMPLE
+.PP
+This can be used to allow an application to be shipped with multiple builds of
+a shared library, so that the same package works on many versions of an
+operating system. For example:
+.PP
+.CS
+\fBpackage require platform\fR
+# Assume that app script is .../theapp/bin/theapp.tcl
+set binDir [file dirname [file normalize [info script]]]
+set libDir [file join $binDir .. lib]
+set platLibDir [file join $libDir [\fBplatform::identify\fR]]
+load [file join $platLibDir support[info sharedlibextension]]
+.CE
.SH KEYWORDS
operating system, cpu architecture, platform, architecture
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/platform_shell.n b/doc/platform_shell.n
index eef4d4e..64a2e46 100644
--- a/doc/platform_shell.n
+++ b/doc/platform_shell.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH "platform::shell" n 1.1.4 platform::shell "Tcl Bundled Packages"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/prefix.n b/doc/prefix.n
index eb79996..344ade7 100644
--- a/doc/prefix.n
+++ b/doc/prefix.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH prefix n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/proc.n b/doc/proc.n
index bd5df09..632485e 100644
--- a/doc/proc.n
+++ b/doc/proc.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH proc n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -53,7 +53,7 @@ error).
There is one special case to permit procedures with
variable numbers of arguments. If the last formal argument has the name
\fBargs\fR, then a call to the procedure may contain more actual arguments
-than the procedure has formals. In this case, all of the actual arguments
+than the procedure has formal arguments. In this case, all of the actual arguments
starting at the one that would be assigned to \fBargs\fR are combined into
a list (as if the \fBlist\fR command had been used); this combined value
is assigned to the local variable \fBargs\fR.
@@ -66,7 +66,7 @@ Other variables can only be accessed by invoking one of the \fBglobal\fR,
\fBvariable\fR, \fBupvar\fR or \fBnamespace upvar\fR commands.
The current namespace when \fIbody\fR is executed will be the
namespace that the procedure's name exists in, which will be the
-namespace that itwas created in unless it has been changed with
+namespace that it was created in unless it has been changed with
\fBrename\fR.
'\" We may change this! It makes [variable] unstable when renamed and is
'\" frankly pretty crazy, but doing it right is harder than it looks.
diff --git a/doc/puts.n b/doc/puts.n
index 4a53d44..01ca122 100644
--- a/doc/puts.n
+++ b/doc/puts.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH puts n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/pwd.n b/doc/pwd.n
index 65fed84..31d378f 100644
--- a/doc/pwd.n
+++ b/doc/pwd.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH pwd n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/re_syntax.n b/doc/re_syntax.n
index 8701641..46a180d 100644
--- a/doc/re_syntax.n
+++ b/doc/re_syntax.n
@@ -6,6 +6,8 @@
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.so man.macros
+.ie '\w'o''\w'\C'^o''' .ds qo \C'^o'
+.el .ds qo u
.TH re_syntax n "8.1" Tcl "Tcl Built-In Commands"
.BS
.SH NAME
@@ -176,7 +178,7 @@ endpoint, so e.g.
.QW \fBa\-c\-e\fR
is illegal. Ranges in Tcl always use the
Unicode collating sequence, but other programs may use other collating
-sequences and this can be a source of incompatability between programs.
+sequences and this can be a source of incompatibility between programs.
.PP
To include a literal \fB]\fR or \fB\-\fR in the list, the simplest
method is to enclose it in \fB[.\fR and \fB.]\fR to make it a
@@ -221,7 +223,8 @@ A character producing white space in displayed text.
.IP \fBpunct\fR 8
A punctuation character.
.IP \fBgraph\fR 8
-A character with a visible representation (includes both alnum and punct).
+A character with a visible representation (includes both \fBalnum\fR
+and \fBpunct\fR).
.IP \fBcntrl\fR 8
A control character.
.PP
@@ -290,12 +293,12 @@ treatment is as if the enclosing delimiters were
.QW \fB[.\fR \&
and
.QW \fB.]\fR .)
-For example, if \fBo\fR and \fB\N'244'\fR are the members of an
+For example, if \fBo\fR and \fB\*(qo\fR are the members of an
equivalence class, then
.QW \fB[[=o=]]\fR ,
-.QW \fB[[=\N'244'=]]\fR ,
+.QW \fB[[=\*(qo=]]\fR ,
and
-.QW \fB[o\N'244']\fR \&
+.QW \fB[o\*(qo]\fR \&
are all synonymous. An equivalence class may not be an endpoint of a range.
.RS
.PP
@@ -359,39 +362,42 @@ horizontal tab, as in C
.TP
\fB\eu\fIwxyz\fR
.
-(where \fIwxyz\fR is exactly four hexadecimal digits) the Unicode
+(where \fIwxyz\fR is one up to four hexadecimal digits) the Unicode
character \fBU+\fIwxyz\fR in the local byte ordering
.TP
\fB\eU\fIstuvwxyz\fR
.
-(where \fIstuvwxyz\fR is exactly eight hexadecimal digits) reserved
-for a somewhat-hypothetical Unicode extension to 32 bits
+(where \fIstuvwxyz\fR is one up to eight hexadecimal digits) reserved
+for a Unicode extension up to 21 bits. The digits are parsed until the
+first non-hexadecimal character is encountered, the maximun of eight
+hexadecimal digits are reached, or an overflow would occur in the maximum
+value of \fBU+\fI10ffff\fR.
.TP
\fB\ev\fR
.
vertical tab, as in C are all available.
.TP
-\fB\ex\fIhhh\fR
+\fB\ex\fIhh\fR
.
-(where \fIhhh\fR is any sequence of hexadecimal digits) the character
-whose hexadecimal value is \fB0x\fIhhh\fR (a single character no
-matter how many hexadecimal digits are used).
+(where \fIhh\fR is one or two hexadecimal digits) the character
+whose hexadecimal value is \fB0x\fIhh\fR.
.TP
\fB\e0\fR
.
the character whose value is \fB0\fR
.TP
+\fB\e\fIxyz\fR
+.
+(where \fIxyz\fR is exactly three octal digits, and is not a \fIback
+reference\fR (see below)) the character whose octal value is
+\fB0\fIxyz\fR. The first digit must be in the range 0-3, otherwise
+the two-digit form is assumed.
+.TP
\fB\e\fIxy\fR
.
(where \fIxy\fR is exactly two octal digits, and is not a \fIback
reference\fR (see below)) the character whose octal value is
\fB0\fIxy\fR
-.TP
-\fB\e\fIxyz\fR
-.
-(where \fIxyz\fR is exactly three octal digits, and is not a back
-reference (see below)) the character whose octal value is
-\fB0\fIxyz\fR
.RE
.PP
Hexadecimal digits are
diff --git a/doc/read.n b/doc/read.n
index 007c0ac..87aa897 100644
--- a/doc/read.n
+++ b/doc/read.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH read n 8.1 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/refchan.n b/doc/refchan.n
index a51c3d7..2232d50 100644
--- a/doc/refchan.n
+++ b/doc/refchan.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH refchan n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
.\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/regexp.n b/doc/regexp.n
index 5e857f8..17bf564 100644
--- a/doc/regexp.n
+++ b/doc/regexp.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH regexp n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/registry.n b/doc/registry.n
index 2e69b1e..001def9 100644
--- a/doc/registry.n
+++ b/doc/registry.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH registry n 1.1 registry "Tcl Bundled Packages"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/regsub.n b/doc/regsub.n
index fe473d9..ef4c289 100644
--- a/doc/regsub.n
+++ b/doc/regsub.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH regsub n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/rename.n b/doc/rename.n
index 77dc095..744bf5a 100644
--- a/doc/rename.n
+++ b/doc/rename.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH rename n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/return.n b/doc/return.n
index b59a93d..383ed8c 100644
--- a/doc/return.n
+++ b/doc/return.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH return n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -317,8 +317,8 @@ proc myReturn {args} {
}
.CE
.SH "SEE ALSO"
-break(n), catch(n), continue(n), dict(n), error(n), proc(n),
-source(n), tclvars(n), throw(n), try(n)
+break(n), catch(n), continue(n), dict(n), error(n), errorCode(n),
+errorInfo(n), proc(n), source(n), throw(n), try(n)
.SH KEYWORDS
break, catch, continue, error, exception, procedure, result, return
.\" Local Variables:
diff --git a/doc/safe.n b/doc/safe.n
index a5acb02..76184a5 100644
--- a/doc/safe.n
+++ b/doc/safe.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH "Safe Tcl" n 8.0 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -67,7 +67,7 @@ The following commands are provided in the master interpreter:
\fB::safe::interpCreate\fR ?\fIslave\fR? ?\fIoptions...\fR?
Creates a safe interpreter, installs the aliases described in the section
\fBALIASES\fR and initializes the auto-loading and package mechanism as
-specified by the supplied \fBoptions\fR.
+specified by the supplied \fIoptions\fR.
See the \fBOPTIONS\fR section below for a description of the
optional arguments.
If the \fIslave\fR argument is omitted, a name will be generated.
@@ -293,9 +293,9 @@ executing.
The only valid file names arguments
for the \fBsource\fR and \fBload\fR aliases provided to the slave
are path in the form of
-\fB[file join \fR\fItoken filename\fR\fB]\fR (i.e. when using the
-native file path formats: \fItoken\fR\fB/\fR\fIfilename\fR
-on Unix and \fItoken\fR\fB\e\fIfilename\fR on Windows),
+\fB[file join \fItoken filename\fB]\fR (i.e. when using the
+native file path formats: \fItoken\fB/\fIfilename\fR
+on Unix and \fItoken\fB\e\fIfilename\fR on Windows),
where \fItoken\fR is representing one of the directories
of the \fIaccessPath\fR list and \fIfilename\fR is
one file in that directory (no sub directories access are allowed).
diff --git a/doc/scan.n b/doc/scan.n
index cc5ed79..5b91449 100644
--- a/doc/scan.n
+++ b/doc/scan.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH scan n 8.4 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -99,7 +99,7 @@ The input substring must be an octal integer. It is read in and the
integer value is stored in the variable,
truncated as required by the size modifier value.
.TP
-\fBx\fR
+\fBx\fR or \fBX\fR
.
The input substring must be a hexadecimal integer.
It is read in and the integer value is stored in the variable,
@@ -140,7 +140,7 @@ substring may be a white-space character.
The input substring consists of all the characters up to the next
white-space character; the characters are copied to the variable.
.TP
-\fBe\fR or \fBf\fR or \fBg\fR
+\fBe\fR or \fBf\fR or \fBg\fR or \fBE\fR or \fBG\fR
.
The input substring must be a floating-point number consisting
of an optional sign, a string of decimal digits possibly
diff --git a/doc/seek.n b/doc/seek.n
index 996a7f2..02c5341 100644
--- a/doc/seek.n
+++ b/doc/seek.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH seek n 8.1 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -49,7 +49,7 @@ position after the end of file.
The \fIorigin\fR argument defaults to \fBstart\fR.
.PP
The command flushes all buffered output for the channel before the command
-returns, even if the channel is in nonblocking mode.
+returns, even if the channel is in non-blocking mode.
It also discards any buffered and unread input.
This command returns an empty string.
An error occurs if this command is applied to channels whose underlying
@@ -86,3 +86,7 @@ close $f
file(n), open(n), close(n), gets(n), tell(n), Tcl_StandardChannels(3)
.SH KEYWORDS
access position, file, seek
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/self.n b/doc/self.n
index 348c38f..0ad5428 100644
--- a/doc/self.n
+++ b/doc/self.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH self n 0.1 TclOO "TclOO Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -91,7 +91,7 @@ method call chain; the first element is the name of the class or object that
declares the next part of the call chain, and the second element is the name
of the method (with the strings \fB<constructor>\fR and \fB<destructor>\fR
indicating constructors and destructors respectively). If invoked from a
-method that is at the end of a call chain, this subcommand returns the emtpy
+method that is at the end of a call chain, this subcommand returns the empty
string.
.TP
\fBself object\fR
diff --git a/doc/set.n b/doc/set.n
index 32a788e..545b15f 100644
--- a/doc/set.n
+++ b/doc/set.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH set n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/socket.n b/doc/socket.n
index e2c4759..b7a4a45 100644
--- a/doc/socket.n
+++ b/doc/socket.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH socket n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -72,7 +72,8 @@ This option will cause the client socket to be connected
asynchronously. This means that the socket will be created immediately
but may not yet be connected to the server, when the call to
\fBsocket\fR returns.
-
+.RS
+.PP
When a \fBgets\fR or \fBflush\fR is done on the socket before the
connection attempt succeeds or fails, if the socket is in blocking
mode, the operation will wait until the connection is completed or
@@ -82,22 +83,20 @@ succeeds or fails, the operation returns immediately and
\fBfblocked\fR on the socket returns 1. Synchronous client sockets may
be switched (after they have connected) to operating in asynchronous
mode using:
-.RS
.PP
.CS
\fBchan configure \fIchan \fB\-blocking 0\fR
.CE
.PP
See the \fBchan configure\fR command for more details.
-
+.PP
The Tcl event loop should be running while an asynchronous connection
is in progress, because it may have to do several connection attempts
-in the background. Runnig the event loop also allows you to set up a
+in the background. Running the event loop also allows you to set up a
writable channel event on the socket to get notified when the
-asyncronous connection has succeeded or failed. See the \fBvwait\fR
-and the \fBchan\fR comands for more details on the event loop and
+asynchronous connection has succeeded or failed. See the \fBvwait\fR
+and the \fBchan\fR commands for more details on the event loop and
channel events.
-
.RE
.SH "SERVER SOCKETS"
.PP
@@ -157,6 +156,11 @@ This option gets the current error status of the given socket. This
is useful when you need to determine if an asynchronous connect
operation succeeded. If there was an error, the error message is
returned. If there was no error, an empty string is returned.
+.RS
+.PP
+Note that the error status is reset by the read operation; this mimics
+the underlying getsockopt(SO_ERROR) call.
+.RE
.TP
\fB\-sockname\fR
.
@@ -165,14 +169,15 @@ client connects to a server socket) this option returns a list of
three elements, the address, the host name and the port number for the
socket. If the host name cannot be computed, the second element is
identical to the address, the first element of the list.
-
+.RS
+.PP
For server sockets this option returns a list of a multiple of three
elements each group of which have the same meaning as described
above. The list contains more than one group when the server socket
was created without \fB\-myaddr\fR or with the argument to
\fB\-myaddr\fR being a domain name that resolves multiple IP addresses
that are local to the invoking host.
-
+.RE
.TP
\fB\-peername\fR
.
diff --git a/doc/source.n b/doc/source.n
index 57a9fa2..9f488c5 100644
--- a/doc/source.n
+++ b/doc/source.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH source n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/split.n b/doc/split.n
index e3259df..f1c66d0 100644
--- a/doc/split.n
+++ b/doc/split.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH split n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/string.n b/doc/string.n
index d960b71..163abdd 100644
--- a/doc/string.n
+++ b/doc/string.n
@@ -5,8 +5,8 @@
.\" See the file "license.terms" for information on usage and redistribution
.\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
.\"
-.so man.macros
.TH string n 8.1 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
.\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -19,25 +19,7 @@ string \- Manipulate strings
Performs one of several string operations, depending on \fIoption\fR.
The legal \fIoption\fRs (which may be abbreviated) are:
.TP
-\fBstring bytelength \fIstring\fR
-.
-Returns a decimal string giving the number of bytes used to represent
-\fIstring\fR in memory. Because UTF\-8 uses one to three bytes to
-represent Unicode characters, the byte length will not be the same as
-the character length in general. The cases where a script cares about
-the byte length are rare. In almost all cases, you should use the
-\fBstring length\fR operation (including determining the length of a
-Tcl ByteArray object). Refer to the \fBTcl_NumUtfChars\fR manual
-entry for more details on the UTF\-8 representation.
-.RS
-.PP
-\fICompatibility note:\fR it is likely that this subcommand will be
-withdrawn in a future version of Tcl. It is better to use the
-\fBencoding convertto\fR command to convert a string to a known
-encoding and then apply \fBstring length\fR to that.
-.RE
-.TP
-\fBstring compare\fR ?\fB\-nocase\fR? ?\fB\-length int\fR? \fIstring1 string2\fR
+\fBstring compare\fR ?\fB\-nocase\fR? ?\fB\-length\fI length\fR? \fIstring1 string2\fR
.
Perform a character-by-character comparison of strings \fIstring1\fR
and \fIstring2\fR. Returns \-1, 0, or 1, depending on whether
@@ -47,7 +29,7 @@ first \fIlength\fR characters are used in the comparison. If
\fB\-length\fR is negative, it is ignored. If \fB\-nocase\fR is
specified, then the strings are compared in a case-insensitive manner.
.TP
-\fBstring equal\fR ?\fB\-nocase\fR? ?\fB\-length int\fR? \fIstring1 string2\fR
+\fBstring equal\fR ?\fB\-nocase\fR? ?\fB\-length\fI length\fR? \fIstring1 string2\fR
.
Perform a character-by-character comparison of strings \fIstring1\fR
and \fIstring2\fR. Returns 1 if \fIstring1\fR and \fIstring2\fR are
@@ -121,6 +103,12 @@ outside of the [0\-9] range.
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.
+.IP \fBentier\fR 12
+.VS 8.6
+Any of the valid string formats for an integer value of arbitrary size
+in Tcl, with optional surrounding whitespace. The formats accepted are
+exactly those accepted by the C routine \fBTcl_GetBignumFromObj\fR.
+.VE
.IP \fBfalse\fR 12
Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is
false.
@@ -143,7 +131,8 @@ Any Unicode printing character, including space.
.IP \fBpunct\fR 12
Any Unicode punctuation character.
.IP \fBspace\fR 12
-Any Unicode space character.
+Any Unicode whitespace character, zero width space (U+200b),
+word joiner (U+2060) and zero width no-break space (U+feff) (=BOM).
.IP \fBtrue\fR 12
Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is
true.
@@ -192,9 +181,9 @@ will return \fB1\fR.
.
Returns a decimal string giving the number of characters in
\fIstring\fR. Note that this is not necessarily the same as the
-number of bytes used to store the string. If the object is a
-ByteArray object (such as those returned from reading a binary encoded
-channel), then this will return the actual byte length of the object.
+number of bytes used to store the string. If the value is a
+byte array value (such as those returned from reading a binary encoded
+channel), then this will return the actual byte length of the value.
.TP
\fBstring map\fR ?\fB\-nocase\fR? \fImapping string\fR
.
@@ -329,22 +318,67 @@ specified using the forms described in \fBSTRING INDICES\fR.
.
Returns a value equal to \fIstring\fR except that any leading or
trailing characters present in the string given by \fIchars\fR are removed. If
-\fIchars\fR is not specified then white space is removed (spaces,
-tabs, newlines, and carriage returns).
+\fIchars\fR is not specified then white space is removed (any character
+for which \fBstring is space\fR returns 1, and "\0").
.TP
\fBstring trimleft \fIstring\fR ?\fIchars\fR?
.
Returns a value equal to \fIstring\fR except that any leading
characters present in the string given by \fIchars\fR are removed. If
-\fIchars\fR is not specified then white space is removed (spaces,
-tabs, newlines, and carriage returns).
+\fIchars\fR is not specified then white space is removed (any character
+for which \fBstring is space\fR returns 1, and "\0").
.TP
\fBstring trimright \fIstring\fR ?\fIchars\fR?
.
Returns a value equal to \fIstring\fR except that any trailing
characters present in the string given by \fIchars\fR are removed. If
-\fIchars\fR is not specified then white space is removed (spaces,
-tabs, newlines, and carriage returns).
+\fIchars\fR is not specified then white space is removed (any character
+for which \fBstring is space\fR returns 1, and "\0").
+.SS "OBSOLETE SUBCOMMANDS"
+.PP
+These subcommands are currently supported, but are likely to go away in a
+future release as their functionality is either virtually never used or highly
+misleading.
+.TP
+\fBstring bytelength \fIstring\fR
+.
+Returns a decimal string giving the number of bytes used to represent
+\fIstring\fR in memory when encoded as Tcl's internal modified UTF\-8;
+Tcl may use other encodings for \fIstring\fR as well, and does not
+guarantee to only use a single encoding for a particular \fIstring\fR.
+Because UTF\-8 uses a variable number of bytes to represent Unicode
+characters, the byte length will not be the same as the character
+length in general. The cases where a script cares about the byte
+length are rare.
+.RS
+.PP
+In almost all cases, you should use the
+\fBstring length\fR operation (including determining the length of a
+Tcl byte array value). Refer to the \fBTcl_NumUtfChars\fR manual
+entry for more details on the UTF\-8 representation.
+.PP
+Formally, the \fBstring bytelength\fR operation returns the content of
+the \fIlength\fR field of the \fBTcl_Obj\fR structure, after calling
+\fBTcl_GetString\fR to ensure that the \fIbytes\fR field is populated.
+This is highly unlikely to be useful to Tcl scripts, as Tcl's internal
+encoding is not strict UTF\-8, but rather a modified CESU\-8 with a
+denormalized NUL (identical to that used in a number of places by
+Java's serialization mechanism) to enable basic processing with
+non-Unicode-aware C functions. As this representation should only
+ever be used by Tcl's implementation, the number of bytes used to
+store the representation is of very low value (except to C extension
+code, which has direct access for the purpose of memory management,
+etc.)
+.PP
+\fICompatibility note:\fR it is likely that this subcommand will be
+withdrawn in a future version of Tcl. It is better to use the
+\fBencoding convertto\fR command to convert a string to a known
+encoding and then apply \fBstring length\fR to that.
+.PP
+.CS
+\fBstring length\fR [encoding convertto utf-8 $theString]
+.CE
+.RE
.TP
\fBstring wordend \fIstring charIndex\fR
.
diff --git a/doc/subst.n b/doc/subst.n
index aba2bc9..990b9d3 100644
--- a/doc/subst.n
+++ b/doc/subst.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH subst n 7.4 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/switch.n b/doc/switch.n
index acde6cb..6e27f56 100644
--- a/doc/switch.n
+++ b/doc/switch.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH switch n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/tailcall.n b/doc/tailcall.n
index 6a88aca..926c608 100644
--- a/doc/tailcall.n
+++ b/doc/tailcall.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH tailcall n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/tclsh.1 b/doc/tclsh.1
index 2819408..6ed5eb6 100644
--- a/doc/tclsh.1
+++ b/doc/tclsh.1
@@ -5,14 +5,14 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH tclsh 1 "" Tcl "Tcl Applications"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
tclsh \- Simple shell containing Tcl interpreter
.SH SYNOPSIS
-\fBtclsh\fR ?-encoding \fIname\fR? ?\fIfileName arg arg ...\fR?
+\fBtclsh\fR ?\fB\-encoding \fIname\fR? ?\fIfileName arg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
@@ -102,7 +102,9 @@ but also the disadvantage of making it harder to write scripts that
start up uniformly across different versions of Tcl.
.SH "VARIABLES"
.PP
-\fBTclsh\fR sets the following Tcl variables:
+\fBTclsh\fR sets the following global Tcl variables in addition to those
+created by the Tcl library itself (such as \fBenv\fR, which maps
+environment variables such as \fBPATH\fR into Tcl):
.TP 15
\fBargc\fR
.
@@ -129,7 +131,7 @@ device), 0 otherwise.
When \fBtclsh\fR is invoked interactively it normally prompts for each
command with
.QW "\fB% \fR" .
-You can change the prompt by setting the
+You can change the prompt by setting the global
variables \fBtcl_prompt1\fR and \fBtcl_prompt2\fR. If variable
\fBtcl_prompt1\fR exists then it must consist of a Tcl script
to output a prompt; instead of outputting a prompt \fBtclsh\fR
@@ -142,6 +144,6 @@ incomplete commands.
.PP
See \fBTcl_StandardChannels\fR for more explanations.
.SH "SEE ALSO"
-encoding(n), fconfigure(n), tclvars(n)
+auto_path(n), encoding(n), env(n), fconfigure(n)
.SH KEYWORDS
application, argument, interpreter, prompt, script file, shell
diff --git a/doc/tcltest.n b/doc/tcltest.n
index 731bed7..8d2398b 100644
--- a/doc/tcltest.n
+++ b/doc/tcltest.n
@@ -8,8 +8,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH "tcltest" n 2.3 tcltest "Tcl Bundled Packages"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/tclvars.n b/doc/tclvars.n
index 3bd18e8..9d7a4ce 100644
--- a/doc/tclvars.n
+++ b/doc/tclvars.n
@@ -5,12 +5,12 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH tclvars n 8.0 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-argc, argv, argv0, auto_path, env, errorCode, errorInfo, tcl_interactive, tcl_library, tcl_nonwordchars, tcl_patchLevel, tcl_pkgPath, tcl_platform, tcl_precision, tcl_rcFileName, tcl_traceCompile, tcl_traceEval, tcl_wordchars, tcl_version \- Variables used by Tcl
+argc, argv, argv0, auto_path, env, errorCode, errorInfo, tcl_interactive, tcl_library, tcl_nonwordchars, tcl_patchLevel, tcl_pkgPath, tcl_platform, tcl_precision, tcl_rcFileName, tcl_traceCompile, tcl_traceExec, tcl_wordchars, tcl_version \- Variables used by Tcl
.BE
.SH DESCRIPTION
.PP
@@ -100,6 +100,17 @@ Tcl format, using
as the path separator, regardless of platform.
This variable is only used when initializing the \fBauto_path\fR variable.
.TP
+\fBenv(TCL_TZ)\fR, \fBenv(TZ)\fR
+.
+These specify the default timezone used for parsing and formatting times and
+dates in the \fBclock\fR command. On many platforms, the TZ environment
+variable is set up by the operating system.
+.TP
+\fBenv(LC_ALL)\fR, \fBenv(LC_MESSAGES)\fR, \fBenv(LANG)\fR
+.
+These environment variables are used by the \fBmsgcat\fR package to
+determine what locale to format messages using.
+.TP
\fBenv(TCL_INTERP_DEBUG_FRAME)\fR
.
If existing, it has the same effect as running \fBinterp debug\fR
diff --git a/doc/tell.n b/doc/tell.n
index 87e63b0..e8bf3af 100644
--- a/doc/tell.n
+++ b/doc/tell.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH tell n 8.1 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/throw.n b/doc/throw.n
index d49fb24..0d1df78 100644
--- a/doc/throw.n
+++ b/doc/throw.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH throw n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -40,7 +40,7 @@ The following produces an error that is identical to that produced by
\fBthrow\fR {ARITH DIVZERO {divide by zero}} {divide by zero}
.CE
.SH "SEE ALSO"
-catch(n), error(n), return(n), tclvars(n), try(n)
+catch(n), error(n), errorCode(n), errorInfo(n), return(n), try(n)
.SH "KEYWORDS"
error, exception
'\" Local Variables:
diff --git a/doc/time.n b/doc/time.n
index 52730a1..35b41c4 100644
--- a/doc/time.n
+++ b/doc/time.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH time n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/tm.n b/doc/tm.n
index ddfbac2..5602686 100644
--- a/doc/tm.n
+++ b/doc/tm.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH tm n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/trace.n b/doc/trace.n
index 940a1e9..4ae7e19 100644
--- a/doc/trace.n
+++ b/doc/trace.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH trace n "8.4" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -143,7 +143,7 @@ error will occur.
For \fBleave\fR and \fBleavestep\fR operations:
.PP
.CS
-\fIcommand command-string code result op\fR
+\fIcommandPrefix command-string code result op\fR
.CE
.PP
\fICommand-string\fR gives the complete current command being
diff --git a/doc/transchan.n b/doc/transchan.n
index e308e13..e00aa84 100644
--- a/doc/transchan.n
+++ b/doc/transchan.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH transchan n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/try.n b/doc/try.n
index 393fe5b..834ccc1 100644
--- a/doc/try.n
+++ b/doc/try.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH try n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -87,7 +87,7 @@ Handle different reasons for a file to not be openable for reading:
.PP
.CS
\fBtry\fR {
- set f [open /some/file/name]
+ set f [open /some/file/name w]
} \fBtrap\fR {POSIX EISDIR} {} {
puts "failed to open /some/file/name: it's a directory"
} \fBtrap\fR {POSIX ENOENT} {} {
diff --git a/doc/unknown.n b/doc/unknown.n
index fc2a5a1..cdfbe43 100644
--- a/doc/unknown.n
+++ b/doc/unknown.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH unknown n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/unload.n b/doc/unload.n
index 4c0b292..febd694 100644
--- a/doc/unload.n
+++ b/doc/unload.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH unload n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/unset.n b/doc/unset.n
index 64b334d..8b63959 100644
--- a/doc/unset.n
+++ b/doc/unset.n
@@ -6,8 +6,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH unset n 8.4 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/update.n b/doc/update.n
index 0c77c5f..875172a 100644
--- a/doc/update.n
+++ b/doc/update.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH update n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/uplevel.n b/doc/uplevel.n
index 6c8a957..a96f729 100644
--- a/doc/uplevel.n
+++ b/doc/uplevel.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH uplevel n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/upvar.n b/doc/upvar.n
index 60e5324..380a390 100644
--- a/doc/upvar.n
+++ b/doc/upvar.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH upvar n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/variable.n b/doc/variable.n
index 96263b6..7d58a02 100644
--- a/doc/variable.n
+++ b/doc/variable.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH variable n 8.0 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/vwait.n b/doc/vwait.n
index 38a8081..c9b51ab 100644
--- a/doc/vwait.n
+++ b/doc/vwait.n
@@ -4,8 +4,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH vwait n 8.0 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/while.n b/doc/while.n
index 5416e25..60275e8 100644
--- a/doc/while.n
+++ b/doc/while.n
@@ -5,8 +5,8 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH while n "" Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
diff --git a/doc/zlib.n b/doc/zlib.n
index 9fa83c6..b8d0ee5 100644
--- a/doc/zlib.n
+++ b/doc/zlib.n
@@ -1,11 +1,11 @@
'\"
-'\" Copyright (c) 2008 Donal K. Fellows
+'\" Copyright (c) 2008-2012 Donal K. Fellows
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-.so man.macros
.TH zlib n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -170,6 +170,13 @@ the
.QW "\fIoptions ...\fR"
to the \fBzlib push\fR command:
.TP
+\fB\-dictionary\fI binData\fR
+.VS "TIP 400"
+Sets the compression dictionary to use when working with compressing or
+decompressing the data to be \fIbinData\fR. Not valid for transformations that
+work with gzip-format data.
+.VE
+.TP
\fB\-header\fI dictionary\fR
.
Passes a description of the gzip header to create, in the same format that
@@ -179,15 +186,33 @@ Passes a description of the gzip header to create, in the same format that
.
How hard to compress the data. Must be an integer from 0 (uncompressed) to 9
(maximally compressed).
-'\".TP
-'\"\fB\-limit\fI readaheadLimit\fR
-'\".
-'\"The maximum number of bytes ahead to read.
-'\"\fITODO: not yet implemented!\fR
+.TP
+\fB\-limit\fI readaheadLimit\fR
+.
+The maximum number of bytes ahead to read when decompressing. This defaults to
+1, which ensures that data is always decompressed correctly, but may be
+increased to improve performance. This is more useful when the channel is
+non-blocking.
.PP
Both compressing and decompressing channel transformations add extra
-configuration options that may be accessed through \fBchan configure\fR. Each
-option is either a read-only or a write-only option. The options are:
+configuration options that may be accessed through \fBchan configure\fR. The
+options are:
+.TP
+\fB\-checksum\fI checksum\fR
+.
+This read-only option gets the current checksum for the uncompressed data that
+the compression engine has seen so far. It is valid for both compressing and
+decompressing transforms, but not for the raw inflate and deflate formats. The
+compression algorithm depends on what format is being produced or consumed.
+.TP
+\fB\-dictionary\fI binData\fR
+.VS "TIP 400"
+This read-write options gets or sets the compression dictionary to use when
+working with compressing or decompressing the data to be \fIbinData\fR. It is
+not valid for transformations that work with gzip-format data, and should not
+normally be set on compressing transformations other than at the point where
+the transformation is stacked.
+.VE
.TP
\fB\-flush\fI type\fR
.
@@ -198,62 +223,80 @@ expensive flush respectively. Flushing degrades the compression ratio, but
makes it easier for a decompressor to recover more of the file in the case of
data corruption.
.TP
-\fB\-checksum\fR
-.
-This read-only option, valid for both compressing and decompressing
-transforms, gets the current checksum for the uncompressed data that the
-compression engine has seen so far. The compression algorithm depends on what
-format is being produced or consumed.
-.TP
-\fB\-header\fR
+\fB\-header\fI dictionary\fR
.
This read-only option, only valid for decompressing transforms that are
processing gzip-format data, returns the dictionary describing the header read
off the data stream.
+.TP
+\fB\-limit\fI readaheadLimit\fR
+.
+This read-write option is used by decompressing channels to control the
+maximum number of bytes ahead to read from the underlying data source. This
+defaults to 1, which ensures that data is always decompressed correctly, but
+may be increased to improve performance. This is more useful when the channel
+is non-blocking.
.RE
.SS "STREAMING SUBCOMMAND"
.TP
-\fBzlib stream\fI mode\fR ?\fIlevel\fR?
+\fBzlib stream\fI mode\fR ?\fIoptions\fR?
.
Creates a streaming compression or decompression command based on the
\fImode\fR, and return the name of the command. For a description of how that
command works, see \fBSTREAMING INSTANCE COMMAND\fR below. The following modes
-are supported:
+and \fIoptions\fR are supported:
.RS
.TP
-\fBzlib stream compress\fR ?\fIlevel\fR?
+\fBzlib stream compress\fR ?\fB\-dictionary \fIbindata\fR? ?\fB\-level \fIlevel\fR?
.
The stream will be a compressing stream that produces zlib-format output,
using compression level \fIlevel\fR (if specified) which will be an integer
-from 0 to 9.
+from 0 to 9,
+.VS "TIP 400"
+and the compression dictionary \fIbindata\fR (if specified).
+.VE
.TP
-\fBzlib stream decompress\fR
+\fBzlib stream decompress\fR ?\fB\-dictionary \fIbindata\fR?
.
The stream will be a decompressing stream that takes zlib-format input and
produces uncompressed output.
+.VS "TIP 400"
+If \fIbindata\fR is supplied, it is a compression dictionary to use if
+required.
+.VE
.TP
-\fBzlib stream deflate\fR ?\fIlevel\fR?
+\fBzlib stream deflate\fR ?\fB\-dictionary \fIbindata\fR? ?\fB\-level \fIlevel\fR?
.
The stream will be a compressing stream that produces raw output, using
compression level \fIlevel\fR (if specified) which will be an integer from 0
-to 9.
+to 9,
+.VS "TIP 400"
+and the compression dictionary \fIbindata\fR (if specified). Note that
+the raw compressed data includes no metadata about what compression
+dictionary was used, if any; that is a feature of the zlib-format data.
+.VE
.TP
\fBzlib stream gunzip\fR
.
The stream will be a decompressing stream that takes gzip-format input and
produces uncompressed output.
.TP
-\fBzlib stream gzip\fR ?\fIlevel\fR?
+\fBzlib stream gzip\fR ?\fB\-header \fIheader\fR? ?\fB\-level \fIlevel\fR?
.
The stream will be a compressing stream that produces gzip-format output,
using compression level \fIlevel\fR (if specified) which will be an integer
-from 0 to 9.
-'\" TODO: Header dictionary!
+from 0 to 9, and the header descriptor dictionary \fIheader\fR (if specified;
+for keys see \fBzlib gzip\fR).
.TP
-\fBzlib stream inflate\fR
+\fBzlib stream inflate\fR ?\fB\-dictionary \fIbindata\fR?
.
The stream will be a decompressing stream that takes raw compressed input and
produces uncompressed output.
+.VS "TIP 400"
+If \fIbindata\fR is supplied, it is a compression dictionary to use. Note that
+there are no checks in place to determine whether the compression dictionary
+is correct.
+.VE
.RE
.SS "CHECKSUMMING SUBCOMMANDS"
.TP
@@ -276,10 +319,10 @@ the transformed data.
The full set of subcommands supported by a streaming instance command,
\fIstream\fR, is as follows:
.TP
-\fIstream \fBadd\fR ?\fIoption\fR? \fIdata\fR
+\fIstream \fBadd\fR ?\fIoption...\fR? \fIdata\fR
.
A short-cut for
-.QW "\fIstream \fBput \fIoption data\fR"
+.QW "\fIstream \fBput \fR?\fIoption...\fR? \fIdata\fR"
followed by
.QW "\fIstream \fBget\fR" .
.TP
@@ -317,15 +360,27 @@ A short-cut for
Return up to \fIcount\fR bytes from \fIstream\fR's internal buffers with the
transformation applied. If \fIcount\fR is omitted, the entire contents of the
buffers are returned.
+.
+\fIstream \fBheader\fR
+.
+Return the gzip header description dictionary extracted from the stream. Only
+supported for streams created with their \fImode\fR parameter set to
+\fBgunzip\fR.
.TP
-\fIstream \fBput\fR ?\fIoption\fR? \fIdata\fR
+\fIstream \fBput\fR ?\fIoption...\fR? \fIdata\fR
.
Append the contents of the binary string \fIdata\fR to \fIstream\fR's internal
-buffers while applying the transformation. If present, \fIoption\fR must be
-one of the following (or an unambiguous prefix) which are used to modify the
+buffers while applying the transformation. The following \fIoption\fRs are
+supported (or an unambiguous prefix of them), which are used to modify the
way in which the transformation is applied:
.RS
.TP
+\fB\-dictionary\fI binData\fR
+.VS "TIP 400"
+Sets the compression dictionary to use when working with compressing or
+decompressing the data to be \fIbinData\fR.
+.VE
+.TP
\fB\-finalize\fR
.
Mark the stream as finished, ensuring that all bytes have been wholly
@@ -333,12 +388,22 @@ compressed or decompressed. For gzip streams, this also ensures that the
footer is written to the stream. The stream will need to be reset before
having more data written to it after this, though data can still be read out
of the stream with the \fBget\fR subcommand.
+.RS
+.PP
+This option is mutually exclusive with the \fB\-flush\fR and \fB\-fullflush\fR
+options.
+.RE
.TP
\fB\-flush\fR
.
Ensure that a decompressor consuming the bytes that the current (compressing)
stream is producing will be able to produce all the bytes that have been
compressed so far, at some performance penalty.
+.RS
+.PP
+This option is mutually exclusive with the \fB\-finalize\fR and
+\fB\-fullflush\fR options.
+.RE
.TP
\fB\-fullflush\fR
.
@@ -346,6 +411,11 @@ Ensure that not only can a decompressor handle all the bytes produced so far
(as with \fB\-flush\fR above) but also that it can restart from this point if
it detects that the stream is partially corrupt. This incurs a substantial
performance penalty.
+.RS
+.PP
+This option is mutually exclusive with the \fB\-finalize\fR and \fB\-flush\fR
+options.
+.RE
.RE
.TP
\fIstream \fBreset\fR
@@ -384,7 +454,7 @@ $\fIstrm \fBclose\fR
.SH "SEE ALSO"
binary(n), chan(n), encoding(n), Tcl_ZlibDeflate(3), RFC1950 \- RFC1952
.SH "KEYWORDS"
-compress, decompress, deflate, gzip, inflate
+compress, decompress, deflate, gzip, inflate, zlib
'\" Local Variables:
'\" mode: nroff
'\" End:
diff --git a/generic/regc_color.c b/generic/regc_color.c
index b7a571c..f5d6dfd 100644
--- a/generic/regc_color.c
+++ b/generic/regc_color.c
@@ -254,7 +254,14 @@ newcolor(
* Oops, must allocate more.
*/
+ if (cm->max == MAX_COLOR) {
+ CERR(REG_ECOLORS);
+ return COLORLESS; /* too many colors */
+ }
n = cm->ncds * 2;
+ if (n < MAX_COLOR + 1) {
+ n = MAX_COLOR + 1;
+ }
if (cm->cd == cm->cdspace) {
newCd = (struct colordesc *) MALLOC(n * sizeof(struct colordesc));
if (newCd != NULL) {
diff --git a/generic/regc_lex.c b/generic/regc_lex.c
index f3a46da..132e757 100644
--- a/generic/regc_lex.c
+++ b/generic/regc_lex.c
@@ -742,6 +742,7 @@ lexescape(
struct vars *v)
{
chr c;
+ int i;
static const chr alert[] = {
CHR('a'), CHR('l'), CHR('e'), CHR('r'), CHR('t')
};
@@ -818,18 +819,23 @@ lexescape(
RETV(PLAIN, CHR('\t'));
break;
case CHR('u'):
- c = lexdigits(v, 16, 4, 4);
+ c = (uchr) lexdigits(v, 16, 1, 4);
if (ISERR()) {
FAILW(REG_EESCAPE);
}
RETV(PLAIN, c);
break;
case CHR('U'):
- c = lexdigits(v, 16, 8, 8);
+ i = lexdigits(v, 16, 1, 8);
if (ISERR()) {
FAILW(REG_EESCAPE);
}
- RETV(PLAIN, c);
+ if (i > 0xFFFF) {
+ /* TODO: output a Surrogate pair
+ */
+ i = 0xFFFD;
+ }
+ RETV(PLAIN, (uchr) i);
break;
case CHR('v'):
RETV(PLAIN, CHR('\v'));
@@ -844,7 +850,7 @@ lexescape(
break;
case CHR('x'):
NOTE(REG_UUNPORT);
- c = lexdigits(v, 16, 1, 255); /* REs >255 long outside spec */
+ c = (uchr) lexdigits(v, 16, 1, 2);
if (ISERR()) {
FAILW(REG_EESCAPE);
}
@@ -866,7 +872,7 @@ lexescape(
case CHR('9'):
save = v->now;
v->now--; /* put first digit back */
- c = lexdigits(v, 10, 1, 255); /* REs >255 long outside spec */
+ c = (uchr) lexdigits(v, 10, 1, 255); /* REs >255 long outside spec */
if (ISERR()) {
FAILW(REG_EESCAPE);
}
@@ -893,10 +899,15 @@ lexescape(
case CHR('0'):
NOTE(REG_UUNPORT);
v->now--; /* put first digit back */
- c = lexdigits(v, 8, 1, 3);
+ c = (uchr) lexdigits(v, 8, 1, 3);
if (ISERR()) {
FAILW(REG_EESCAPE);
}
+ if (c > 0xff) {
+ /* out of range, so we handled one digit too much */
+ v->now--;
+ c >>= 3;
+ }
RETV(PLAIN, c);
break;
default:
@@ -909,16 +920,16 @@ lexescape(
/*
- lexdigits - slurp up digits and return chr value
- ^ static chr lexdigits(struct vars *, int, int, int);
+ ^ static int lexdigits(struct vars *, int, int, int);
*/
-static chr /* chr value; errors signalled via ERR */
+static int /* chr value; errors signalled via ERR */
lexdigits(
struct vars *v,
int base,
int minlen,
int maxlen)
{
- uchr n; /* unsigned to avoid overflow misbehavior */
+ int n;
int len;
chr c;
int d;
@@ -926,6 +937,10 @@ lexdigits(
n = 0;
for (len = 0; len < maxlen && !ATEOS(); len++) {
+ if (n > 0x10fff) {
+ /* Stop when continuing would otherwise overflow */
+ break;
+ }
c = *v->now++;
switch (c) {
case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
@@ -958,7 +973,7 @@ lexdigits(
ERR(REG_EESCAPE);
}
- return (chr)n;
+ return n;
}
/*
diff --git a/generic/regc_locale.c b/generic/regc_locale.c
index 124dff4..0f8d1b2 100644
--- a/generic/regc_locale.c
+++ b/generic/regc_locale.c
@@ -118,7 +118,7 @@ static const struct cname {
* Unicode character-class tables.
*/
-typedef struct crange {
+typedef struct {
chr start;
chr end;
} crange;
@@ -134,109 +134,168 @@ typedef struct crange {
*/
static const crange alphaRangeTable[] = {
- {0x0041, 0x005a}, {0x0061, 0x007a}, {0x00c0, 0x00d6}, {0x00d8, 0x00f6},
- {0x00f8, 0x02c1}, {0x02c6, 0x02d1}, {0x02e0, 0x02e4}, {0x0370, 0x0374},
- {0x037a, 0x037d}, {0x0388, 0x038a}, {0x038e, 0x03a1}, {0x03a3, 0x03f5},
- {0x03f7, 0x0481}, {0x048a, 0x0527}, {0x0531, 0x0556}, {0x0561, 0x0587},
- {0x05d0, 0x05ea}, {0x05f0, 0x05f2}, {0x0620, 0x064a}, {0x0671, 0x06d3},
- {0x06fa, 0x06fc}, {0x0712, 0x072f}, {0x074d, 0x07a5}, {0x07ca, 0x07ea},
- {0x0800, 0x0815}, {0x0840, 0x0858}, {0x0904, 0x0939}, {0x0958, 0x0961},
- {0x0971, 0x0977}, {0x0979, 0x097f}, {0x0985, 0x098c}, {0x0993, 0x09a8},
- {0x09aa, 0x09b0}, {0x09b6, 0x09b9}, {0x09df, 0x09e1}, {0x0a05, 0x0a0a},
- {0x0a13, 0x0a28}, {0x0a2a, 0x0a30}, {0x0a59, 0x0a5c}, {0x0a72, 0x0a74},
- {0x0a85, 0x0a8d}, {0x0a8f, 0x0a91}, {0x0a93, 0x0aa8}, {0x0aaa, 0x0ab0},
- {0x0ab5, 0x0ab9}, {0x0b05, 0x0b0c}, {0x0b13, 0x0b28}, {0x0b2a, 0x0b30},
- {0x0b35, 0x0b39}, {0x0b5f, 0x0b61}, {0x0b85, 0x0b8a}, {0x0b8e, 0x0b90},
- {0x0b92, 0x0b95}, {0x0ba8, 0x0baa}, {0x0bae, 0x0bb9}, {0x0c05, 0x0c0c},
- {0x0c0e, 0x0c10}, {0x0c12, 0x0c28}, {0x0c2a, 0x0c33}, {0x0c35, 0x0c39},
- {0x0c85, 0x0c8c}, {0x0c8e, 0x0c90}, {0x0c92, 0x0ca8}, {0x0caa, 0x0cb3},
- {0x0cb5, 0x0cb9}, {0x0d05, 0x0d0c}, {0x0d0e, 0x0d10}, {0x0d12, 0x0d3a},
- {0x0d7a, 0x0d7f}, {0x0d85, 0x0d96}, {0x0d9a, 0x0db1}, {0x0db3, 0x0dbb},
- {0x0dc0, 0x0dc6}, {0x0e01, 0x0e30}, {0x0e40, 0x0e46}, {0x0e94, 0x0e97},
- {0x0e99, 0x0e9f}, {0x0ea1, 0x0ea3}, {0x0ead, 0x0eb0}, {0x0ec0, 0x0ec4},
- {0x0f40, 0x0f47}, {0x0f49, 0x0f6c}, {0x0f88, 0x0f8c}, {0x1000, 0x102a},
- {0x1050, 0x1055}, {0x105a, 0x105d}, {0x106e, 0x1070}, {0x1075, 0x1081},
- {0x10a0, 0x10c5}, {0x10d0, 0x10fa}, {0x1100, 0x1248}, {0x124a, 0x124d},
- {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d},
- {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5},
- {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a},
- {0x1380, 0x138f}, {0x13a0, 0x13f4}, {0x1401, 0x166c}, {0x166f, 0x167f},
- {0x1681, 0x169a}, {0x16a0, 0x16ea}, {0x1700, 0x170c}, {0x170e, 0x1711},
- {0x1720, 0x1731}, {0x1740, 0x1751}, {0x1760, 0x176c}, {0x176e, 0x1770},
- {0x1780, 0x17b3}, {0x1820, 0x1877}, {0x1880, 0x18a8}, {0x18b0, 0x18f5},
- {0x1900, 0x191c}, {0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab},
- {0x19c1, 0x19c7}, {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33},
- {0x1b45, 0x1b4b}, {0x1b83, 0x1ba0}, {0x1bc0, 0x1be5}, {0x1c00, 0x1c23},
- {0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {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, 0x2d65}, {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, 0x312d},
- {0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, {0x3400, 0x4db5},
- {0x4e00, 0x9fcb}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, {0xa500, 0xa60c},
- {0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa697}, {0xa6a0, 0xa6e5},
- {0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa78e}, {0xa7a0, 0xa7a9},
- {0xa7fa, 0xa801}, {0xa803, 0xa805}, {0xa807, 0xa80a}, {0xa80c, 0xa822},
- {0xa840, 0xa873}, {0xa882, 0xa8b3}, {0xa8f2, 0xa8f7}, {0xa90a, 0xa925},
- {0xa930, 0xa946}, {0xa960, 0xa97c}, {0xa984, 0xa9b2}, {0xaa00, 0xaa28},
- {0xaa40, 0xaa42}, {0xaa44, 0xaa4b}, {0xaa60, 0xaa76}, {0xaa80, 0xaaaf},
- {0xaab9, 0xaabd}, {0xaadb, 0xaadd}, {0xab01, 0xab06}, {0xab09, 0xab0e},
- {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e}, {0xabc0, 0xabe2},
- {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xfa2d},
- {0xfa30, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17},
+ {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, 0x527}, {0x531, 0x556}, {0x561, 0x587},
+ {0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3},
+ {0x6fa, 0x6fc}, {0x712, 0x72f}, {0x74d, 0x7a5}, {0x7ca, 0x7ea},
+ {0x800, 0x815}, {0x840, 0x858}, {0x8a2, 0x8ac}, {0x904, 0x939},
+ {0x958, 0x961}, {0x971, 0x977}, {0x979, 0x97f}, {0x985, 0x98c},
+ {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9df, 0x9e1},
+ {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa59, 0xa5c},
+ {0xa72, 0xa74}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8},
+ {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xb05, 0xb0c}, {0xb13, 0xb28},
+ {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb5f, 0xb61}, {0xb85, 0xb8a},
+ {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9},
+ {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc33},
+ {0xc35, 0xc39}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8},
+ {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
+ {0xd12, 0xd3a}, {0xd7a, 0xd7f}, {0xd85, 0xd96}, {0xd9a, 0xdb1},
+ {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, {0xe01, 0xe30}, {0xe40, 0xe46},
+ {0xe94, 0xe97}, {0xe99, 0xe9f}, {0xea1, 0xea3}, {0xead, 0xeb0},
+ {0xec0, 0xec4}, {0xedc, 0xedf}, {0xf40, 0xf47}, {0xf49, 0xf6c},
+ {0xf88, 0xf8c}, {0x1000, 0x102a}, {0x1050, 0x1055}, {0x105a, 0x105d},
+ {0x106e, 0x1070}, {0x1075, 0x1081}, {0x10a0, 0x10c5}, {0x10d0, 0x10fa},
+ {0x10fc, 0x1248}, {0x124a, 0x124d}, {0x1250, 0x1256}, {0x125a, 0x125d},
+ {0x1260, 0x1288}, {0x128a, 0x128d}, {0x1290, 0x12b0}, {0x12b2, 0x12b5},
+ {0x12b8, 0x12be}, {0x12c2, 0x12c5}, {0x12c8, 0x12d6}, {0x12d8, 0x1310},
+ {0x1312, 0x1315}, {0x1318, 0x135a}, {0x1380, 0x138f}, {0x13a0, 0x13f4},
+ {0x1401, 0x166c}, {0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea},
+ {0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731}, {0x1740, 0x1751},
+ {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3}, {0x1820, 0x1877},
+ {0x1880, 0x18a8}, {0x18b0, 0x18f5}, {0x1900, 0x191c}, {0x1950, 0x196d},
+ {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19c1, 0x19c7}, {0x1a00, 0x1a16},
+ {0x1a20, 0x1a54}, {0x1b05, 0x1b33}, {0x1b45, 0x1b4b}, {0x1b83, 0x1ba0},
+ {0x1bba, 0x1be5}, {0x1c00, 0x1c23}, {0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d},
+ {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, 0x312d}, {0x3131, 0x318e}, {0x31a0, 0x31ba},
+ {0x31f0, 0x31ff}, {0x3400, 0x4db5}, {0x4e00, 0x9fcc}, {0xa000, 0xa48c},
+ {0xa4d0, 0xa4fd}, {0xa500, 0xa60c}, {0xa610, 0xa61f}, {0xa640, 0xa66e},
+ {0xa67f, 0xa697}, {0xa6a0, 0xa6e5}, {0xa717, 0xa71f}, {0xa722, 0xa788},
+ {0xa78b, 0xa78e}, {0xa790, 0xa793}, {0xa7a0, 0xa7aa}, {0xa7f8, 0xa801},
+ {0xa803, 0xa805}, {0xa807, 0xa80a}, {0xa80c, 0xa822}, {0xa840, 0xa873},
+ {0xa882, 0xa8b3}, {0xa8f2, 0xa8f7}, {0xa90a, 0xa925}, {0xa930, 0xa946},
+ {0xa960, 0xa97c}, {0xa984, 0xa9b2}, {0xaa00, 0xaa28}, {0xaa40, 0xaa42},
+ {0xaa44, 0xaa4b}, {0xaa60, 0xaa76}, {0xaa80, 0xaaaf}, {0xaab9, 0xaabd},
+ {0xaadb, 0xaadd}, {0xaae0, 0xaaea}, {0xaaf2, 0xaaf4}, {0xab01, 0xab06},
+ {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e},
+ {0xabc0, 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 TCL_UTF_MAX > 4
+ ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
+ {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0},
+ {0x10300, 0x1031e}, {0x10330, 0x10340}, {0x10342, 0x10349}, {0x10380, 0x1039d},
+ {0x103a0, 0x103c3}, {0x103c8, 0x103cf}, {0x10400, 0x1049d}, {0x10800, 0x10805},
+ {0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10900, 0x10915}, {0x10920, 0x10939},
+ {0x10980, 0x109b7}, {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33},
+ {0x10a60, 0x10a7c}, {0x10b00, 0x10b35}, {0x10b40, 0x10b55}, {0x10b60, 0x10b72},
+ {0x10c00, 0x10c48}, {0x11003, 0x11037}, {0x11083, 0x110af}, {0x110d0, 0x110e8},
+ {0x11103, 0x11126}, {0x11183, 0x111b2}, {0x111c1, 0x111c4}, {0x11680, 0x116aa},
+ {0x12000, 0x1236e}, {0x13000, 0x1342e}, {0x16800, 0x16a38}, {0x16f00, 0x16f44},
+ {0x16f93, 0x16f9f}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac},
+ {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a},
+ {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
+ {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d6c0},
+ {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734},
+ {0x1d736, 0x1d74e}, {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8},
+ {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7cb}, {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f},
+ {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a},
+ {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89},
+ {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb},
+ {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, {0x2f800, 0x2fa1d}
+#endif
};
#define NUM_ALPHA_RANGE (sizeof(alphaRangeTable)/sizeof(crange))
static const chr alphaCharTable[] = {
- 0x00aa, 0x00b5, 0x00ba, 0x02ec, 0x02ee, 0x0376, 0x0377, 0x0386, 0x038c,
- 0x0559, 0x066e, 0x066f, 0x06d5, 0x06e5, 0x06e6, 0x06ee, 0x06ef, 0x06ff,
- 0x0710, 0x07b1, 0x07f4, 0x07f5, 0x07fa, 0x081a, 0x0824, 0x0828, 0x093d,
- 0x0950, 0x098f, 0x0990, 0x09b2, 0x09bd, 0x09ce, 0x09dc, 0x09dd, 0x09f0,
- 0x09f1, 0x0a0f, 0x0a10, 0x0a32, 0x0a33, 0x0a35, 0x0a36, 0x0a38, 0x0a39,
- 0x0a5e, 0x0ab2, 0x0ab3, 0x0abd, 0x0ad0, 0x0ae0, 0x0ae1, 0x0b0f, 0x0b10,
- 0x0b32, 0x0b33, 0x0b3d, 0x0b5c, 0x0b5d, 0x0b71, 0x0b83, 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9e, 0x0b9f, 0x0ba3, 0x0ba4, 0x0bd0, 0x0c3d, 0x0c58, 0x0c59,
- 0x0c60, 0x0c61, 0x0cbd, 0x0cde, 0x0ce0, 0x0ce1, 0x0cf1, 0x0cf2, 0x0d3d,
- 0x0d4e, 0x0d60, 0x0d61, 0x0dbd, 0x0e32, 0x0e33, 0x0e81, 0x0e82, 0x0e84,
- 0x0e87, 0x0e88, 0x0e8a, 0x0e8d, 0x0ea5, 0x0ea7, 0x0eaa, 0x0eab, 0x0eb2,
- 0x0eb3, 0x0ebd, 0x0ec6, 0x0edc, 0x0edd, 0x0f00, 0x103f, 0x1061, 0x1065,
- 0x1066, 0x108e, 0x10fc, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7,
- 0x1bae, 0x1baf, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071, 0x207f, 0x2102,
- 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183, 0x2184, 0x2d6f,
- 0x2e2f, 0x3005, 0x3006, 0x303b, 0x303c, 0xa62a, 0xa62b, 0xa790, 0xa791,
- 0xa8fb, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5, 0xaab6, 0xaac0, 0xaac2, 0xfb1d,
- 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffe, 0xffff
+ 0xaa, 0xb5, 0xba, 0x2ec, 0x2ee, 0x376, 0x377, 0x386, 0x38c,
+ 0x559, 0x66e, 0x66f, 0x6d5, 0x6e5, 0x6e6, 0x6ee, 0x6ef, 0x6ff,
+ 0x710, 0x7b1, 0x7f4, 0x7f5, 0x7fa, 0x81a, 0x824, 0x828, 0x8a0,
+ 0x93d, 0x950, 0x98f, 0x990, 0x9b2, 0x9bd, 0x9ce, 0x9dc, 0x9dd,
+ 0x9f0, 0x9f1, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38,
+ 0xa39, 0xa5e, 0xab2, 0xab3, 0xabd, 0xad0, 0xae0, 0xae1, 0xb0f,
+ 0xb10, 0xb32, 0xb33, 0xb3d, 0xb5c, 0xb5d, 0xb71, 0xb83, 0xb99,
+ 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xbd0, 0xc3d, 0xc58,
+ 0xc59, 0xc60, 0xc61, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1, 0xcf2,
+ 0xd3d, 0xd4e, 0xd60, 0xd61, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82,
+ 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab,
+ 0xeb2, 0xeb3, 0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066,
+ 0x108e, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7,
+ 0x1bae, 0x1baf, 0x1cf5, 0x1cf6, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071,
+ 0x207f, 0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183,
+ 0x2184, 0x2cf2, 0x2cf3, 0x2d27, 0x2d2d, 0x2d6f, 0x2e2f, 0x3005, 0x3006,
+ 0x303b, 0x303c, 0xa62a, 0xa62b, 0xa8fb, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5,
+ 0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44
+#if TCL_UTF_MAX > 4
+ ,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x109be, 0x109bf, 0x10a00,
+ 0x16f50, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb,
+ 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47,
+ 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d,
+ 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
+#endif
};
#define NUM_ALPHA_CHAR (sizeof(alphaCharTable)/sizeof(chr))
/*
+ * Unicode: control characters.
+ */
+
+static const crange controlRangeTable[] = {
+ {0x0, 0x1f}, {0x7f, 0x9f}, {0x600, 0x604}, {0x200b, 0x200f},
+ {0x202a, 0x202e}, {0x2060, 0x2064}, {0x2066, 0x206f}, {0xe000, 0xf8ff},
+ {0xfff9, 0xfffb}
+#if TCL_UTF_MAX > 4
+ ,{0x1d173, 0x1d17a}, {0xe0020, 0xe007f}, {0xf0000, 0xffffd}, {0x100000, 0x10fffd}
+#endif
+};
+
+#define NUM_CONTROL_RANGE (sizeof(controlRangeTable)/sizeof(crange))
+
+static const chr controlCharTable[] = {
+ 0xad, 0x61c, 0x6dd, 0x70f, 0x180e, 0xfeff
+#if TCL_UTF_MAX > 4
+ ,0x110bd, 0xe0001
+#endif
+};
+
+#define NUM_CONTROL_CHAR (sizeof(controlCharTable)/sizeof(chr))
+
+/*
* Unicode: decimal digit characters.
*/
static const crange digitRangeTable[] = {
- {0x0030, 0x0039}, {0x0660, 0x0669}, {0x06f0, 0x06f9}, {0x07c0, 0x07c9},
- {0x0966, 0x096f}, {0x09e6, 0x09ef}, {0x0a66, 0x0a6f}, {0x0ae6, 0x0aef},
- {0x0b66, 0x0b6f}, {0x0be6, 0x0bef}, {0x0c66, 0x0c6f}, {0x0ce6, 0x0cef},
- {0x0d66, 0x0d6f}, {0x0e50, 0x0e59}, {0x0ed0, 0x0ed9}, {0x0f20, 0x0f29},
+ {0x30, 0x39}, {0x660, 0x669}, {0x6f0, 0x6f9}, {0x7c0, 0x7c9},
+ {0x966, 0x96f}, {0x9e6, 0x9ef}, {0xa66, 0xa6f}, {0xae6, 0xaef},
+ {0xb66, 0xb6f}, {0xbe6, 0xbef}, {0xc66, 0xc6f}, {0xce6, 0xcef},
+ {0xd66, 0xd6f}, {0xe50, 0xe59}, {0xed0, 0xed9}, {0xf20, 0xf29},
{0x1040, 0x1049}, {0x1090, 0x1099}, {0x17e0, 0x17e9}, {0x1810, 0x1819},
{0x1946, 0x194f}, {0x19d0, 0x19d9}, {0x1a80, 0x1a89}, {0x1a90, 0x1a99},
{0x1b50, 0x1b59}, {0x1bb0, 0x1bb9}, {0x1c40, 0x1c49}, {0x1c50, 0x1c59},
{0xa620, 0xa629}, {0xa8d0, 0xa8d9}, {0xa900, 0xa909}, {0xa9d0, 0xa9d9},
{0xaa50, 0xaa59}, {0xabf0, 0xabf9}, {0xff10, 0xff19}
+#if TCL_UTF_MAX > 4
+ ,{0x104a0, 0x104a9}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, {0x11136, 0x1113f},
+ {0x111d0, 0x111d9}, {0x116c0, 0x116c9}, {0x1d7ce, 0x1d7ff}
+#endif
};
#define NUM_DIGIT_RANGE (sizeof(digitRangeTable)/sizeof(crange))
@@ -250,36 +309,44 @@ static const crange digitRangeTable[] = {
*/
static const crange punctRangeTable[] = {
- {0x0021, 0x0023}, {0x0025, 0x002a}, {0x002c, 0x002f}, {0x005b, 0x005d},
- {0x055a, 0x055f}, {0x066a, 0x066d}, {0x0700, 0x070d}, {0x07f7, 0x07f9},
- {0x0830, 0x083e}, {0x0f04, 0x0f12}, {0x0f3a, 0x0f3d}, {0x0fd0, 0x0fd4},
- {0x104a, 0x104f}, {0x1361, 0x1368}, {0x16eb, 0x16ed}, {0x17d4, 0x17d6},
+ {0x21, 0x23}, {0x25, 0x2a}, {0x2c, 0x2f}, {0x5b, 0x5d},
+ {0x55a, 0x55f}, {0x66a, 0x66d}, {0x700, 0x70d}, {0x7f7, 0x7f9},
+ {0x830, 0x83e}, {0xf04, 0xf12}, {0xf3a, 0xf3d}, {0xfd0, 0xfd4},
+ {0x104a, 0x104f}, {0x1360, 0x1368}, {0x16eb, 0x16ed}, {0x17d4, 0x17d6},
{0x17d8, 0x17da}, {0x1800, 0x180a}, {0x1aa0, 0x1aa6}, {0x1aa8, 0x1aad},
- {0x1b5a, 0x1b60}, {0x1bfc, 0x1bff}, {0x1c3b, 0x1c3f}, {0x2010, 0x2027},
- {0x2030, 0x2043}, {0x2045, 0x2051}, {0x2053, 0x205e}, {0x2768, 0x2775},
- {0x27e6, 0x27ef}, {0x2983, 0x2998}, {0x29d8, 0x29db}, {0x2cf9, 0x2cfc},
- {0x2e00, 0x2e2e}, {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}
+ {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, 0x2e3b},
+ {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
+ ,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10b39, 0x10b3f}, {0x11047, 0x1104d},
+ {0x110be, 0x110c1}, {0x11140, 0x11143}, {0x111c5, 0x111c8}, {0x12470, 0x12473}
+#endif
};
#define NUM_PUNCT_RANGE (sizeof(punctRangeTable)/sizeof(crange))
static const chr punctCharTable[] = {
- 0x003a, 0x003b, 0x003f, 0x0040, 0x005f, 0x007b, 0x007d, 0x00a1, 0x00ab,
- 0x00b7, 0x00bb, 0x00bf, 0x037e, 0x0387, 0x0589, 0x058a, 0x05be, 0x05c0,
- 0x05c3, 0x05c6, 0x05f3, 0x05f4, 0x0609, 0x060a, 0x060c, 0x060d, 0x061b,
- 0x061e, 0x061f, 0x06d4, 0x085e, 0x0964, 0x0965, 0x0970, 0x0df4, 0x0e4f,
- 0x0e5a, 0x0e5b, 0x0f85, 0x0fd9, 0x0fda, 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, 0x2e30, 0x2e31, 0x3030,
- 0x303d, 0x30a0, 0x30fb, 0xa4fe, 0xa4ff, 0xa673, 0xa67e, 0xa8ce, 0xa8cf,
- 0xa92e, 0xa92f, 0xa95f, 0xa9de, 0xa9df, 0xaade, 0xaadf, 0xabeb, 0xfd3e,
- 0xfd3f, 0xfe63, 0xfe68, 0xfe6a, 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20,
- 0xff3f, 0xff5b, 0xff5d
+ 0x3a, 0x3b, 0x3f, 0x40, 0x5f, 0x7b, 0x7d, 0xa1, 0xa7,
+ 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,
+ 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, 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
+ ,0x1039f, 0x103d0, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc
+#endif
};
#define NUM_PUNCT_CHAR (sizeof(punctCharTable)/sizeof(chr))
@@ -289,13 +356,14 @@ static const chr punctCharTable[] = {
*/
static const crange spaceRangeTable[] = {
- {0x0009, 0x000d}, {0x2000, 0x200a}
+ {0x9, 0xd}, {0x2000, 0x200b}
};
#define NUM_SPACE_RANGE (sizeof(spaceRangeTable)/sizeof(crange))
static const chr spaceCharTable[] = {
- 0x0020, 0x00a0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f, 0x3000
+ 0x20, 0x85, 0xa0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f,
+ 0x2060, 0x3000, 0xfeff
};
#define NUM_SPACE_CHAR (sizeof(spaceCharTable)/sizeof(chr))
@@ -305,84 +373,96 @@ static const chr spaceCharTable[] = {
*/
static const crange lowerRangeTable[] = {
- {0x0061, 0x007a}, {0x00df, 0x00f6}, {0x00f8, 0x00ff}, {0x017e, 0x0180},
- {0x0199, 0x019b}, {0x01bd, 0x01bf}, {0x0233, 0x0239}, {0x024f, 0x0293},
- {0x0295, 0x02af}, {0x037b, 0x037d}, {0x03ac, 0x03ce}, {0x03d5, 0x03d7},
- {0x03ef, 0x03f3}, {0x0430, 0x045f}, {0x0561, 0x0587}, {0x1d00, 0x1d2b},
- {0x1d62, 0x1d77}, {0x1d79, 0x1d9a}, {0x1e95, 0x1e9d}, {0x1eff, 0x1f07},
+ {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}, {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, 0x2c7c}, {0x2d00, 0x2d25}, {0xa72f, 0xa731},
+ {0x2c30, 0x2c5e}, {0x2c76, 0x2c7b}, {0x2d00, 0x2d25}, {0xa72f, 0xa731},
{0xa771, 0xa778}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xff41, 0xff5a}
+#if TCL_UTF_MAX > 4
+ ,{0x10428, 0x1044f}, {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}
+#endif
};
#define NUM_LOWER_RANGE (sizeof(lowerRangeTable)/sizeof(crange))
static const chr lowerCharTable[] = {
- 0x00aa, 0x00b5, 0x00ba, 0x0101, 0x0103, 0x0105, 0x0107, 0x0109, 0x010b,
- 0x010d, 0x010f, 0x0111, 0x0113, 0x0115, 0x0117, 0x0119, 0x011b, 0x011d,
- 0x011f, 0x0121, 0x0123, 0x0125, 0x0127, 0x0129, 0x012b, 0x012d, 0x012f,
- 0x0131, 0x0133, 0x0135, 0x0137, 0x0138, 0x013a, 0x013c, 0x013e, 0x0140,
- 0x0142, 0x0144, 0x0146, 0x0148, 0x0149, 0x014b, 0x014d, 0x014f, 0x0151,
- 0x0153, 0x0155, 0x0157, 0x0159, 0x015b, 0x015d, 0x015f, 0x0161, 0x0163,
- 0x0165, 0x0167, 0x0169, 0x016b, 0x016d, 0x016f, 0x0171, 0x0173, 0x0175,
- 0x0177, 0x017a, 0x017c, 0x0183, 0x0185, 0x0188, 0x018c, 0x018d, 0x0192,
- 0x0195, 0x019e, 0x01a1, 0x01a3, 0x01a5, 0x01a8, 0x01aa, 0x01ab, 0x01ad,
- 0x01b0, 0x01b4, 0x01b6, 0x01b9, 0x01ba, 0x01c6, 0x01c9, 0x01cc, 0x01ce,
- 0x01d0, 0x01d2, 0x01d4, 0x01d6, 0x01d8, 0x01da, 0x01dc, 0x01dd, 0x01df,
- 0x01e1, 0x01e3, 0x01e5, 0x01e7, 0x01e9, 0x01eb, 0x01ed, 0x01ef, 0x01f0,
- 0x01f3, 0x01f5, 0x01f9, 0x01fb, 0x01fd, 0x01ff, 0x0201, 0x0203, 0x0205,
- 0x0207, 0x0209, 0x020b, 0x020d, 0x020f, 0x0211, 0x0213, 0x0215, 0x0217,
- 0x0219, 0x021b, 0x021d, 0x021f, 0x0221, 0x0223, 0x0225, 0x0227, 0x0229,
- 0x022b, 0x022d, 0x022f, 0x0231, 0x023c, 0x023f, 0x0240, 0x0242, 0x0247,
- 0x0249, 0x024b, 0x024d, 0x0371, 0x0373, 0x0377, 0x0390, 0x03d0, 0x03d1,
- 0x03d9, 0x03db, 0x03dd, 0x03df, 0x03e1, 0x03e3, 0x03e5, 0x03e7, 0x03e9,
- 0x03eb, 0x03ed, 0x03f5, 0x03f8, 0x03fb, 0x03fc, 0x0461, 0x0463, 0x0465,
- 0x0467, 0x0469, 0x046b, 0x046d, 0x046f, 0x0471, 0x0473, 0x0475, 0x0477,
- 0x0479, 0x047b, 0x047d, 0x047f, 0x0481, 0x048b, 0x048d, 0x048f, 0x0491,
- 0x0493, 0x0495, 0x0497, 0x0499, 0x049b, 0x049d, 0x049f, 0x04a1, 0x04a3,
- 0x04a5, 0x04a7, 0x04a9, 0x04ab, 0x04ad, 0x04af, 0x04b1, 0x04b3, 0x04b5,
- 0x04b7, 0x04b9, 0x04bb, 0x04bd, 0x04bf, 0x04c2, 0x04c4, 0x04c6, 0x04c8,
- 0x04ca, 0x04cc, 0x04ce, 0x04cf, 0x04d1, 0x04d3, 0x04d5, 0x04d7, 0x04d9,
- 0x04db, 0x04dd, 0x04df, 0x04e1, 0x04e3, 0x04e5, 0x04e7, 0x04e9, 0x04eb,
- 0x04ed, 0x04ef, 0x04f1, 0x04f3, 0x04f5, 0x04f7, 0x04f9, 0x04fb, 0x04fd,
- 0x04ff, 0x0501, 0x0503, 0x0505, 0x0507, 0x0509, 0x050b, 0x050d, 0x050f,
- 0x0511, 0x0513, 0x0515, 0x0517, 0x0519, 0x051b, 0x051d, 0x051f, 0x0521,
- 0x0523, 0x0525, 0x0527, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09, 0x1e0b,
- 0x1e0d, 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b, 0x1e1d,
- 0x1e1f, 0x1e21, 0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b, 0x1e2d, 0x1e2f,
- 0x1e31, 0x1e33, 0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d, 0x1e3f, 0x1e41,
- 0x1e43, 0x1e45, 0x1e47, 0x1e49, 0x1e4b, 0x1e4d, 0x1e4f, 0x1e51, 0x1e53,
- 0x1e55, 0x1e57, 0x1e59, 0x1e5b, 0x1e5d, 0x1e5f, 0x1e61, 0x1e63, 0x1e65,
- 0x1e67, 0x1e69, 0x1e6b, 0x1e6d, 0x1e6f, 0x1e71, 0x1e73, 0x1e75, 0x1e77,
- 0x1e79, 0x1e7b, 0x1e7d, 0x1e7f, 0x1e81, 0x1e83, 0x1e85, 0x1e87, 0x1e89,
- 0x1e8b, 0x1e8d, 0x1e8f, 0x1e91, 0x1e93, 0x1e9f, 0x1ea1, 0x1ea3, 0x1ea5,
- 0x1ea7, 0x1ea9, 0x1eab, 0x1ead, 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7,
- 0x1eb9, 0x1ebb, 0x1ebd, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ec9,
- 0x1ecb, 0x1ecd, 0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, 0x1edb,
- 0x1edd, 0x1edf, 0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, 0x1eeb, 0x1eed,
- 0x1eef, 0x1ef1, 0x1ef3, 0x1ef5, 0x1ef7, 0x1ef9, 0x1efb, 0x1efd, 0x1fb6,
- 0x1fb7, 0x1fbe, 0x1fc6, 0x1fc7, 0x1fd6, 0x1fd7, 0x1ff6, 0x1ff7, 0x210a,
- 0x210e, 0x210f, 0x2113, 0x212f, 0x2134, 0x2139, 0x213c, 0x213d, 0x214e,
- 0x2184, 0x2c61, 0x2c65, 0x2c66, 0x2c68, 0x2c6a, 0x2c6c, 0x2c71, 0x2c73,
- 0x2c74, 0x2c81, 0x2c83, 0x2c85, 0x2c87, 0x2c89, 0x2c8b, 0x2c8d, 0x2c8f,
- 0x2c91, 0x2c93, 0x2c95, 0x2c97, 0x2c99, 0x2c9b, 0x2c9d, 0x2c9f, 0x2ca1,
- 0x2ca3, 0x2ca5, 0x2ca7, 0x2ca9, 0x2cab, 0x2cad, 0x2caf, 0x2cb1, 0x2cb3,
- 0x2cb5, 0x2cb7, 0x2cb9, 0x2cbb, 0x2cbd, 0x2cbf, 0x2cc1, 0x2cc3, 0x2cc5,
- 0x2cc7, 0x2cc9, 0x2ccb, 0x2ccd, 0x2ccf, 0x2cd1, 0x2cd3, 0x2cd5, 0x2cd7,
- 0x2cd9, 0x2cdb, 0x2cdd, 0x2cdf, 0x2ce1, 0x2ce3, 0x2ce4, 0x2cec, 0x2cee,
- 0xa641, 0xa643, 0xa645, 0xa647, 0xa649, 0xa64b, 0xa64d, 0xa64f, 0xa651,
- 0xa653, 0xa655, 0xa657, 0xa659, 0xa65b, 0xa65d, 0xa65f, 0xa661, 0xa663,
- 0xa665, 0xa667, 0xa669, 0xa66b, 0xa66d, 0xa681, 0xa683, 0xa685, 0xa687,
- 0xa689, 0xa68b, 0xa68d, 0xa68f, 0xa691, 0xa693, 0xa695, 0xa697, 0xa723,
- 0xa725, 0xa727, 0xa729, 0xa72b, 0xa72d, 0xa733, 0xa735, 0xa737, 0xa739,
- 0xa73b, 0xa73d, 0xa73f, 0xa741, 0xa743, 0xa745, 0xa747, 0xa749, 0xa74b,
- 0xa74d, 0xa74f, 0xa751, 0xa753, 0xa755, 0xa757, 0xa759, 0xa75b, 0xa75d,
- 0xa75f, 0xa761, 0xa763, 0xa765, 0xa767, 0xa769, 0xa76b, 0xa76d, 0xa76f,
- 0xa77a, 0xa77c, 0xa77f, 0xa781, 0xa783, 0xa785, 0xa787, 0xa78c, 0xa78e,
- 0xa791, 0xa7a1, 0xa7a3, 0xa7a5, 0xa7a7, 0xa7a9, 0xa7fa
+ 0xb5, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10b, 0x10d, 0x10f,
+ 0x111, 0x113, 0x115, 0x117, 0x119, 0x11b, 0x11d, 0x11f, 0x121,
+ 0x123, 0x125, 0x127, 0x129, 0x12b, 0x12d, 0x12f, 0x131, 0x133,
+ 0x135, 0x137, 0x138, 0x13a, 0x13c, 0x13e, 0x140, 0x142, 0x144,
+ 0x146, 0x148, 0x149, 0x14b, 0x14d, 0x14f, 0x151, 0x153, 0x155,
+ 0x157, 0x159, 0x15b, 0x15d, 0x15f, 0x161, 0x163, 0x165, 0x167,
+ 0x169, 0x16b, 0x16d, 0x16f, 0x171, 0x173, 0x175, 0x177, 0x17a,
+ 0x17c, 0x183, 0x185, 0x188, 0x18c, 0x18d, 0x192, 0x195, 0x19e,
+ 0x1a1, 0x1a3, 0x1a5, 0x1a8, 0x1aa, 0x1ab, 0x1ad, 0x1b0, 0x1b4,
+ 0x1b6, 0x1b9, 0x1ba, 0x1c6, 0x1c9, 0x1cc, 0x1ce, 0x1d0, 0x1d2,
+ 0x1d4, 0x1d6, 0x1d8, 0x1da, 0x1dc, 0x1dd, 0x1df, 0x1e1, 0x1e3,
+ 0x1e5, 0x1e7, 0x1e9, 0x1eb, 0x1ed, 0x1ef, 0x1f0, 0x1f3, 0x1f5,
+ 0x1f9, 0x1fb, 0x1fd, 0x1ff, 0x201, 0x203, 0x205, 0x207, 0x209,
+ 0x20b, 0x20d, 0x20f, 0x211, 0x213, 0x215, 0x217, 0x219, 0x21b,
+ 0x21d, 0x21f, 0x221, 0x223, 0x225, 0x227, 0x229, 0x22b, 0x22d,
+ 0x22f, 0x231, 0x23c, 0x23f, 0x240, 0x242, 0x247, 0x249, 0x24b,
+ 0x24d, 0x371, 0x373, 0x377, 0x390, 0x3d0, 0x3d1, 0x3d9, 0x3db,
+ 0x3dd, 0x3df, 0x3e1, 0x3e3, 0x3e5, 0x3e7, 0x3e9, 0x3eb, 0x3ed,
+ 0x3f5, 0x3f8, 0x3fb, 0x3fc, 0x461, 0x463, 0x465, 0x467, 0x469,
+ 0x46b, 0x46d, 0x46f, 0x471, 0x473, 0x475, 0x477, 0x479, 0x47b,
+ 0x47d, 0x47f, 0x481, 0x48b, 0x48d, 0x48f, 0x491, 0x493, 0x495,
+ 0x497, 0x499, 0x49b, 0x49d, 0x49f, 0x4a1, 0x4a3, 0x4a5, 0x4a7,
+ 0x4a9, 0x4ab, 0x4ad, 0x4af, 0x4b1, 0x4b3, 0x4b5, 0x4b7, 0x4b9,
+ 0x4bb, 0x4bd, 0x4bf, 0x4c2, 0x4c4, 0x4c6, 0x4c8, 0x4ca, 0x4cc,
+ 0x4ce, 0x4cf, 0x4d1, 0x4d3, 0x4d5, 0x4d7, 0x4d9, 0x4db, 0x4dd,
+ 0x4df, 0x4e1, 0x4e3, 0x4e5, 0x4e7, 0x4e9, 0x4eb, 0x4ed, 0x4ef,
+ 0x4f1, 0x4f3, 0x4f5, 0x4f7, 0x4f9, 0x4fb, 0x4fd, 0x4ff, 0x501,
+ 0x503, 0x505, 0x507, 0x509, 0x50b, 0x50d, 0x50f, 0x511, 0x513,
+ 0x515, 0x517, 0x519, 0x51b, 0x51d, 0x51f, 0x521, 0x523, 0x525,
+ 0x527, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09, 0x1e0b, 0x1e0d, 0x1e0f,
+ 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b, 0x1e1d, 0x1e1f, 0x1e21,
+ 0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b, 0x1e2d, 0x1e2f, 0x1e31, 0x1e33,
+ 0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d, 0x1e3f, 0x1e41, 0x1e43, 0x1e45,
+ 0x1e47, 0x1e49, 0x1e4b, 0x1e4d, 0x1e4f, 0x1e51, 0x1e53, 0x1e55, 0x1e57,
+ 0x1e59, 0x1e5b, 0x1e5d, 0x1e5f, 0x1e61, 0x1e63, 0x1e65, 0x1e67, 0x1e69,
+ 0x1e6b, 0x1e6d, 0x1e6f, 0x1e71, 0x1e73, 0x1e75, 0x1e77, 0x1e79, 0x1e7b,
+ 0x1e7d, 0x1e7f, 0x1e81, 0x1e83, 0x1e85, 0x1e87, 0x1e89, 0x1e8b, 0x1e8d,
+ 0x1e8f, 0x1e91, 0x1e93, 0x1e9f, 0x1ea1, 0x1ea3, 0x1ea5, 0x1ea7, 0x1ea9,
+ 0x1eab, 0x1ead, 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, 0x1eb9, 0x1ebb,
+ 0x1ebd, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ec9, 0x1ecb, 0x1ecd,
+ 0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, 0x1edb, 0x1edd, 0x1edf,
+ 0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, 0x1eeb, 0x1eed, 0x1eef, 0x1ef1,
+ 0x1ef3, 0x1ef5, 0x1ef7, 0x1ef9, 0x1efb, 0x1efd, 0x1fb6, 0x1fb7, 0x1fbe,
+ 0x1fc6, 0x1fc7, 0x1fd6, 0x1fd7, 0x1ff6, 0x1ff7, 0x210a, 0x210e, 0x210f,
+ 0x2113, 0x212f, 0x2134, 0x2139, 0x213c, 0x213d, 0x214e, 0x2184, 0x2c61,
+ 0x2c65, 0x2c66, 0x2c68, 0x2c6a, 0x2c6c, 0x2c71, 0x2c73, 0x2c74, 0x2c81,
+ 0x2c83, 0x2c85, 0x2c87, 0x2c89, 0x2c8b, 0x2c8d, 0x2c8f, 0x2c91, 0x2c93,
+ 0x2c95, 0x2c97, 0x2c99, 0x2c9b, 0x2c9d, 0x2c9f, 0x2ca1, 0x2ca3, 0x2ca5,
+ 0x2ca7, 0x2ca9, 0x2cab, 0x2cad, 0x2caf, 0x2cb1, 0x2cb3, 0x2cb5, 0x2cb7,
+ 0x2cb9, 0x2cbb, 0x2cbd, 0x2cbf, 0x2cc1, 0x2cc3, 0x2cc5, 0x2cc7, 0x2cc9,
+ 0x2ccb, 0x2ccd, 0x2ccf, 0x2cd1, 0x2cd3, 0x2cd5, 0x2cd7, 0x2cd9, 0x2cdb,
+ 0x2cdd, 0x2cdf, 0x2ce1, 0x2ce3, 0x2ce4, 0x2cec, 0x2cee, 0x2cf3, 0x2d27,
+ 0x2d2d, 0xa641, 0xa643, 0xa645, 0xa647, 0xa649, 0xa64b, 0xa64d, 0xa64f,
+ 0xa651, 0xa653, 0xa655, 0xa657, 0xa659, 0xa65b, 0xa65d, 0xa65f, 0xa661,
+ 0xa663, 0xa665, 0xa667, 0xa669, 0xa66b, 0xa66d, 0xa681, 0xa683, 0xa685,
+ 0xa687, 0xa689, 0xa68b, 0xa68d, 0xa68f, 0xa691, 0xa693, 0xa695, 0xa697,
+ 0xa723, 0xa725, 0xa727, 0xa729, 0xa72b, 0xa72d, 0xa733, 0xa735, 0xa737,
+ 0xa739, 0xa73b, 0xa73d, 0xa73f, 0xa741, 0xa743, 0xa745, 0xa747, 0xa749,
+ 0xa74b, 0xa74d, 0xa74f, 0xa751, 0xa753, 0xa755, 0xa757, 0xa759, 0xa75b,
+ 0xa75d, 0xa75f, 0xa761, 0xa763, 0xa765, 0xa767, 0xa769, 0xa76b, 0xa76d,
+ 0xa76f, 0xa77a, 0xa77c, 0xa77f, 0xa781, 0xa783, 0xa785, 0xa787, 0xa78c,
+ 0xa78e, 0xa791, 0xa793, 0xa7a1, 0xa7a3, 0xa7a5, 0xa7a7, 0xa7a9, 0xa7fa
+#if TCL_UTF_MAX > 4
+ ,0x1d4bb, 0x1d7cb
+#endif
};
#define NUM_LOWER_CHAR (sizeof(lowerCharTable)/sizeof(chr))
@@ -392,83 +472,95 @@ static const chr lowerCharTable[] = {
*/
static const crange upperRangeTable[] = {
- {0x0041, 0x005a}, {0x00c0, 0x00d6}, {0x00d8, 0x00de}, {0x0189, 0x018b},
- {0x018e, 0x0191}, {0x0196, 0x0198}, {0x01b1, 0x01b3}, {0x01f6, 0x01f8},
- {0x0243, 0x0246}, {0x0388, 0x038a}, {0x0391, 0x03a1}, {0x03a3, 0x03ab},
- {0x03d2, 0x03d4}, {0x03fd, 0x042f}, {0x0531, 0x0556}, {0x10a0, 0x10c5},
+ {0x41, 0x5a}, {0xc0, 0xd6}, {0xd8, 0xde}, {0x189, 0x18b},
+ {0x18e, 0x191}, {0x196, 0x198}, {0x1b1, 0x1b3}, {0x1f6, 0x1f8},
+ {0x243, 0x246}, {0x388, 0x38a}, {0x391, 0x3a1}, {0x3a3, 0x3ab},
+ {0x3d2, 0x3d4}, {0x3fd, 0x42f}, {0x531, 0x556}, {0x10a0, 0x10c5},
{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},
{0xff21, 0xff3a}
+#if TCL_UTF_MAX > 4
+ ,{0x10400, 0x10427}, {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}
+#endif
};
#define NUM_UPPER_RANGE (sizeof(upperRangeTable)/sizeof(crange))
static const chr upperCharTable[] = {
- 0x0100, 0x0102, 0x0104, 0x0106, 0x0108, 0x010a, 0x010c, 0x010e, 0x0110,
- 0x0112, 0x0114, 0x0116, 0x0118, 0x011a, 0x011c, 0x011e, 0x0120, 0x0122,
- 0x0124, 0x0126, 0x0128, 0x012a, 0x012c, 0x012e, 0x0130, 0x0132, 0x0134,
- 0x0136, 0x0139, 0x013b, 0x013d, 0x013f, 0x0141, 0x0143, 0x0145, 0x0147,
- 0x014a, 0x014c, 0x014e, 0x0150, 0x0152, 0x0154, 0x0156, 0x0158, 0x015a,
- 0x015c, 0x015e, 0x0160, 0x0162, 0x0164, 0x0166, 0x0168, 0x016a, 0x016c,
- 0x016e, 0x0170, 0x0172, 0x0174, 0x0176, 0x0178, 0x0179, 0x017b, 0x017d,
- 0x0181, 0x0182, 0x0184, 0x0186, 0x0187, 0x0193, 0x0194, 0x019c, 0x019d,
- 0x019f, 0x01a0, 0x01a2, 0x01a4, 0x01a6, 0x01a7, 0x01a9, 0x01ac, 0x01ae,
- 0x01af, 0x01b5, 0x01b7, 0x01b8, 0x01bc, 0x01c4, 0x01c7, 0x01ca, 0x01cd,
- 0x01cf, 0x01d1, 0x01d3, 0x01d5, 0x01d7, 0x01d9, 0x01db, 0x01de, 0x01e0,
- 0x01e2, 0x01e4, 0x01e6, 0x01e8, 0x01ea, 0x01ec, 0x01ee, 0x01f1, 0x01f4,
- 0x01fa, 0x01fc, 0x01fe, 0x0200, 0x0202, 0x0204, 0x0206, 0x0208, 0x020a,
- 0x020c, 0x020e, 0x0210, 0x0212, 0x0214, 0x0216, 0x0218, 0x021a, 0x021c,
- 0x021e, 0x0220, 0x0222, 0x0224, 0x0226, 0x0228, 0x022a, 0x022c, 0x022e,
- 0x0230, 0x0232, 0x023a, 0x023b, 0x023d, 0x023e, 0x0241, 0x0248, 0x024a,
- 0x024c, 0x024e, 0x0370, 0x0372, 0x0376, 0x0386, 0x038c, 0x038e, 0x038f,
- 0x03cf, 0x03d8, 0x03da, 0x03dc, 0x03de, 0x03e0, 0x03e2, 0x03e4, 0x03e6,
- 0x03e8, 0x03ea, 0x03ec, 0x03ee, 0x03f4, 0x03f7, 0x03f9, 0x03fa, 0x0460,
- 0x0462, 0x0464, 0x0466, 0x0468, 0x046a, 0x046c, 0x046e, 0x0470, 0x0472,
- 0x0474, 0x0476, 0x0478, 0x047a, 0x047c, 0x047e, 0x0480, 0x048a, 0x048c,
- 0x048e, 0x0490, 0x0492, 0x0494, 0x0496, 0x0498, 0x049a, 0x049c, 0x049e,
- 0x04a0, 0x04a2, 0x04a4, 0x04a6, 0x04a8, 0x04aa, 0x04ac, 0x04ae, 0x04b0,
- 0x04b2, 0x04b4, 0x04b6, 0x04b8, 0x04ba, 0x04bc, 0x04be, 0x04c0, 0x04c1,
- 0x04c3, 0x04c5, 0x04c7, 0x04c9, 0x04cb, 0x04cd, 0x04d0, 0x04d2, 0x04d4,
- 0x04d6, 0x04d8, 0x04da, 0x04dc, 0x04de, 0x04e0, 0x04e2, 0x04e4, 0x04e6,
- 0x04e8, 0x04ea, 0x04ec, 0x04ee, 0x04f0, 0x04f2, 0x04f4, 0x04f6, 0x04f8,
- 0x04fa, 0x04fc, 0x04fe, 0x0500, 0x0502, 0x0504, 0x0506, 0x0508, 0x050a,
- 0x050c, 0x050e, 0x0510, 0x0512, 0x0514, 0x0516, 0x0518, 0x051a, 0x051c,
- 0x051e, 0x0520, 0x0522, 0x0524, 0x0526, 0x1e00, 0x1e02, 0x1e04, 0x1e06,
- 0x1e08, 0x1e0a, 0x1e0c, 0x1e0e, 0x1e10, 0x1e12, 0x1e14, 0x1e16, 0x1e18,
- 0x1e1a, 0x1e1c, 0x1e1e, 0x1e20, 0x1e22, 0x1e24, 0x1e26, 0x1e28, 0x1e2a,
- 0x1e2c, 0x1e2e, 0x1e30, 0x1e32, 0x1e34, 0x1e36, 0x1e38, 0x1e3a, 0x1e3c,
- 0x1e3e, 0x1e40, 0x1e42, 0x1e44, 0x1e46, 0x1e48, 0x1e4a, 0x1e4c, 0x1e4e,
- 0x1e50, 0x1e52, 0x1e54, 0x1e56, 0x1e58, 0x1e5a, 0x1e5c, 0x1e5e, 0x1e60,
- 0x1e62, 0x1e64, 0x1e66, 0x1e68, 0x1e6a, 0x1e6c, 0x1e6e, 0x1e70, 0x1e72,
- 0x1e74, 0x1e76, 0x1e78, 0x1e7a, 0x1e7c, 0x1e7e, 0x1e80, 0x1e82, 0x1e84,
- 0x1e86, 0x1e88, 0x1e8a, 0x1e8c, 0x1e8e, 0x1e90, 0x1e92, 0x1e94, 0x1e9e,
- 0x1ea0, 0x1ea2, 0x1ea4, 0x1ea6, 0x1ea8, 0x1eaa, 0x1eac, 0x1eae, 0x1eb0,
- 0x1eb2, 0x1eb4, 0x1eb6, 0x1eb8, 0x1eba, 0x1ebc, 0x1ebe, 0x1ec0, 0x1ec2,
- 0x1ec4, 0x1ec6, 0x1ec8, 0x1eca, 0x1ecc, 0x1ece, 0x1ed0, 0x1ed2, 0x1ed4,
- 0x1ed6, 0x1ed8, 0x1eda, 0x1edc, 0x1ede, 0x1ee0, 0x1ee2, 0x1ee4, 0x1ee6,
- 0x1ee8, 0x1eea, 0x1eec, 0x1eee, 0x1ef0, 0x1ef2, 0x1ef4, 0x1ef6, 0x1ef8,
- 0x1efa, 0x1efc, 0x1efe, 0x1f59, 0x1f5b, 0x1f5d, 0x1f5f, 0x2102, 0x2107,
- 0x2115, 0x2124, 0x2126, 0x2128, 0x213e, 0x213f, 0x2145, 0x2183, 0x2c60,
- 0x2c67, 0x2c69, 0x2c6b, 0x2c72, 0x2c75, 0x2c82, 0x2c84, 0x2c86, 0x2c88,
- 0x2c8a, 0x2c8c, 0x2c8e, 0x2c90, 0x2c92, 0x2c94, 0x2c96, 0x2c98, 0x2c9a,
- 0x2c9c, 0x2c9e, 0x2ca0, 0x2ca2, 0x2ca4, 0x2ca6, 0x2ca8, 0x2caa, 0x2cac,
- 0x2cae, 0x2cb0, 0x2cb2, 0x2cb4, 0x2cb6, 0x2cb8, 0x2cba, 0x2cbc, 0x2cbe,
- 0x2cc0, 0x2cc2, 0x2cc4, 0x2cc6, 0x2cc8, 0x2cca, 0x2ccc, 0x2cce, 0x2cd0,
- 0x2cd2, 0x2cd4, 0x2cd6, 0x2cd8, 0x2cda, 0x2cdc, 0x2cde, 0x2ce0, 0x2ce2,
- 0x2ceb, 0x2ced, 0xa640, 0xa642, 0xa644, 0xa646, 0xa648, 0xa64a, 0xa64c,
- 0xa64e, 0xa650, 0xa652, 0xa654, 0xa656, 0xa658, 0xa65a, 0xa65c, 0xa65e,
- 0xa660, 0xa662, 0xa664, 0xa666, 0xa668, 0xa66a, 0xa66c, 0xa680, 0xa682,
- 0xa684, 0xa686, 0xa688, 0xa68a, 0xa68c, 0xa68e, 0xa690, 0xa692, 0xa694,
- 0xa696, 0xa722, 0xa724, 0xa726, 0xa728, 0xa72a, 0xa72c, 0xa72e, 0xa732,
- 0xa734, 0xa736, 0xa738, 0xa73a, 0xa73c, 0xa73e, 0xa740, 0xa742, 0xa744,
- 0xa746, 0xa748, 0xa74a, 0xa74c, 0xa74e, 0xa750, 0xa752, 0xa754, 0xa756,
- 0xa758, 0xa75a, 0xa75c, 0xa75e, 0xa760, 0xa762, 0xa764, 0xa766, 0xa768,
- 0xa76a, 0xa76c, 0xa76e, 0xa779, 0xa77b, 0xa77d, 0xa77e, 0xa780, 0xa782,
- 0xa784, 0xa786, 0xa78b, 0xa78d, 0xa790, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6,
- 0xa7a8
+ 0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e, 0x110,
+ 0x112, 0x114, 0x116, 0x118, 0x11a, 0x11c, 0x11e, 0x120, 0x122,
+ 0x124, 0x126, 0x128, 0x12a, 0x12c, 0x12e, 0x130, 0x132, 0x134,
+ 0x136, 0x139, 0x13b, 0x13d, 0x13f, 0x141, 0x143, 0x145, 0x147,
+ 0x14a, 0x14c, 0x14e, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15a,
+ 0x15c, 0x15e, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16a, 0x16c,
+ 0x16e, 0x170, 0x172, 0x174, 0x176, 0x178, 0x179, 0x17b, 0x17d,
+ 0x181, 0x182, 0x184, 0x186, 0x187, 0x193, 0x194, 0x19c, 0x19d,
+ 0x19f, 0x1a0, 0x1a2, 0x1a4, 0x1a6, 0x1a7, 0x1a9, 0x1ac, 0x1ae,
+ 0x1af, 0x1b5, 0x1b7, 0x1b8, 0x1bc, 0x1c4, 0x1c7, 0x1ca, 0x1cd,
+ 0x1cf, 0x1d1, 0x1d3, 0x1d5, 0x1d7, 0x1d9, 0x1db, 0x1de, 0x1e0,
+ 0x1e2, 0x1e4, 0x1e6, 0x1e8, 0x1ea, 0x1ec, 0x1ee, 0x1f1, 0x1f4,
+ 0x1fa, 0x1fc, 0x1fe, 0x200, 0x202, 0x204, 0x206, 0x208, 0x20a,
+ 0x20c, 0x20e, 0x210, 0x212, 0x214, 0x216, 0x218, 0x21a, 0x21c,
+ 0x21e, 0x220, 0x222, 0x224, 0x226, 0x228, 0x22a, 0x22c, 0x22e,
+ 0x230, 0x232, 0x23a, 0x23b, 0x23d, 0x23e, 0x241, 0x248, 0x24a,
+ 0x24c, 0x24e, 0x370, 0x372, 0x376, 0x386, 0x38c, 0x38e, 0x38f,
+ 0x3cf, 0x3d8, 0x3da, 0x3dc, 0x3de, 0x3e0, 0x3e2, 0x3e4, 0x3e6,
+ 0x3e8, 0x3ea, 0x3ec, 0x3ee, 0x3f4, 0x3f7, 0x3f9, 0x3fa, 0x460,
+ 0x462, 0x464, 0x466, 0x468, 0x46a, 0x46c, 0x46e, 0x470, 0x472,
+ 0x474, 0x476, 0x478, 0x47a, 0x47c, 0x47e, 0x480, 0x48a, 0x48c,
+ 0x48e, 0x490, 0x492, 0x494, 0x496, 0x498, 0x49a, 0x49c, 0x49e,
+ 0x4a0, 0x4a2, 0x4a4, 0x4a6, 0x4a8, 0x4aa, 0x4ac, 0x4ae, 0x4b0,
+ 0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba, 0x4bc, 0x4be, 0x4c0, 0x4c1,
+ 0x4c3, 0x4c5, 0x4c7, 0x4c9, 0x4cb, 0x4cd, 0x4d0, 0x4d2, 0x4d4,
+ 0x4d6, 0x4d8, 0x4da, 0x4dc, 0x4de, 0x4e0, 0x4e2, 0x4e4, 0x4e6,
+ 0x4e8, 0x4ea, 0x4ec, 0x4ee, 0x4f0, 0x4f2, 0x4f4, 0x4f6, 0x4f8,
+ 0x4fa, 0x4fc, 0x4fe, 0x500, 0x502, 0x504, 0x506, 0x508, 0x50a,
+ 0x50c, 0x50e, 0x510, 0x512, 0x514, 0x516, 0x518, 0x51a, 0x51c,
+ 0x51e, 0x520, 0x522, 0x524, 0x526, 0x10c7, 0x10cd, 0x1e00, 0x1e02,
+ 0x1e04, 0x1e06, 0x1e08, 0x1e0a, 0x1e0c, 0x1e0e, 0x1e10, 0x1e12, 0x1e14,
+ 0x1e16, 0x1e18, 0x1e1a, 0x1e1c, 0x1e1e, 0x1e20, 0x1e22, 0x1e24, 0x1e26,
+ 0x1e28, 0x1e2a, 0x1e2c, 0x1e2e, 0x1e30, 0x1e32, 0x1e34, 0x1e36, 0x1e38,
+ 0x1e3a, 0x1e3c, 0x1e3e, 0x1e40, 0x1e42, 0x1e44, 0x1e46, 0x1e48, 0x1e4a,
+ 0x1e4c, 0x1e4e, 0x1e50, 0x1e52, 0x1e54, 0x1e56, 0x1e58, 0x1e5a, 0x1e5c,
+ 0x1e5e, 0x1e60, 0x1e62, 0x1e64, 0x1e66, 0x1e68, 0x1e6a, 0x1e6c, 0x1e6e,
+ 0x1e70, 0x1e72, 0x1e74, 0x1e76, 0x1e78, 0x1e7a, 0x1e7c, 0x1e7e, 0x1e80,
+ 0x1e82, 0x1e84, 0x1e86, 0x1e88, 0x1e8a, 0x1e8c, 0x1e8e, 0x1e90, 0x1e92,
+ 0x1e94, 0x1e9e, 0x1ea0, 0x1ea2, 0x1ea4, 0x1ea6, 0x1ea8, 0x1eaa, 0x1eac,
+ 0x1eae, 0x1eb0, 0x1eb2, 0x1eb4, 0x1eb6, 0x1eb8, 0x1eba, 0x1ebc, 0x1ebe,
+ 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6, 0x1ec8, 0x1eca, 0x1ecc, 0x1ece, 0x1ed0,
+ 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8, 0x1eda, 0x1edc, 0x1ede, 0x1ee0, 0x1ee2,
+ 0x1ee4, 0x1ee6, 0x1ee8, 0x1eea, 0x1eec, 0x1eee, 0x1ef0, 0x1ef2, 0x1ef4,
+ 0x1ef6, 0x1ef8, 0x1efa, 0x1efc, 0x1efe, 0x1f59, 0x1f5b, 0x1f5d, 0x1f5f,
+ 0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x213e, 0x213f, 0x2145,
+ 0x2183, 0x2c60, 0x2c67, 0x2c69, 0x2c6b, 0x2c72, 0x2c75, 0x2c82, 0x2c84,
+ 0x2c86, 0x2c88, 0x2c8a, 0x2c8c, 0x2c8e, 0x2c90, 0x2c92, 0x2c94, 0x2c96,
+ 0x2c98, 0x2c9a, 0x2c9c, 0x2c9e, 0x2ca0, 0x2ca2, 0x2ca4, 0x2ca6, 0x2ca8,
+ 0x2caa, 0x2cac, 0x2cae, 0x2cb0, 0x2cb2, 0x2cb4, 0x2cb6, 0x2cb8, 0x2cba,
+ 0x2cbc, 0x2cbe, 0x2cc0, 0x2cc2, 0x2cc4, 0x2cc6, 0x2cc8, 0x2cca, 0x2ccc,
+ 0x2cce, 0x2cd0, 0x2cd2, 0x2cd4, 0x2cd6, 0x2cd8, 0x2cda, 0x2cdc, 0x2cde,
+ 0x2ce0, 0x2ce2, 0x2ceb, 0x2ced, 0x2cf2, 0xa640, 0xa642, 0xa644, 0xa646,
+ 0xa648, 0xa64a, 0xa64c, 0xa64e, 0xa650, 0xa652, 0xa654, 0xa656, 0xa658,
+ 0xa65a, 0xa65c, 0xa65e, 0xa660, 0xa662, 0xa664, 0xa666, 0xa668, 0xa66a,
+ 0xa66c, 0xa680, 0xa682, 0xa684, 0xa686, 0xa688, 0xa68a, 0xa68c, 0xa68e,
+ 0xa690, 0xa692, 0xa694, 0xa696, 0xa722, 0xa724, 0xa726, 0xa728, 0xa72a,
+ 0xa72c, 0xa72e, 0xa732, 0xa734, 0xa736, 0xa738, 0xa73a, 0xa73c, 0xa73e,
+ 0xa740, 0xa742, 0xa744, 0xa746, 0xa748, 0xa74a, 0xa74c, 0xa74e, 0xa750,
+ 0xa752, 0xa754, 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,
+ 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7aa
+#if TCL_UTF_MAX > 4
+ ,0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d504, 0x1d505, 0x1d538,
+ 0x1d539, 0x1d546, 0x1d7ca
+#endif
};
#define NUM_UPPER_CHAR (sizeof(upperCharTable)/sizeof(chr))
@@ -478,232 +570,147 @@ static const chr upperCharTable[] = {
*/
static const crange graphRangeTable[] = {
- {0x0021, 0x007e}, {0x00a0, 0x00ac}, {0x00ae, 0x011f}, {0x0121, 0x021f},
- {0x0221, 0x031f}, {0x0321, 0x0377}, {0x037a, 0x037e}, {0x0384, 0x038a},
- {0x038e, 0x03a1}, {0x03a3, 0x041f}, {0x0421, 0x051f}, {0x0521, 0x0527},
- {0x0531, 0x0556}, {0x0559, 0x055f}, {0x0561, 0x0587}, {0x0591, 0x05c7},
- {0x05d0, 0x05ea}, {0x05f0, 0x05f4}, {0x0606, 0x061b}, {0x0621, 0x06dc},
- {0x06de, 0x070d}, {0x0710, 0x071f}, {0x0721, 0x074a}, {0x074d, 0x07b1},
- {0x07c0, 0x07fa}, {0x0800, 0x081f}, {0x0821, 0x082d}, {0x0830, 0x083e},
- {0x0840, 0x085b}, {0x0900, 0x091f}, {0x0921, 0x0977}, {0x0979, 0x097f},
- {0x0981, 0x0983}, {0x0985, 0x098c}, {0x0993, 0x09a8}, {0x09aa, 0x09b0},
- {0x09b6, 0x09b9}, {0x09bc, 0x09c4}, {0x09cb, 0x09ce}, {0x09df, 0x09e3},
- {0x09e6, 0x09fb}, {0x0a01, 0x0a03}, {0x0a05, 0x0a0a}, {0x0a13, 0x0a1f},
- {0x0a21, 0x0a28}, {0x0a2a, 0x0a30}, {0x0a3e, 0x0a42}, {0x0a4b, 0x0a4d},
- {0x0a59, 0x0a5c}, {0x0a66, 0x0a75}, {0x0a81, 0x0a83}, {0x0a85, 0x0a8d},
- {0x0a8f, 0x0a91}, {0x0a93, 0x0aa8}, {0x0aaa, 0x0ab0}, {0x0ab5, 0x0ab9},
- {0x0abc, 0x0ac5}, {0x0ac7, 0x0ac9}, {0x0acb, 0x0acd}, {0x0ae0, 0x0ae3},
- {0x0ae6, 0x0aef}, {0x0b01, 0x0b03}, {0x0b05, 0x0b0c}, {0x0b13, 0x0b1f},
- {0x0b21, 0x0b28}, {0x0b2a, 0x0b30}, {0x0b35, 0x0b39}, {0x0b3c, 0x0b44},
- {0x0b4b, 0x0b4d}, {0x0b5f, 0x0b63}, {0x0b66, 0x0b77}, {0x0b85, 0x0b8a},
- {0x0b8e, 0x0b90}, {0x0b92, 0x0b95}, {0x0ba8, 0x0baa}, {0x0bae, 0x0bb9},
- {0x0bbe, 0x0bc2}, {0x0bc6, 0x0bc8}, {0x0bca, 0x0bcd}, {0x0be6, 0x0bfa},
- {0x0c01, 0x0c03}, {0x0c05, 0x0c0c}, {0x0c0e, 0x0c10}, {0x0c12, 0x0c1f},
- {0x0c21, 0x0c28}, {0x0c2a, 0x0c33}, {0x0c35, 0x0c39}, {0x0c3d, 0x0c44},
- {0x0c46, 0x0c48}, {0x0c4a, 0x0c4d}, {0x0c60, 0x0c63}, {0x0c66, 0x0c6f},
- {0x0c78, 0x0c7f}, {0x0c85, 0x0c8c}, {0x0c8e, 0x0c90}, {0x0c92, 0x0ca8},
- {0x0caa, 0x0cb3}, {0x0cb5, 0x0cb9}, {0x0cbc, 0x0cc4}, {0x0cc6, 0x0cc8},
- {0x0cca, 0x0ccd}, {0x0ce0, 0x0ce3}, {0x0ce6, 0x0cef}, {0x0d05, 0x0d0c},
- {0x0d0e, 0x0d10}, {0x0d12, 0x0d1f}, {0x0d21, 0x0d3a}, {0x0d3d, 0x0d44},
- {0x0d46, 0x0d48}, {0x0d4a, 0x0d4e}, {0x0d60, 0x0d63}, {0x0d66, 0x0d75},
- {0x0d79, 0x0d7f}, {0x0d85, 0x0d96}, {0x0d9a, 0x0db1}, {0x0db3, 0x0dbb},
- {0x0dc0, 0x0dc6}, {0x0dcf, 0x0dd4}, {0x0dd8, 0x0ddf}, {0x0df2, 0x0df4},
- {0x0e01, 0x0e1f}, {0x0e21, 0x0e3a}, {0x0e3f, 0x0e5b}, {0x0e94, 0x0e97},
- {0x0e99, 0x0e9f}, {0x0ea1, 0x0ea3}, {0x0ead, 0x0eb9}, {0x0ebb, 0x0ebd},
- {0x0ec0, 0x0ec4}, {0x0ec8, 0x0ecd}, {0x0ed0, 0x0ed9}, {0x0f00, 0x0f1f},
- {0x0f21, 0x0f47}, {0x0f49, 0x0f6c}, {0x0f71, 0x0f97}, {0x0f99, 0x0fbc},
- {0x0fbe, 0x0fcc}, {0x0fce, 0x0fda}, {0x1000, 0x101f}, {0x1021, 0x10c5},
- {0x10d0, 0x10fc}, {0x1100, 0x111f}, {0x1121, 0x121f}, {0x1221, 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, 0x131f}, {0x1321, 0x135a}, {0x135d, 0x137c}, {0x1380, 0x1399},
- {0x13a0, 0x13f4}, {0x1400, 0x141f}, {0x1421, 0x151f}, {0x1521, 0x161f},
- {0x1621, 0x169c}, {0x16a0, 0x16f0}, {0x1700, 0x170c}, {0x170e, 0x1714},
- {0x1721, 0x1736}, {0x1740, 0x1753}, {0x1760, 0x176c}, {0x176e, 0x1770},
- {0x1780, 0x17b3}, {0x17b6, 0x17dd}, {0x17e0, 0x17e9}, {0x17f0, 0x17f9},
- {0x1800, 0x180e}, {0x1810, 0x1819}, {0x1821, 0x1877}, {0x1880, 0x18aa},
- {0x18b0, 0x18f5}, {0x1900, 0x191c}, {0x1921, 0x192b}, {0x1930, 0x193b},
- {0x1944, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9},
- {0x19d0, 0x19da}, {0x19de, 0x1a1b}, {0x1a21, 0x1a5e}, {0x1a60, 0x1a7c},
- {0x1a7f, 0x1a89}, {0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, {0x1b00, 0x1b1f},
- {0x1b21, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1baa}, {0x1bae, 0x1bb9},
- {0x1bc0, 0x1bf3}, {0x1bfc, 0x1c1f}, {0x1c21, 0x1c37}, {0x1c3b, 0x1c49},
- {0x1c4d, 0x1c7f}, {0x1cd0, 0x1cf2}, {0x1d00, 0x1d1f}, {0x1d21, 0x1de6},
- {0x1dfc, 0x1e1f}, {0x1e21, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f21, 0x1f45},
+ {0x21, 0x7e}, {0xa1, 0xac}, {0xae, 0x377}, {0x37a, 0x37e},
+ {0x384, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x527}, {0x531, 0x556},
+ {0x559, 0x55f}, {0x561, 0x587}, {0x591, 0x5c7}, {0x5d0, 0x5ea},
+ {0x5f0, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc}, {0x6de, 0x70d},
+ {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa}, {0x800, 0x82d},
+ {0x830, 0x83e}, {0x840, 0x85b}, {0x8a2, 0x8ac}, {0x8e4, 0x8fe},
+ {0x900, 0x977}, {0x979, 0x97f}, {0x981, 0x983}, {0x985, 0x98c},
+ {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9bc, 0x9c4},
+ {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fb}, {0xa01, 0xa03},
+ {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa3e, 0xa42},
+ {0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa75}, {0xa81, 0xa83},
+ {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0},
+ {0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9}, {0xacb, 0xacd},
+ {0xae0, 0xae3}, {0xae6, 0xaf1}, {0xb01, 0xb03}, {0xb05, 0xb0c},
+ {0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb3c, 0xb44},
+ {0xb4b, 0xb4d}, {0xb5f, 0xb63}, {0xb66, 0xb77}, {0xb85, 0xb8a},
+ {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9},
+ {0xbbe, 0xbc2}, {0xbc6, 0xbc8}, {0xbca, 0xbcd}, {0xbe6, 0xbfa},
+ {0xc01, 0xc03}, {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28},
+ {0xc2a, 0xc33}, {0xc35, 0xc39}, {0xc3d, 0xc44}, {0xc46, 0xc48},
+ {0xc4a, 0xc4d}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc78, 0xc7f},
+ {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3},
+ {0xcb5, 0xcb9}, {0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd},
+ {0xce0, 0xce3}, {0xce6, 0xcef}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
+ {0xd12, 0xd3a}, {0xd3d, 0xd44}, {0xd46, 0xd48}, {0xd4a, 0xd4e},
+ {0xd60, 0xd63}, {0xd66, 0xd75}, {0xd79, 0xd7f}, {0xd85, 0xd96},
+ {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, {0xdcf, 0xdd4},
+ {0xdd8, 0xddf}, {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, 0x13f4}, {0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f0},
+ {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, 0x191c}, {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},
+ {0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37},
+ {0x1c3b, 0x1c49}, {0x1c4d, 0x1c7f}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf6},
+ {0x1d00, 0x1de6}, {0x1dfc, 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}, {0x2000, 0x200a}, {0x2010, 0x201f},
- {0x2021, 0x2029}, {0x202f, 0x205f}, {0x2074, 0x208e}, {0x2090, 0x209c},
- {0x20a0, 0x20b9}, {0x20d0, 0x20f0}, {0x2100, 0x211f}, {0x2121, 0x2189},
- {0x2190, 0x221f}, {0x2221, 0x231f}, {0x2321, 0x23f3}, {0x2400, 0x241f},
- {0x2421, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x251f}, {0x2521, 0x261f},
- {0x2621, 0x26ff}, {0x2701, 0x271f}, {0x2721, 0x27ca}, {0x27ce, 0x281f},
- {0x2821, 0x291f}, {0x2921, 0x2a1f}, {0x2a21, 0x2b1f}, {0x2b21, 0x2b4c},
- {0x2b50, 0x2b59}, {0x2c00, 0x2c1f}, {0x2c21, 0x2c2e}, {0x2c30, 0x2c5e},
- {0x2c60, 0x2cf1}, {0x2cf9, 0x2d1f}, {0x2d21, 0x2d25}, {0x2d30, 0x2d65},
+ {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe}, {0x2010, 0x2027}, {0x2030, 0x205e},
+ {0x2074, 0x208e}, {0x2090, 0x209c}, {0x20a0, 0x20ba}, {0x20d0, 0x20f0},
+ {0x2100, 0x2189}, {0x2190, 0x23f3}, {0x2400, 0x2426}, {0x2440, 0x244a},
+ {0x2460, 0x26ff}, {0x2701, 0x2b4c}, {0x2b50, 0x2b59}, {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, 0x2e1f}, {0x2e21, 0x2e31}, {0x2e80, 0x2e99},
- {0x2e9b, 0x2ef3}, {0x2f00, 0x2f1f}, {0x2f21, 0x2fd5}, {0x2ff0, 0x2ffb},
- {0x3000, 0x301f}, {0x3021, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff},
- {0x3105, 0x311f}, {0x3121, 0x312d}, {0x3131, 0x318e}, {0x3190, 0x31ba},
- {0x31c0, 0x31e3}, {0x31f0, 0x321e}, {0x3221, 0x32fe}, {0x3300, 0x331f},
- {0x3321, 0x341f}, {0x3421, 0x351f}, {0x3521, 0x361f}, {0x3621, 0x371f},
- {0x3721, 0x381f}, {0x3821, 0x391f}, {0x3921, 0x3a1f}, {0x3a21, 0x3b1f},
- {0x3b21, 0x3c1f}, {0x3c21, 0x3d1f}, {0x3d21, 0x3e1f}, {0x3e21, 0x3f1f},
- {0x3f21, 0x401f}, {0x4021, 0x411f}, {0x4121, 0x421f}, {0x4221, 0x431f},
- {0x4321, 0x441f}, {0x4421, 0x451f}, {0x4521, 0x461f}, {0x4621, 0x471f},
- {0x4721, 0x481f}, {0x4821, 0x491f}, {0x4921, 0x4a1f}, {0x4a21, 0x4b1f},
- {0x4b21, 0x4c1f}, {0x4c21, 0x4d1f}, {0x4d21, 0x4db5}, {0x4dc0, 0x4e1f},
- {0x4e21, 0x4f1f}, {0x4f21, 0x501f}, {0x5021, 0x511f}, {0x5121, 0x521f},
- {0x5221, 0x531f}, {0x5321, 0x541f}, {0x5421, 0x551f}, {0x5521, 0x561f},
- {0x5621, 0x571f}, {0x5721, 0x581f}, {0x5821, 0x591f}, {0x5921, 0x5a1f},
- {0x5a21, 0x5b1f}, {0x5b21, 0x5c1f}, {0x5c21, 0x5d1f}, {0x5d21, 0x5e1f},
- {0x5e21, 0x5f1f}, {0x5f21, 0x601f}, {0x6021, 0x611f}, {0x6121, 0x621f},
- {0x6221, 0x631f}, {0x6321, 0x641f}, {0x6421, 0x651f}, {0x6521, 0x661f},
- {0x6621, 0x671f}, {0x6721, 0x681f}, {0x6821, 0x691f}, {0x6921, 0x6a1f},
- {0x6a21, 0x6b1f}, {0x6b21, 0x6c1f}, {0x6c21, 0x6d1f}, {0x6d21, 0x6e1f},
- {0x6e21, 0x6f1f}, {0x6f21, 0x701f}, {0x7021, 0x711f}, {0x7121, 0x721f},
- {0x7221, 0x731f}, {0x7321, 0x741f}, {0x7421, 0x751f}, {0x7521, 0x761f},
- {0x7621, 0x771f}, {0x7721, 0x781f}, {0x7821, 0x791f}, {0x7921, 0x7a1f},
- {0x7a21, 0x7b1f}, {0x7b21, 0x7c1f}, {0x7c21, 0x7d1f}, {0x7d21, 0x7e1f},
- {0x7e21, 0x7f1f}, {0x7f21, 0x801f}, {0x8021, 0x811f}, {0x8121, 0x821f},
- {0x8221, 0x831f}, {0x8321, 0x841f}, {0x8421, 0x851f}, {0x8521, 0x861f},
- {0x8621, 0x871f}, {0x8721, 0x881f}, {0x8821, 0x891f}, {0x8921, 0x8a1f},
- {0x8a21, 0x8b1f}, {0x8b21, 0x8c1f}, {0x8c21, 0x8d1f}, {0x8d21, 0x8e1f},
- {0x8e21, 0x8f1f}, {0x8f21, 0x901f}, {0x9021, 0x911f}, {0x9121, 0x921f},
- {0x9221, 0x931f}, {0x9321, 0x941f}, {0x9421, 0x951f}, {0x9521, 0x961f},
- {0x9621, 0x971f}, {0x9721, 0x981f}, {0x9821, 0x991f}, {0x9921, 0x9a1f},
- {0x9a21, 0x9b1f}, {0x9b21, 0x9c1f}, {0x9c21, 0x9d1f}, {0x9d21, 0x9e1f},
- {0x9e21, 0x9f1f}, {0x9f21, 0x9fcb}, {0xa000, 0xa01f}, {0xa021, 0xa11f},
- {0xa121, 0xa21f}, {0xa221, 0xa31f}, {0xa321, 0xa41f}, {0xa421, 0xa48c},
- {0xa490, 0xa4c6}, {0xa4d0, 0xa51f}, {0xa521, 0xa61f}, {0xa621, 0xa62b},
- {0xa640, 0xa673}, {0xa67c, 0xa697}, {0xa6a0, 0xa6f7}, {0xa700, 0xa71f},
- {0xa721, 0xa78e}, {0xa7a0, 0xa7a9}, {0xa7fa, 0xa81f}, {0xa821, 0xa82b},
- {0xa830, 0xa839}, {0xa840, 0xa877}, {0xa880, 0xa8c4}, {0xa8ce, 0xa8d9},
- {0xa8e0, 0xa8fb}, {0xa900, 0xa91f}, {0xa921, 0xa953}, {0xa95f, 0xa97c},
- {0xa980, 0xa9cd}, {0xa9cf, 0xa9d9}, {0xaa00, 0xaa1f}, {0xaa21, 0xaa36},
+ {0x2dd8, 0x2dde}, {0x2de0, 0x2e3b}, {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3},
+ {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb}, {0x3001, 0x303f}, {0x3041, 0x3096},
+ {0x3099, 0x30ff}, {0x3105, 0x312d}, {0x3131, 0x318e}, {0x3190, 0x31ba},
+ {0x31c0, 0x31e3}, {0x31f0, 0x321e}, {0x3220, 0x32fe}, {0x3300, 0x4db5},
+ {0x4dc0, 0x9fcc}, {0xa000, 0xa48c}, {0xa490, 0xa4c6}, {0xa4d0, 0xa62b},
+ {0xa640, 0xa697}, {0xa69f, 0xa6f7}, {0xa700, 0xa78e}, {0xa790, 0xa793},
+ {0xa7a0, 0xa7aa}, {0xa7f8, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877},
+ {0xa880, 0xa8c4}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa8fb}, {0xa900, 0xa953},
+ {0xa95f, 0xa97c}, {0xa980, 0xa9cd}, {0xa9cf, 0xa9d9}, {0xaa00, 0xaa36},
{0xaa40, 0xaa4d}, {0xaa50, 0xaa59}, {0xaa5c, 0xaa7b}, {0xaa80, 0xaac2},
- {0xaadb, 0xaadf}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16},
- {0xab21, 0xab26}, {0xab28, 0xab2e}, {0xabc0, 0xabed}, {0xabf0, 0xabf9},
- {0xac00, 0xac1f}, {0xac21, 0xad1f}, {0xad21, 0xae1f}, {0xae21, 0xaf1f},
- {0xaf21, 0xb01f}, {0xb021, 0xb11f}, {0xb121, 0xb21f}, {0xb221, 0xb31f},
- {0xb321, 0xb41f}, {0xb421, 0xb51f}, {0xb521, 0xb61f}, {0xb621, 0xb71f},
- {0xb721, 0xb81f}, {0xb821, 0xb91f}, {0xb921, 0xba1f}, {0xba21, 0xbb1f},
- {0xbb21, 0xbc1f}, {0xbc21, 0xbd1f}, {0xbd21, 0xbe1f}, {0xbe21, 0xbf1f},
- {0xbf21, 0xc01f}, {0xc021, 0xc11f}, {0xc121, 0xc21f}, {0xc221, 0xc31f},
- {0xc321, 0xc41f}, {0xc421, 0xc51f}, {0xc521, 0xc61f}, {0xc621, 0xc71f},
- {0xc721, 0xc81f}, {0xc821, 0xc91f}, {0xc921, 0xca1f}, {0xca21, 0xcb1f},
- {0xcb21, 0xcc1f}, {0xcc21, 0xcd1f}, {0xcd21, 0xce1f}, {0xce21, 0xcf1f},
- {0xcf21, 0xd01f}, {0xd021, 0xd11f}, {0xd121, 0xd21f}, {0xd221, 0xd31f},
- {0xd321, 0xd41f}, {0xd421, 0xd51f}, {0xd521, 0xd61f}, {0xd621, 0xd71f},
- {0xd721, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xf91f},
- {0xf921, 0xfa1f}, {0xfa21, 0xfa2d}, {0xfa30, 0xfa6d}, {0xfa70, 0xfad9},
- {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb1f}, {0xfb21, 0xfb36},
- {0xfb38, 0xfb3c}, {0xfb46, 0xfbc1}, {0xfbd3, 0xfc1f}, {0xfc21, 0xfd1f},
- {0xfd21, 0xfd3f}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfd},
- {0xfe00, 0xfe19}, {0xfe21, 0xfe26}, {0xfe30, 0xfe52}, {0xfe54, 0xfe66},
- {0xfe68, 0xfe6b}, {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff01, 0xff1f},
- {0xff21, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7},
- {0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee}, {0xfffc, 0xffff}
+ {0xaadb, 0xaaf6}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16},
+ {0xab20, 0xab26}, {0xab28, 0xab2e}, {0xabc0, 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, 0xfe26},
+ {0xfe30, 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
+ ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
+ {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133},
+ {0x10137, 0x1018a}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c},
+ {0x102a0, 0x102d0}, {0x10300, 0x1031e}, {0x10320, 0x10323}, {0x10330, 0x1034a},
+ {0x10380, 0x1039d}, {0x1039f, 0x103c3}, {0x103c8, 0x103d5}, {0x10400, 0x1049d},
+ {0x104a0, 0x104a9}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855},
+ {0x10857, 0x1085f}, {0x10900, 0x1091b}, {0x1091f, 0x10939}, {0x10980, 0x109b7},
+ {0x10a00, 0x10a03}, {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33},
+ {0x10a38, 0x10a3a}, {0x10a3f, 0x10a47}, {0x10a50, 0x10a58}, {0x10a60, 0x10a7f},
+ {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72}, {0x10b78, 0x10b7f},
+ {0x10c00, 0x10c48}, {0x10e60, 0x10e7e}, {0x11000, 0x1104d}, {0x11052, 0x1106f},
+ {0x11080, 0x110bc}, {0x110be, 0x110c1}, {0x110d0, 0x110e8}, {0x110f0, 0x110f9},
+ {0x11100, 0x11134}, {0x11136, 0x11143}, {0x11180, 0x111c8}, {0x111d0, 0x111d9},
+ {0x11680, 0x116b7}, {0x116c0, 0x116c9}, {0x12000, 0x1236e}, {0x12400, 0x12462},
+ {0x12470, 0x12473}, {0x13000, 0x1342e}, {0x16800, 0x16a38}, {0x16f00, 0x16f44},
+ {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126},
+ {0x1d129, 0x1d172}, {0x1d17b, 0x1d1dd}, {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, 0x1d7ff}, {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, 0x1f0be}, {0x1f0c1, 0x1f0cf},
+ {0x1f0d1, 0x1f0df}, {0x1f100, 0x1f10a}, {0x1f110, 0x1f12e}, {0x1f130, 0x1f16b},
+ {0x1f170, 0x1f19a}, {0x1f1e6, 0x1f202}, {0x1f210, 0x1f23a}, {0x1f240, 0x1f248},
+ {0x1f300, 0x1f320}, {0x1f330, 0x1f335}, {0x1f337, 0x1f37c}, {0x1f380, 0x1f393},
+ {0x1f3a0, 0x1f3c4}, {0x1f3c6, 0x1f3ca}, {0x1f3e0, 0x1f3f0}, {0x1f400, 0x1f43e},
+ {0x1f442, 0x1f4f7}, {0x1f4f9, 0x1f4fc}, {0x1f500, 0x1f53d}, {0x1f540, 0x1f543},
+ {0x1f550, 0x1f567}, {0x1f5fb, 0x1f640}, {0x1f645, 0x1f64f}, {0x1f680, 0x1f6c5},
+ {0x1f700, 0x1f773}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d},
+ {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
+#endif
};
#define NUM_GRAPH_RANGE (sizeof(graphRangeTable)/sizeof(crange))
static const chr graphCharTable[] = {
- 0x038c, 0x0589, 0x058a, 0x061e, 0x061f, 0x085e, 0x098f, 0x0990, 0x09b2,
- 0x09c7, 0x09c8, 0x09d7, 0x09dc, 0x09dd, 0x0a0f, 0x0a10, 0x0a32, 0x0a33,
- 0x0a35, 0x0a36, 0x0a38, 0x0a39, 0x0a3c, 0x0a47, 0x0a48, 0x0a51, 0x0a5e,
- 0x0ab2, 0x0ab3, 0x0ad0, 0x0af1, 0x0b0f, 0x0b10, 0x0b32, 0x0b33, 0x0b47,
- 0x0b48, 0x0b56, 0x0b57, 0x0b5c, 0x0b5d, 0x0b82, 0x0b83, 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9e, 0x0b9f, 0x0ba3, 0x0ba4, 0x0bd0, 0x0bd7, 0x0c55, 0x0c56,
- 0x0c58, 0x0c59, 0x0c82, 0x0c83, 0x0cd5, 0x0cd6, 0x0cde, 0x0cf1, 0x0cf2,
- 0x0d02, 0x0d03, 0x0d57, 0x0d82, 0x0d83, 0x0dbd, 0x0dca, 0x0dd6, 0x0e81,
- 0x0e82, 0x0e84, 0x0e87, 0x0e88, 0x0e8a, 0x0e8d, 0x0ea5, 0x0ea7, 0x0eaa,
- 0x0eab, 0x0ec6, 0x0edc, 0x0edd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940,
- 0x1a1e, 0x1a1f, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x27cc, 0x2d6f,
- 0x2d70, 0xa790, 0xa791, 0xa9de, 0xa9df, 0xfb3e, 0xfb40, 0xfb41, 0xfb43,
- 0xfb44
+ 0x38c, 0x589, 0x58a, 0x58f, 0x85e, 0x8a0, 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, 0xc58,
+ 0xc59, 0xc82, 0xc83, 0xcd5, 0xcd6, 0xcde, 0xcf1, 0xcf2, 0xd02,
+ 0xd03, 0xd57, 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81, 0xe82,
+ 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab,
+ 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940, 0x1f59,
+ 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xa9de,
+ 0xa9df, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd
+#if TCL_UTF_MAX > 4
+ ,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x1093f, 0x109be, 0x109bf,
+ 0x10a05, 0x10a06, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6,
+ 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42,
+ 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b,
+ 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e, 0x1eef0, 0x1eef1, 0x1f250,
+ 0x1f251, 0x1f440
+#endif
};
#define NUM_GRAPH_CHAR (sizeof(graphCharTable)/sizeof(chr))
/*
- * Unicode: unicode print characters including space, i.e. all Letters (class
- * L*), Numbers (N*), Punctuation (P*), Symbols (S*) and Spaces (Zs).
- */
-
-static const crange printRangeTable[] = {
- {0x0020, 0x007E}, {0x00A0, 0x01F5}, {0x01FA, 0x0217}, {0x0250, 0x02A8},
- {0x02B0, 0x02DE}, {0x02E0, 0x02E9}, {0x0374, 0x0375}, {0x0384, 0x038A},
- {0x038E, 0x03A1}, {0x03A3, 0x03CE}, {0x03D0, 0x03D6}, {0x03E2, 0x03F3},
- {0x0401, 0x040C}, {0x040E, 0x044F}, {0x0451, 0x045C}, {0x045E, 0x0482},
- {0x0490, 0x04C4}, {0x04C7, 0x04C8}, {0x04CB, 0x04CC}, {0x04D0, 0x04EB},
- {0x04EE, 0x04F5}, {0x04F8, 0x04F9}, {0x0531, 0x0556}, {0x0559, 0x055F},
- {0x0561, 0x0587}, {0x05D0, 0x05EA}, {0x05F0, 0x05F4}, {0x0621, 0x063A},
- {0x0640, 0x064A}, {0x0660, 0x066D}, {0x0671, 0x06B7}, {0x06BA, 0x06BE},
- {0x06C0, 0x06CE}, {0x06D0, 0x06D5}, {0x06E5, 0x06E6}, {0x06F0, 0x06F9},
- {0x0905, 0x0939}, {0x0958, 0x0961}, {0x0964, 0x0970}, {0x0985, 0x098C},
- {0x098F, 0x0990}, {0x0993, 0x09A8}, {0x09AA, 0x09B0}, {0x09B6, 0x09B9},
- {0x09DC, 0x09DD}, {0x09DF, 0x09E1}, {0x09E6, 0x09FA}, {0x0A05, 0x0A0A},
- {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, {0x0A32, 0x0A33},
- {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, {0x0A59, 0x0A5C}, {0x0A66, 0x0A6F},
- {0x0A72, 0x0A74}, {0x0A85, 0x0A8B}, {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8},
- {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0AE6, 0x0AEF},
- {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, {0x0B13, 0x0B28}, {0x0B2A, 0x0B30},
- {0x0B32, 0x0B33}, {0x0B36, 0x0B39}, {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61},
- {0x0B66, 0x0B70}, {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95},
- {0x0B99, 0x0B9A}, {0x0B9E, 0x0B9F}, {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA},
- {0x0BAE, 0x0BB5}, {0x0BB7, 0x0BB9}, {0x0BE7, 0x0BF2}, {0x0C05, 0x0C0C},
- {0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, {0x0C2A, 0x0C33}, {0x0C35, 0x0C39},
- {0x0C60, 0x0C61}, {0x0C66, 0x0C6F}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90},
- {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, {0x0CE0, 0x0CE1},
- {0x0CE6, 0x0CEF}, {0x0D05, 0x0D0C}, {0x0D0E, 0x0D10}, {0x0D12, 0x0D28},
- {0x0D2A, 0x0D39}, {0x0D60, 0x0D61}, {0x0D66, 0x0D6F}, {0x0E3F, 0x0E46},
- {0x0E4F, 0x0E5B}, {0x0E99, 0x0E9F}, {0x0EA1, 0x0EA3}, {0x0EAA, 0x0EAB},
- {0x0EAD, 0x0EB0}, {0x0EB2, 0x0EB3}, {0x0EC0, 0x0EC4}, {0x0ED0, 0x0ED9},
- {0x0EDC, 0x0EDD}, {0x0F00, 0x0F17}, {0x0F1A, 0x0F34}, {0x0F3A, 0x0F3D},
- {0x0F40, 0x0F47}, {0x0F49, 0x0F69}, {0x0F88, 0x0F8B}, {0x10A0, 0x10C5},
- {0x10D0, 0x10F6}, {0x1100, 0x1159}, {0x115F, 0x11A2}, {0x11A8, 0x11F9},
- {0x1E00, 0x1E9B}, {0x1EA0, 0x1EF9}, {0x1F00, 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}, {0x2000, 0x200B},
- {0x2010, 0x2027}, {0x2030, 0x2046}, {0x2074, 0x208E}, {0x20A0, 0x20AC},
- {0x2100, 0x2138}, {0x2153, 0x2182}, {0x2190, 0x21EA}, {0x2200, 0x22F1},
- {0x2302, 0x237A}, {0x2400, 0x2424}, {0x2440, 0x244A}, {0x2460, 0x24EA},
- {0x2500, 0x2595}, {0x25A0, 0x25EF}, {0x2600, 0x2613}, {0x261A, 0x266F},
- {0x2701, 0x2704}, {0x2706, 0x2709}, {0x270C, 0x2727}, {0x2729, 0x274B},
- {0x274F, 0x2752}, {0x2758, 0x275E}, {0x2761, 0x2767}, {0x2776, 0x2794},
- {0x2798, 0x27AF}, {0x27B1, 0x27BE}, {0x3000, 0x3029}, {0x3030, 0x3037},
- {0x3041, 0x3094}, {0x309B, 0x309E}, {0x30A1, 0x30FE}, {0x3105, 0x312C},
- {0x3131, 0x318E}, {0x3190, 0x319F}, {0x3200, 0x321C}, {0x3220, 0x3243},
- {0x3260, 0x327B}, {0x327F, 0x32B0}, {0x32C0, 0x32CB}, {0x32D0, 0x32FE},
- {0x3300, 0x3376}, {0x337B, 0x33DD}, {0x33E0, 0x33FE}, {0x4E00, 0x9FA5},
- {0xAC00, 0xD7A3}, {0xF900, 0xFA2D}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17},
- {0xFB1F, 0xFB36}, {0xFB38, 0xFB3C}, {0xFB40, 0xFB41}, {0xFB43, 0xFB44},
- {0xFB46, 0xFBB1}, {0xFBD3, 0xFD3F}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7},
- {0xFDF0, 0xFDFB}, {0xFE30, 0xFE44}, {0xFE49, 0xFE52}, {0xFE54, 0xFE66},
- {0xFE68, 0xFE6B}, {0xFE70, 0xFE72}, {0xFE76, 0xFEFC}, {0xFF01, 0xFF5E},
- {0xFF61, 0xFFBE}, {0xFFC2, 0xFFC7}, {0xFFCA, 0xFFCF}, {0xFFD2, 0xFFD7},
- {0xFFDA, 0xFFDC}, {0xFFE0, 0xFFE6}, {0xFFE8, 0xFFEE}, {0xFFFC, 0xFFFD}
-};
-
-#define NUM_PRINT_RANGE (sizeof(printRangeTable)/sizeof(crange))
-
-static const chr printCharTable[] = {
- 0x037A, 0x037E, 0x038C, 0x03DA, 0x03DC, 0x03DE, 0x03E0, 0x0589, 0x05BE,
- 0x05C0, 0x05C3, 0x060C, 0x061B, 0x061F, 0x06E9, 0x093D, 0x0950, 0x09B2,
- 0x0A5E, 0x0A8D, 0x0ABD, 0x0AD0, 0x0AE0, 0x0B3D, 0x0B9C, 0x0CDE, 0x0E01,
- 0x0E32, 0x0E81, 0x0E84, 0x0E87, 0x0E8A, 0x0E8D, 0x0E94, 0x0EA5, 0x0EA7,
- 0x0EBD, 0x0EC6, 0x0F36, 0x0F38, 0x0F85, 0x10FB, 0x1F59, 0x1F5B, 0x1F5D,
- 0x2070, 0x2300, 0x274D, 0x2756, 0x303F, 0xFB3E, 0xFE74
-};
-
-#define NUM_PRINT_CHAR (sizeof(printCharTable)/sizeof(chr))
-
-/*
* End of auto-generated Unicode character ranges declarations.
*/
@@ -916,15 +923,6 @@ cclass(
np = Tcl_UniCharToUtfDString(startp, (int)len, &ds);
/*
- * Remap lower and upper to alpha if the match is case insensitive.
- */
-
- if (cases && len == 5 && (strncmp("lower", np, 5) == 0
- || strncmp("upper", np, 5) == 0)) {
- np = "alpha";
- }
-
- /*
* Map the name to the corresponding enumerated value.
*/
@@ -942,22 +940,18 @@ cclass(
}
/*
+ * Remap lower and upper to alpha if the match is case insensitive.
+ */
+
+ if (cases && ((index == CC_LOWER) || (index == CC_UPPER))) {
+ index = CC_ALNUM;
+ }
+
+ /*
* Now compute the character class contents.
*/
switch((enum classes) index) {
- case CC_PRINT:
- cv = getcvec(v, NUM_PRINT_CHAR, NUM_PRINT_RANGE);
- if (cv) {
- for (i=0 ; (size_t)i<NUM_PRINT_CHAR ; i++) {
- addchr(cv, printCharTable[i]);
- }
- for (i=0 ; (size_t)i<NUM_PRINT_RANGE ; i++) {
- addrange(cv, printRangeTable[i].start,
- printRangeTable[i].end);
- }
- }
- break;
case CC_ALNUM:
cv = getcvec(v, NUM_ALPHA_CHAR, NUM_DIGIT_RANGE + NUM_ALPHA_RANGE);
if (cv) {
@@ -998,9 +992,16 @@ cclass(
addchr(cv, ' ');
break;
case CC_CNTRL:
- cv = getcvec(v, 0, 2);
- addrange(cv, 0x0, 0x1f);
- addrange(cv, 0x7f, 0x9f);
+ cv = getcvec(v, NUM_CONTROL_CHAR, NUM_CONTROL_RANGE);
+ if (cv) {
+ for (i=0 ; (size_t)i<NUM_CONTROL_RANGE ; i++) {
+ addrange(cv, controlRangeTable[i].start,
+ controlRangeTable[i].end);
+ }
+ for (i=0 ; (size_t)i<NUM_CONTROL_CHAR ; i++) {
+ addchr(cv, controlCharTable[i]);
+ }
+ }
break;
case CC_DIGIT:
cv = getcvec(v, 0, NUM_DIGIT_RANGE);
@@ -1076,6 +1077,25 @@ cclass(
}
}
break;
+ case CC_PRINT:
+ cv = getcvec(v, NUM_SPACE_CHAR + NUM_GRAPH_CHAR, NUM_SPACE_RANGE + NUM_GRAPH_RANGE - 1);
+ if (cv) {
+ for (i=1 ; (size_t)i<NUM_SPACE_RANGE ; i++) {
+ addrange(cv, spaceRangeTable[i].start,
+ spaceRangeTable[i].end);
+ }
+ for (i=0 ; (size_t)i<NUM_SPACE_CHAR ; i++) {
+ addchr(cv, spaceCharTable[i]);
+ }
+ for (i=0 ; (size_t)i<NUM_GRAPH_RANGE ; i++) {
+ addrange(cv, graphRangeTable[i].start,
+ graphRangeTable[i].end);
+ }
+ for (i=0 ; (size_t)i<NUM_GRAPH_CHAR ; i++) {
+ addchr(cv, graphCharTable[i]);
+ }
+ }
+ break;
case CC_GRAPH:
cv = getcvec(v, NUM_GRAPH_CHAR, NUM_GRAPH_RANGE);
if (cv) {
diff --git a/generic/regc_nfa.c b/generic/regc_nfa.c
index 4fb3ea6..42489dd 100644
--- a/generic/regc_nfa.c
+++ b/generic/regc_nfa.c
@@ -497,6 +497,62 @@ freearc(
}
/*
+ - hasnonemptyout - Does state have a non-EMPTY out arc?
+ ^ static int hasnonemptyout(struct state *);
+ */
+static int
+hasnonemptyout(
+ struct state *s)
+{
+ struct arc *a;
+
+ for (a = s->outs; a != NULL; a = a->outchain) {
+ if (a->type != EMPTY) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+ - nonemptyouts - count non-EMPTY out arcs of a state
+ ^ static int nonemptyouts(struct state *);
+ */
+static int
+nonemptyouts(
+ struct state *s)
+{
+ int n = 0;
+ struct arc *a;
+
+ for (a = s->outs; a != NULL; a = a->outchain) {
+ if (a->type != EMPTY) {
+ n++;
+ }
+ }
+ return n;
+}
+
+/*
+ - nonemptyins - count non-EMPTY in arcs of a state
+ ^ static int nonemptyins(struct state *);
+ */
+static int
+nonemptyins(
+ struct state *s)
+{
+ int n = 0;
+ struct arc *a;
+
+ for (a = s->ins; a != NULL; a = a->inchain) {
+ if (a->type != EMPTY) {
+ n++;
+ }
+ }
+ return n;
+}
+
+/*
- findarc - find arc, if any, from given source with given type and color
* If there is more than one such arc, the result is random.
^ static struct arc *findarc(struct state *, int, pcolor);
@@ -559,21 +615,25 @@ moveins(
}
/*
- - copyins - copy all in arcs of a state to another state
- ^ static void copyins(struct nfa *, struct state *, struct state *);
+ - copyins - copy in arcs of a state to another state
+ * Either all arcs, or only non-empty ones as determined by all value.
+ ^ static VOID copyins(struct nfa *, struct state *, struct state *, int);
*/
static void
copyins(
struct nfa *nfa,
struct state *oldState,
- struct state *newState)
+ struct state *newState,
+ int all)
{
struct arc *a;
assert(oldState != newState);
for (a=oldState->ins ; a!=NULL ; a=a->inchain) {
- cparc(nfa, a, a->from, newState);
+ if (all || a->type != EMPTY) {
+ cparc(nfa, a, a->from, newState);
+ }
}
}
@@ -598,21 +658,25 @@ moveouts(
}
/*
- - copyouts - copy all out arcs of a state to another state
- ^ static void copyouts(struct nfa *, struct state *, struct state *);
+ - copyouts - copy out arcs of a state to another state
+ * Either all arcs, or only non-empty ones as determined by all value.
+ ^ static VOID copyouts(struct nfa *, struct state *, struct state *, int);
*/
static void
copyouts(
struct nfa *nfa,
struct state *oldState,
- struct state *newState)
+ struct state *newState,
+ int all)
{
struct arc *a;
assert(oldState != newState);
for (a=oldState->outs ; a!=NULL ; a=a->outchain) {
- cparc(nfa, a, newState, a->to);
+ if (all || a->type != EMPTY) {
+ cparc(nfa, a, newState, a->to);
+ }
}
}
@@ -759,7 +823,9 @@ duptraverse(
* Arbitrary depth limit. Needs tuning, but this value is sufficient to
* make all normal tests (not reg-33.14) pass.
*/
-#define DUPTRAVERSE_MAX_DEPTH 500
+#ifndef DUPTRAVERSE_MAX_DEPTH
+#define DUPTRAVERSE_MAX_DEPTH 15000
+#endif
if (depth++ > DUPTRAVERSE_MAX_DEPTH) {
NERR(REG_ESPACE);
@@ -968,9 +1034,9 @@ pull(
if (NISERR()) {
return 0;
}
- assert(to != from); /* con is not an inarc */
- copyins(nfa, from, s); /* duplicate inarcs */
- cparc(nfa, con, s, to); /* move constraint arc */
+ assert(to != from); /* con is not an inarc */
+ copyins(nfa, from, s, 1); /* duplicate inarcs */
+ cparc(nfa, con, s, to); /* move constraint arc */
freearc(nfa, con);
from = s;
con = from->outs;
@@ -1128,7 +1194,7 @@ push(
if (NISERR()) {
return 0;
}
- copyouts(nfa, to, s); /* duplicate outarcs */
+ copyouts(nfa, to, s, 1); /* duplicate outarcs */
cparc(nfa, con, from, s); /* move constraint */
freearc(nfa, con);
to = s;
@@ -1245,100 +1311,209 @@ fixempties(
FILE *f) /* for debug output; NULL none */
{
struct state *s;
+ struct state *s2;
struct state *nexts;
struct arc *a;
struct arc *nexta;
- int progress;
/*
- * Find and eliminate empties until there are no more.
+ * First, get rid of any states whose sole out-arc is an EMPTY,
+ * since they're basically just aliases for their successor. The
+ * parsing algorithm creates enough of these that it's worth
+ * special-casing this.
*/
+ for (s = nfa->states; s != NULL && !NISERR(); s = nexts) {
+ nexts = s->next;
+ if (s->flag || s->nouts != 1) {
+ continue;
+ }
+ a = s->outs;
+ assert(a != NULL && a->outchain == NULL);
+ if (a->type != EMPTY) {
+ continue;
+ }
+ if (s != a->to) {
+ moveins(nfa, s, a->to);
+ }
+ dropstate(nfa, s);
+ }
- do {
- progress = 0;
- for (s = nfa->states; s != NULL && !NISERR()
- && s->no != FREESTATE; s = nexts) {
- nexts = s->next;
- for (a = s->outs; a != NULL && !NISERR(); a = nexta) {
- nexta = a->outchain;
- if (a->type == EMPTY && unempty(nfa, a)) {
- progress = 1;
- }
- assert(nexta == NULL || s->no != FREESTATE);
+ /*
+ * Similarly, get rid of any state with a single EMPTY in-arc, by
+ * folding it into its predecessor.
+ */
+ for (s = nfa->states; s != NULL && !NISERR(); s = nexts) {
+ nexts = s->next;
+ /* Ensure tmp fields are clear for next step */
+ assert(s->tmp = NULL);
+ if (s->flag || s->nins != 1) {
+ continue;
+ }
+ a = s->ins;
+ assert(a != NULL && a->inchain == NULL);
+ if (a->type != EMPTY) {
+ continue;
+ }
+ if (s != a->from) {
+ moveouts(nfa, s, a->from);
+ }
+ dropstate(nfa, s);
+ }
+
+ /*
+ * For each remaining NFA state, find all other states that are
+ * reachable from it by a chain of one or more EMPTY arcs. Then
+ * generate new arcs that eliminate the need for each such chain.
+ *
+ * If we just do this straightforwardly, the algorithm gets slow in
+ * complex graphs, because the same arcs get copied to all
+ * intermediate states of an EMPTY chain, and then uselessly pushed
+ * repeatedly to the chain's final state; we waste a lot of time in
+ * newarc's duplicate checking. To improve matters, we decree that
+ * any state with only EMPTY out-arcs is "doomed" and will not be
+ * part of the final NFA. That can be ensured by not adding any new
+ * out-arcs to such a state. Having ensured that, we need not update
+ * the state's in-arcs list either; all arcs that might have gotten
+ * pushed forward to it will just get pushed directly to successor
+ * states. This eliminates most of the useless duplicate arcs.
+ */
+ for (s = nfa->states; s != NULL && !NISERR(); s = s->next) {
+ for (s2 = emptyreachable(s, s); s2 != s && !NISERR();
+ s2 = nexts) {
+ /*
+ * If s2 is doomed, we decide that (1) we will always push
+ * arcs forward to it, not pull them back to s; and (2) we
+ * can optimize away the push-forward, per comment above.
+ * So do nothing.
+ */
+ if (s2->flag || hasnonemptyout(s2)) {
+ replaceempty(nfa, s, s2);
}
+
+ /* Reset the tmp fields as we walk back */
+ nexts = s2->tmp;
+ s2->tmp = NULL;
}
- if (progress && f != NULL) {
- dumpnfa(nfa, f);
+ s->tmp = NULL;
+ }
+ if (NISERR()) {
+ return;
+ }
+
+ /*
+ * Remove all the EMPTY arcs, since we don't need them anymore.
+ */
+ for (s = nfa->states; s != NULL; s = s->next) {
+ for (a = s->outs; a != NULL; a = nexta) {
+ nexta = a->outchain;
+ if (a->type == EMPTY) {
+ freearc(nfa, a);
+ }
}
- } while (progress && !NISERR());
+ }
+
+ /*
+ * And remove any states that have become useless. (This cleanup is
+ * not very thorough, and would be even less so if we tried to
+ * combine it with the previous step; but cleanup() will take care
+ * of anything we miss.)
+ */
+ for (s = nfa->states; s != NULL; s = nexts) {
+ nexts = s->next;
+ if ((s->nins == 0 || s->nouts == 0) && !s->flag) {
+ dropstate(nfa, s);
+ }
+ }
+
+ if (f != NULL) {
+ dumpnfa(nfa, f);
+ }
}
/*
- - unempty - optimize out an EMPTY arc, if possible
- * Actually, as it stands this function always succeeds, but the return value
- * is kept with an eye on possible future changes.
- ^ static int unempty(struct nfa *, struct arc *);
+ - emptyreachable - recursively find all states reachable from s by EMPTY arcs
+ * The return value is the last such state found. Its tmp field links back
+ * to the next-to-last such state, and so on back to s, so that all these
+ * states can be located without searching the whole NFA.
+ * The maximum recursion depth here is equal to the length of the longest
+ * loop-free chain of EMPTY arcs, which is surely no more than the size of
+ * the NFA, and in practice will be a lot less than that.
+ ^ static struct state *emptyreachable(struct state *, struct state *);
*/
-static int /* 0 couldn't, 1 could */
-unempty(
- struct nfa *nfa,
- struct arc *a)
+static struct state *
+emptyreachable(
+ struct state *s,
+ struct state *lastfound)
{
- struct state *from = a->from;
- struct state *to = a->to;
- int usefrom; /* work on from, as opposed to to? */
-
- assert(a->type == EMPTY);
- assert(from != nfa->pre && to != nfa->post);
+ struct arc *a;
- if (from == to) { /* vacuous loop */
- freearc(nfa, a);
- return 1;
+ s->tmp = lastfound;
+ lastfound = s;
+ for (a = s->outs; a != NULL; a = a->outchain) {
+ if (a->type == EMPTY && a->to->tmp == NULL) {
+ lastfound = emptyreachable(a->to, lastfound);
+ }
}
+ return lastfound;
+}
+
+/*
+ - replaceempty - replace an EMPTY arc chain with some non-empty arcs
+ * The EMPTY arc(s) should be deleted later, but we can't do it here because
+ * they may still be needed to identify other arc chains during fixempties().
+ ^ static void replaceempty(struct nfa *, struct state *, struct state *);
+ */
+static void
+replaceempty(
+ struct nfa *nfa,
+ struct state *from,
+ struct state *to)
+{
+ int fromouts;
+ int toins;
+
+ assert(from != to);
/*
- * Decide which end to work on.
+ * Create replacement arcs that bypass the need for the EMPTY chain. We
+ * can do this either by pushing arcs forward (linking directly from
+ * "from"'s predecessors to "to") or by pulling them back (linking
+ * directly from "from" to "to"'s successors). In general, we choose
+ * whichever way creates greater fan-out or fan-in, so as to improve the
+ * odds of reducing the other state to zero in-arcs or out-arcs and
+ * thereby being able to delete it. However, if "from" is doomed (has no
+ * non-EMPTY out-arcs), we must keep it so, so always push forward in that
+ * case.
+ *
+ * The fan-out/fan-in comparison should count only non-EMPTY arcs. If
+ * "from" is doomed, we can skip counting "to"'s arcs, since we want to
+ * force taking the copynonemptyins path in that case.
*/
+ fromouts = nonemptyouts(from);
+ toins = (fromouts == 0) ? 1 : nonemptyins(to);
- usefrom = 1; /* default: attack from */
- if (from->nouts > to->nins) {
- usefrom = 0;
- } else if (from->nouts == to->nins) {
- /*
- * Decide on secondary issue: move/copy fewest arcs.
- */
-
- if (from->nins > to->nouts) {
- usefrom = 0;
- }
+ if (fromouts > toins) {
+ copyouts(nfa, to, from, 0);
+ return;
+ }
+ if (fromouts < toins) {
+ copyins(nfa, from, to, 0);
+ return;
}
- freearc(nfa, a);
- if (usefrom) {
- if (from->nouts == 0) {
- /*
- * Was the state's only outarc.
- */
-
- moveins(nfa, from, to);
- freestate(nfa, from);
- } else {
- copyins(nfa, from, to);
- }
- } else {
- if (to->nins == 0) {
- /*
- * Was the state's only inarc.
- */
-
- moveouts(nfa, to, from);
- freestate(nfa, to);
- } else {
- copyouts(nfa, to, from);
- }
+ /*
+ * fromouts == toins. Decide on secondary issue: copy fewest arcs.
+ *
+ * Doesn't seem to be worth the trouble to exclude empties from these
+ * comparisons; that takes extra time and doesn't seem to improve the
+ * resulting graph much.
+ */
+ if (from->nins > to->nouts) {
+ copyouts(nfa, to, from, 0);
+ return;
}
- return 1;
+ copyins(nfa, from, to, 0);
}
/*
diff --git a/generic/regcomp.c b/generic/regcomp.c
index d7ae05e..c93eb24 100644
--- a/generic/regcomp.c
+++ b/generic/regcomp.c
@@ -79,7 +79,7 @@ static void lexnest(struct vars *, const chr *, const chr *);
static void lexword(struct vars *);
static int next(struct vars *);
static int lexescape(struct vars *);
-static chr lexdigits(struct vars *, int, int, int);
+static int lexdigits(struct vars *, int, int, int);
static int brenext(struct vars *, pchr);
static void skip(struct vars *);
static chr newline(NOPARMS);
@@ -121,12 +121,15 @@ static void destroystate(struct nfa *, struct state *);
static void newarc(struct nfa *, int, pcolor, struct state *, struct state *);
static struct arc *allocarc(struct nfa *, struct state *);
static void freearc(struct nfa *, struct arc *);
+static int hasnonemptyout(struct state *);
+static int nonemptyouts(struct state *);
+static int nonemptyins(struct state *);
static struct arc *findarc(struct state *, int, pcolor);
static void cparc(struct nfa *, struct arc *, struct state *, struct state *);
static void moveins(struct nfa *, struct state *, struct state *);
-static void copyins(struct nfa *, struct state *, struct state *);
+static void copyins(struct nfa *, struct state *, struct state *, int);
static void moveouts(struct nfa *, struct state *, struct state *);
-static void copyouts(struct nfa *, struct state *, struct state *);
+static void copyouts(struct nfa *, struct state *, struct state *, int);
static void cloneouts(struct nfa *, struct state *, struct state *, struct state *, int);
static void delsub(struct nfa *, struct state *, struct state *);
static void deltraverse(struct nfa *, struct state *, struct state *);
@@ -144,7 +147,8 @@ static int push(struct nfa *, struct arc *);
#define COMPATIBLE 3 /* compatible but not satisfied yet */
static int combine(struct arc *, struct arc *);
static void fixempties(struct nfa *, FILE *);
-static int unempty(struct nfa *, struct arc *);
+static struct state *emptyreachable(struct state *, struct state *);
+static void replaceempty(struct nfa *, struct state *, struct state *);
static void cleanup(struct nfa *);
static void markreachable(struct nfa *, struct state *, struct state *, struct state *);
static void markcanreach(struct nfa *, struct state *, struct state *, struct state *);
@@ -607,7 +611,7 @@ makesearch(
for (s=slist ; s!=NULL ; s=s2) {
s2 = newstate(nfa);
- copyouts(nfa, s, s2);
+ copyouts(nfa, s, s2, 1);
for (a=s->ins ; a!=NULL ; a=b) {
b = a->inchain;
@@ -738,6 +742,7 @@ parsebranch(
/* NB, recursion in parseqatom() may swallow rest of branch */
parseqatom(v, stopper, type, lp, right, t);
+ NOERRN();
}
if (!seencontent) { /* empty branch */
@@ -1234,6 +1239,7 @@ parseqatom(
EMPTYARC(atom->end, rp);
t->right = subre(v, '=', 0, atom->end, rp);
}
+ NOERR();
assert(SEE('|') || SEE(stopper) || SEE(EOS));
t->flags |= COMBINE(t->flags, t->right->flags);
top->flags |= COMBINE(top->flags, t->flags);
diff --git a/generic/regcustom.h b/generic/regcustom.h
index bc8c28c..1c970ea 100644
--- a/generic/regcustom.h
+++ b/generic/regcustom.h
@@ -97,7 +97,7 @@ typedef int celt; /* Type to hold chr, or NOCELT */
#define NOCELT (-1) /* Celt value which is not valid chr */
#define CHR(c) (UCHAR(c)) /* Turn char literal into chr literal */
#define DIGITVAL(c) ((c)-'0') /* Turn chr digit into its value */
-#if TCL_UTF_MAX > 3
+#if TCL_UTF_MAX > 4
#define CHRBITS 32 /* Bits in a chr; must not use sizeof */
#define CHR_MIN 0x00000000 /* Smallest and largest chr; the value */
#define CHR_MAX 0xffffffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
diff --git a/generic/regerrs.h b/generic/regerrs.h
index 259c0cb..72548ff 100644
--- a/generic/regerrs.h
+++ b/generic/regerrs.h
@@ -17,3 +17,4 @@
{ REG_MIXED, "REG_MIXED", "character widths of regex and string differ" },
{ REG_BADOPT, "REG_BADOPT", "invalid embedded option" },
{ REG_ETOOBIG, "REG_ETOOBIG", "nfa has too many states" },
+{ REG_ECOLORS, "REG_ECOLORS", "too many colors" },
diff --git a/generic/regex.h b/generic/regex.h
index d6d46ce..9466fbb 100644
--- a/generic/regex.h
+++ b/generic/regex.h
@@ -281,6 +281,7 @@ typedef struct {
#define REG_MIXED 17 /* character widths of regex and string differ */
#define REG_BADOPT 18 /* invalid embedded option */
#define REG_ETOOBIG 19 /* nfa has too many states */
+#define REG_ECOLORS 20 /* too many colors */
/* two specials for debugging and testing */
#define REG_ATOI 101 /* convert error-code name to number */
#define REG_ITOA 102 /* convert error-code number to name */
diff --git a/generic/regexec.c b/generic/regexec.c
index 9b6a693..ad4b6e6 100644
--- a/generic/regexec.c
+++ b/generic/regexec.c
@@ -504,12 +504,7 @@ complicatedFindLoop(
return er;
}
if ((shorter) ? end == estop : end == begin) {
- /*
- * No point in trying again.
- */
-
- *coldp = cold;
- return REG_NOMATCH;
+ break;
}
/*
diff --git a/generic/regguts.h b/generic/regguts.h
index e57b8f8..b478e4c 100644
--- a/generic/regguts.h
+++ b/generic/regguts.h
@@ -145,6 +145,7 @@
typedef short color; /* colors of characters */
typedef int pcolor; /* what color promotes to */
+#define MAX_COLOR SHRT_MAX /* max color value */
#define COLORLESS (-1) /* impossible color */
#define WHITE 0 /* default color, parent of all others */
@@ -340,12 +341,12 @@ struct subre {
#define CAP 010 /* capturing parens below */
#define BACKR 020 /* back reference below */
#define INUSE 0100 /* in use in final tree */
-#define LOCAL 03 /* bits which may not propagate up */
+#define NOPROP 03 /* bits which may not propagate up */
#define LMIX(f) ((f)<<2) /* LONGER -> MIXED */
#define SMIX(f) ((f)<<1) /* SHORTER -> MIXED */
-#define UP(f) (((f)&~LOCAL) | (LMIX(f) & SMIX(f) & MIXED))
+#define UP(f) (((f)&~NOPROP) | (LMIX(f) & SMIX(f) & MIXED))
#define MESSY(f) ((f)&(MIXED|CAP|BACKR))
-#define PREF(f) ((f)&LOCAL)
+#define PREF(f) ((f)&NOPROP)
#define PREF2(f1, f2) ((PREF(f1) != 0) ? PREF(f1) : PREF(f2))
#define COMBINE(f1, f2) (UP((f1)|(f2)) | PREF2(f1, f2))
short retry; /* index into retry memory */
@@ -366,7 +367,7 @@ struct subre {
*/
struct fns {
- VOID FUNCPTR(free, (regex_t *));
+ void FUNCPTR(free, (regex_t *));
};
/*
diff --git a/generic/tcl.decls b/generic/tcl.decls
index 30a2aca..1829249 100644
--- a/generic/tcl.decls
+++ b/generic/tcl.decls
@@ -774,10 +774,10 @@ declare 216 {
declare 217 {
void Tcl_ResetResult(Tcl_Interp *interp)
}
-declare 218 generic {
+declare 218 {
int Tcl_ScanElement(const char *src, int *flagPtr)
}
-declare 219 generic {
+declare 219 {
int Tcl_ScanCountedElement(const char *src, int length, int *flagPtr)
}
# Obsolete
@@ -2311,13 +2311,19 @@ declare 627 {
Tcl_LoadHandle *handlePtr)
}
declare 628 {
- void* Tcl_FindSymbol(Tcl_Interp *interp, Tcl_LoadHandle handle,
+ void *Tcl_FindSymbol(Tcl_Interp *interp, Tcl_LoadHandle handle,
const char *symbol)
}
declare 629 {
int Tcl_FSUnloadFile(Tcl_Interp *interp, Tcl_LoadHandle handlePtr)
}
+# TIP #400
+declare 630 {
+ void Tcl_ZlibStreamSetCompressionDictionary(Tcl_ZlibStream zhandle,
+ Tcl_Obj *compressionDictionaryObj)
+}
+
# ----- BASELINE -- FOR -- 8.6.0 ----- #
##############################################################################
@@ -2365,6 +2371,14 @@ export {
void Tcl_Main(int argc, char **argv, Tcl_AppInitProc *appInitProc)
}
export {
+ const char *Tcl_InitStubs(Tcl_Interp *interp, const char *version,
+ int exact)
+}
+export {
+ const char *TclTomMathInitializeStubs(Tcl_Interp* interp,
+ const char* version, int epoch, int revision)
+}
+export {
const char *Tcl_PkgInitStubsCheck(Tcl_Interp *interp, const char *version,
int exact)
}
diff --git a/generic/tcl.h b/generic/tcl.h
index 54bfedc..e557290 100644
--- a/generic/tcl.h
+++ b/generic/tcl.h
@@ -51,17 +51,15 @@ extern "C" {
* win/README (not patchlevel) (sections 0 and 2)
* unix/tcl.spec (1 LOC patch)
* tools/tcl.hpj.in (not patchlevel, for windows installer)
- * tools/tcl.wse.in (for windows installer)
- * tools/tclSplash.bmp (not patchlevel)
*/
#define TCL_MAJOR_VERSION 8
#define TCL_MINOR_VERSION 6
-#define TCL_RELEASE_LEVEL TCL_BETA_RELEASE
-#define TCL_RELEASE_SERIAL 2
+#define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE
+#define TCL_RELEASE_SERIAL 1
#define TCL_VERSION "8.6"
-#define TCL_PATCH_LEVEL "8.6b2"
+#define TCL_PATCH_LEVEL "8.6.1"
/*
*----------------------------------------------------------------------------
@@ -69,15 +67,12 @@ extern "C" {
* We use this method because there is no autoconf equivalent.
*/
-#ifndef __WIN32__
-# if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || defined(__BORLANDC__) || (defined(__WATCOMC__) && defined(__WINDOWS_386__))
+#ifdef _WIN32
+# ifndef __WIN32__
# define __WIN32__
-# ifndef WIN32
-# define WIN32
-# endif
-# ifndef _WIN32
-# define _WIN32
-# endif
+# endif
+# ifndef WIN32
+# define WIN32
# endif
#endif
@@ -85,11 +80,11 @@ extern "C" {
* STRICT: See MSDN Article Q83456
*/
-#ifdef __WIN32__
+#ifdef _WIN32
# ifndef STRICT
# define STRICT
# endif
-#endif /* __WIN32__ */
+#endif /* _WIN32 */
/*
* Utility macros: STRINGIFY takes an argument and wraps it in "" (double
@@ -163,6 +158,23 @@ extern "C" {
#endif
/*
+ * Allow a part of Tcl's API to be explicitly marked as deprecated.
+ *
+ * Used to make TIP 330/336 generate moans even if people use the
+ * compatibility macros. Change your code, guys! We won't support you forever.
+ */
+
+#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
+# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5))
+# define TCL_DEPRECATED_API(msg) __attribute__ ((__deprecated__ (msg)))
+# else
+# define TCL_DEPRECATED_API(msg) __attribute__ ((__deprecated__))
+# endif
+#else
+# define TCL_DEPRECATED_API(msg) /* nothing portable */
+#endif
+
+/*
*----------------------------------------------------------------------------
* Macros used to declare a function to be exported by a DLL. Used by Windows,
* maps to no-op declarations on non-Windows systems. The default build on
@@ -176,7 +188,7 @@ extern "C" {
* MSVCRT.
*/
-#if (defined(__WIN32__) && (defined(_MSC_VER) || (__BORLANDC__ >= 0x0550) || defined(__LCC__) || defined(__WATCOMC__) || (defined(__GNUC__) && defined(__declspec))))
+#if (defined(_WIN32) && (defined(_MSC_VER) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0550)) || defined(__LCC__) || defined(__WATCOMC__) || (defined(__GNUC__) && defined(__declspec))))
# define HAVE_DECLSPEC 1
# ifdef STATIC_BUILD
# define DLLIMPORT
@@ -300,24 +312,26 @@ extern "C" {
* VOID. This block is skipped under Cygwin and Mingw.
*/
-#if defined(__WIN32__) && !defined(HAVE_WINNT_IGNORE_VOID)
+#if defined(_WIN32) && !defined(HAVE_WINNT_IGNORE_VOID)
#ifndef VOID
#define VOID void
typedef char CHAR;
typedef short SHORT;
typedef long LONG;
#endif
-#endif /* __WIN32__ && !HAVE_WINNT_IGNORE_VOID */
+#endif /* _WIN32 && !HAVE_WINNT_IGNORE_VOID */
/*
* Macro to use instead of "void" for arguments that must have type "void *"
* in ANSI C; maps them to type "char *" in non-ANSI systems.
*/
-#ifndef NO_VOID
-# define VOID void
-#else
-# define VOID char
+#ifndef __VXWORKS__
+# ifndef NO_VOID
+# define VOID void
+# else
+# define VOID char
+# endif
#endif
/*
@@ -373,30 +387,17 @@ typedef long LONG;
*/
#if !defined(TCL_WIDE_INT_TYPE)&&!defined(TCL_WIDE_INT_IS_LONG)
-# if defined(__WIN32__) && !defined(__CYGWIN__)
+# if defined(_WIN32)
# define TCL_WIDE_INT_TYPE __int64
# ifdef __BORLANDC__
-typedef struct stati64 Tcl_StatBuf;
# define TCL_LL_MODIFIER "L"
# else /* __BORLANDC__ */
-# if defined(_WIN64)
-typedef struct __stat64 Tcl_StatBuf;
-# elif (defined(_MSC_VER) && (_MSC_VER < 1400))
-typedef struct _stati64 Tcl_StatBuf;
-# else
-typedef struct _stat32i64 Tcl_StatBuf;
-# endif /* _MSC_VER < 1400 */
# define TCL_LL_MODIFIER "I64"
# endif /* __BORLANDC__ */
# elif defined(__GNUC__)
# define TCL_WIDE_INT_TYPE long long
# define TCL_LL_MODIFIER "ll"
-# if defined(__WIN32__)
-typedef struct _stat32i64 Tcl_StatBuf;
-# else
-typedef struct stat Tcl_StatBuf;
-# endif
-# else /* ! __WIN32__ && ! __GNUC__ */
+# else /* ! _WIN32 && ! __GNUC__ */
/*
* Don't know what platform it is and configure hasn't discovered what is
* going on for us. Try to guess...
@@ -411,7 +412,7 @@ typedef struct stat Tcl_StatBuf;
# define TCL_WIDE_INT_TYPE long long
# endif
# endif /* NO_LIMITS_H */
-# endif /* __WIN32__ */
+# endif /* _WIN32 */
#endif /* !TCL_WIDE_INT_TYPE & !TCL_WIDE_INT_IS_LONG */
#ifdef TCL_WIDE_INT_IS_LONG
# undef TCL_WIDE_INT_TYPE
@@ -422,7 +423,6 @@ typedef TCL_WIDE_INT_TYPE Tcl_WideInt;
typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt;
#ifdef TCL_WIDE_INT_IS_LONG
-typedef struct stat Tcl_StatBuf;
# define Tcl_WideAsLong(val) ((long)(val))
# define Tcl_LongAsWide(val) ((long)(val))
# define Tcl_WideAsDouble(val) ((double)((long)(val)))
@@ -436,11 +436,6 @@ typedef struct stat Tcl_StatBuf;
* or some other strange platform.
*/
# ifndef TCL_LL_MODIFIER
-# ifdef HAVE_STRUCT_STAT64
-typedef struct stat64 Tcl_StatBuf;
-# else
-typedef struct stat Tcl_StatBuf;
-# endif /* HAVE_STRUCT_STAT64 */
# define TCL_LL_MODIFIER "ll"
# endif /* !TCL_LL_MODIFIER */
# define Tcl_WideAsLong(val) ((long)((Tcl_WideInt)(val)))
@@ -448,6 +443,39 @@ typedef struct stat Tcl_StatBuf;
# define Tcl_WideAsDouble(val) ((double)((Tcl_WideInt)(val)))
# define Tcl_DoubleAsWide(val) ((Tcl_WideInt)((double)(val)))
#endif /* TCL_WIDE_INT_IS_LONG */
+
+#if defined(_WIN32)
+# ifdef __BORLANDC__
+ typedef struct stati64 Tcl_StatBuf;
+# elif defined(_WIN64)
+ typedef struct __stat64 Tcl_StatBuf;
+# elif (defined(_MSC_VER) && (_MSC_VER < 1400)) || defined(_USE_32BIT_TIME_T)
+ typedef struct _stati64 Tcl_StatBuf;
+# else
+ typedef struct _stat32i64 Tcl_StatBuf;
+# endif /* _MSC_VER < 1400 */
+#elif defined(__CYGWIN__)
+ typedef struct {
+ dev_t st_dev;
+ unsigned short st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ /* Here is a 2-byte gap */
+ dev_t st_rdev;
+ /* Here is a 4-byte gap */
+ long long st_size;
+ struct {long tv_sec;} st_atim;
+ struct {long tv_sec;} st_mtim;
+ struct {long tv_sec;} st_ctim;
+ /* Here is a 4-byte gap */
+ } Tcl_StatBuf;
+#elif defined(HAVE_STRUCT_STAT64) && !defined(__APPLE__)
+ typedef struct stat64 Tcl_StatBuf;
+#else
+ typedef struct stat Tcl_StatBuf;
+#endif
/*
*----------------------------------------------------------------------------
@@ -469,13 +497,17 @@ typedef struct stat Tcl_StatBuf;
* accessed with Tcl_GetObjResult() and Tcl_SetObjResult().
*/
-typedef struct Tcl_Interp {
+typedef struct Tcl_Interp
+#ifndef TCL_NO_DEPRECATED
+{
/* TIP #330: Strongly discourage extensions from using the string
* result. */
#ifdef USE_INTERP_RESULT
- char *result; /* If the last command returned a string
+ char *result TCL_DEPRECATED_API("use Tcl_GetStringResult/Tcl_SetResult");
+ /* If the last command returned a string
* result, this points to it. */
- void (*freeProc) (char *blockPtr);
+ void (*freeProc) (char *blockPtr)
+ TCL_DEPRECATED_API("use Tcl_GetStringResult/Tcl_SetResult");
/* Zero means the string result is statically
* allocated. TCL_DYNAMIC means it was
* allocated with ckalloc and should be freed
@@ -484,17 +516,20 @@ typedef struct Tcl_Interp {
* Tcl_Eval must free it before executing next
* command. */
#else
- char *unused3;
- void (*unused4) (char *);
+ char *resultDontUse; /* Don't use in extensions! */
+ void (*freeProcDontUse) (char *); /* Don't use in extensions! */
#endif
#ifdef USE_INTERP_ERRORLINE
- int errorLine; /* When TCL_ERROR is returned, this gives the
+ int errorLine TCL_DEPRECATED_API("use Tcl_GetErrorLine/Tcl_SetErrorLine");
+ /* When TCL_ERROR is returned, this gives the
* line number within the command where the
* error occurred (1 if first line). */
#else
- int unused5;
+ int errorLineDontUse; /* Don't use in extensions! */
#endif
-} Tcl_Interp;
+}
+#endif /* TCL_NO_DEPRECATED */
+Tcl_Interp;
typedef struct Tcl_AsyncHandler_ *Tcl_AsyncHandler;
typedef struct Tcl_Channel_ *Tcl_Channel;
@@ -524,7 +559,7 @@ typedef struct Tcl_ZLibStream_ *Tcl_ZlibStream;
* will be called as the main fuction of the new thread created by that call.
*/
-#if defined __WIN32__
+#if defined _WIN32
typedef unsigned (__stdcall Tcl_ThreadCreateProc) (ClientData clientData);
#else
typedef void (Tcl_ThreadCreateProc) (ClientData clientData);
@@ -536,7 +571,7 @@ typedef void (Tcl_ThreadCreateProc) (ClientData clientData);
* in generic/tclThreadTest.c for it's usage.
*/
-#if defined __WIN32__
+#if defined _WIN32
# define Tcl_ThreadCreateType unsigned __stdcall
# define TCL_THREAD_CREATE_RETURN return 0
#else
@@ -818,10 +853,7 @@ typedef struct Tcl_Obj {
* whether an object is shared (i.e. has reference count > 1). Note: clients
* should use Tcl_DecrRefCount() when they are finished using an object, and
* should never call TclFreeObj() directly. TclFreeObj() is only defined and
- * made public in tcl.h to support Tcl_DecrRefCount's macro definition. Note
- * also that Tcl_DecrRefCount() refers to the parameter "obj" twice. This
- * means that you should avoid calling it with an expression that is expensive
- * to compute or has side effects.
+ * made public in tcl.h to support Tcl_DecrRefCount's macro definition.
*/
void Tcl_IncrRefCount(Tcl_Obj *objPtr);
@@ -2153,12 +2185,12 @@ typedef struct Tcl_EncodingType {
/*
* The maximum number of bytes that are necessary to represent a single
- * Unicode character in UTF-8. The valid values should be 3 or 6 (or perhaps 1
- * if we want to support a non-unicode enabled core). If 3, then Tcl_UniChar
- * must be 2-bytes in size (UCS-2) (the default). If 6, then Tcl_UniChar must
- * be 4-bytes in size (UCS-4). At this time UCS-2 mode is the default and
- * recommended mode. UCS-4 is experimental and not recommended. It works for
- * the core, but most extensions expect UCS-2.
+ * Unicode character in UTF-8. The valid values should be 3, 4 or 6
+ * (or perhaps 1 if we want to support a non-unicode enabled core). If 3 or
+ * 4, then Tcl_UniChar must be 2-bytes in size (UCS-2) (the default). If 6,
+ * then Tcl_UniChar must be 4-bytes in size (UCS-4). At this time UCS-2 mode
+ * is the default and recommended mode. UCS-4 is experimental and not
+ * recommended. It works for the core, but most extensions expect UCS-2.
*/
#ifndef TCL_UTF_MAX
@@ -2170,7 +2202,7 @@ typedef struct Tcl_EncodingType {
* reflected in regcustom.h.
*/
-#if TCL_UTF_MAX > 3
+#if TCL_UTF_MAX > 4
/*
* unsigned int isn't 100% accurate as it should be a strict 4-byte value
* (perhaps wchar_t). 64-bit systems may have troubles. The size of this
@@ -2276,12 +2308,12 @@ typedef int (Tcl_ArgvGenFuncProc)(ClientData clientData, Tcl_Interp *interp,
#define TCL_ARGV_AUTO_HELP \
{TCL_ARGV_HELP, "-help", NULL, NULL, \
- "Print summary of command-line options and abort"}
+ "Print summary of command-line options and abort", NULL}
#define TCL_ARGV_AUTO_REST \
{TCL_ARGV_REST, "--", NULL, NULL, \
- "Marks the end of the options"}
+ "Marks the end of the options", NULL}
#define TCL_ARGV_TABLE_END \
- {TCL_ARGV_END}
+ {TCL_ARGV_END, NULL, NULL, NULL, NULL, NULL}
/*
*----------------------------------------------------------------------------
@@ -2326,6 +2358,14 @@ typedef int (Tcl_ArgvGenFuncProc)(ClientData clientData, Tcl_Interp *interp,
/*
*----------------------------------------------------------------------------
+ * Definitions needed for the Tcl_LoadFile function. [TIP #416]
+ */
+
+#define TCL_LOAD_GLOBAL 1
+#define TCL_LOAD_LAZY 2
+
+/*
+ *----------------------------------------------------------------------------
* Single public declaration for NRE.
*/
@@ -2373,8 +2413,10 @@ const char * TclTomMathInitializeStubs(Tcl_Interp *interp,
* Tcl_GetMemoryInfo is needed for AOLserver. [Bug 1868171]
*/
-EXTERN void Tcl_Main(int argc, char **argv,
- Tcl_AppInitProc *appInitProc);
+#define Tcl_Main(argc, argv, proc) Tcl_MainEx(argc, argv, proc, \
+ ((Tcl_CreateInterp)()))
+EXTERN void Tcl_MainEx(int argc, char **argv,
+ Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
EXTERN const char * Tcl_PkgInitStubsCheck(Tcl_Interp *interp,
const char *version, int exact);
#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
@@ -2391,9 +2433,15 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
/*
* Include platform specific public function declarations that are accessible
- * via the stubs table.
+ * via the stubs table. Make all TclOO symbols MODULE_SCOPE (which only
+ * has effect on building it as a shared library). See ticket [3010352].
*/
+#if defined(BUILD_tcl)
+# undef TCLAPI
+# define TCLAPI MODULE_SCOPE
+#endif
+
#include "tclPlatDecls.h"
/*
@@ -2406,15 +2454,15 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
#ifdef TCL_MEM_DEBUG
# define ckalloc(x) \
- ((VOID *) Tcl_DbCkalloc((unsigned)(x), __FILE__, __LINE__))
+ ((void *) Tcl_DbCkalloc((unsigned)(x), __FILE__, __LINE__))
# define ckfree(x) \
Tcl_DbCkfree((char *)(x), __FILE__, __LINE__)
# define ckrealloc(x,y) \
- ((VOID *) Tcl_DbCkrealloc((char *)(x), (unsigned)(y), __FILE__, __LINE__))
+ ((void *) Tcl_DbCkrealloc((char *)(x), (unsigned)(y), __FILE__, __LINE__))
# define attemptckalloc(x) \
- ((VOID *) Tcl_AttemptDbCkalloc((unsigned)(x), __FILE__, __LINE__))
+ ((void *) Tcl_AttemptDbCkalloc((unsigned)(x), __FILE__, __LINE__))
# define attemptckrealloc(x,y) \
- ((VOID *) Tcl_AttemptDbCkrealloc((char *)(x), (unsigned)(y), __FILE__, __LINE__))
+ ((void *) Tcl_AttemptDbCkrealloc((char *)(x), (unsigned)(y), __FILE__, __LINE__))
#else /* !TCL_MEM_DEBUG */
@@ -2425,15 +2473,15 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
*/
# define ckalloc(x) \
- ((VOID *) Tcl_Alloc((unsigned)(x)))
+ ((void *) Tcl_Alloc((unsigned)(x)))
# define ckfree(x) \
Tcl_Free((char *)(x))
# define ckrealloc(x,y) \
- ((VOID *) Tcl_Realloc((char *)(x), (unsigned)(y)))
+ ((void *) Tcl_Realloc((char *)(x), (unsigned)(y)))
# define attemptckalloc(x) \
- ((VOID *) Tcl_AttemptAlloc((unsigned)(x)))
+ ((void *) Tcl_AttemptAlloc((unsigned)(x)))
# define attemptckrealloc(x,y) \
- ((VOID *) Tcl_AttemptRealloc((char *)(x), (unsigned)(y)))
+ ((void *) Tcl_AttemptRealloc((char *)(x), (unsigned)(y)))
# undef Tcl_InitMemory
# define Tcl_InitMemory(x)
# undef Tcl_DumpActiveMemory
@@ -2458,7 +2506,12 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
* http://c2.com/cgi/wiki?TrivialDoWhileLoop
*/
# define Tcl_DecrRefCount(objPtr) \
- do { if (--(objPtr)->refCount <= 0) TclFreeObj(objPtr); } while(0)
+ do { \
+ Tcl_Obj *_objPtr = (objPtr); \
+ if (--(_objPtr)->refCount <= 0) { \
+ TclFreeObj(_objPtr); \
+ } \
+ } while(0)
# define Tcl_IsShared(objPtr) \
((objPtr)->refCount > 1)
#endif
@@ -2554,13 +2607,6 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
*/
#ifndef TCL_NO_DEPRECATED
-# undef Tcl_EvalObj
-# define Tcl_EvalObj(interp,objPtr) \
- Tcl_EvalObjEx((interp),(objPtr),0)
-# undef Tcl_GlobalEvalObj
-# define Tcl_GlobalEvalObj(interp,objPtr) \
- Tcl_EvalObjEx((interp),(objPtr),TCL_EVAL_GLOBAL)
-
/*
* These function have been renamed. The old names are deprecated, but we
* define these macros for backwards compatibilty.
diff --git a/generic/tclAlloc.c b/generic/tclAlloc.c
index 6fff92b..ae61e85 100644
--- a/generic/tclAlloc.c
+++ b/generic/tclAlloc.c
@@ -26,12 +26,6 @@
#if USE_TCLALLOC
-#ifdef TCL_DEBUG
-# define DEBUG
-/* #define MSTATS */
-# define RCHECK
-#endif
-
/*
* We should really make use of AC_CHECK_TYPE(caddr_t) here, but it can wait
* until Tcl uses config.h properly.
@@ -60,7 +54,7 @@ union overhead {
unsigned char index; /* bucket # */
unsigned char unused; /* unused */
unsigned char magic1; /* other magic number */
-#ifdef RCHECK
+#ifndef NDEBUG
unsigned short rmagic; /* range magic number */
unsigned long size; /* actual block size */
unsigned short unused2; /* padding to 8-byte align */
@@ -77,7 +71,7 @@ union overhead {
#define MAGIC 0xef /* magic # on accounting info */
#define RMAGIC 0x5555 /* magic # on range info */
-#ifdef RCHECK
+#ifndef NDEBUG
#define RSLOP sizeof(unsigned short)
#else
#define RSLOP 0
@@ -142,7 +136,7 @@ static int allocInit = 0;
static unsigned int numMallocs[NBUCKETS+1];
#endif
-#if defined(DEBUG) || defined(RCHECK)
+#if !defined(NDEBUG)
#define ASSERT(p) if (!(p)) Tcl_Panic(# p)
#define RANGE_ASSERT(p) if (!(p)) Tcl_Panic(# p)
#else
@@ -299,7 +293,7 @@ TclpAlloc(
numMallocs[NBUCKETS]++;
#endif
-#ifdef RCHECK
+#ifndef NDEBUG
/*
* Record allocated size of block and bound space with magic numbers.
*/
@@ -357,7 +351,7 @@ TclpAlloc(
numMallocs[bucket]++;
#endif
-#ifdef RCHECK
+#ifndef NDEBUG
/*
* Record allocated size of block and bound space with magic numbers.
*/
@@ -577,7 +571,7 @@ TclpRealloc(
numMallocs[NBUCKETS]++;
#endif
-#ifdef RCHECK
+#ifndef NDEBUG
/*
* Record allocated size of block and update magic number bounds.
*/
@@ -619,7 +613,7 @@ TclpRealloc(
* Ok, we don't have to copy, it fits as-is
*/
-#ifdef RCHECK
+#ifndef NDEBUG
overPtr->realBlockSize = (numBytes + RSLOP - 1) & ~(RSLOP - 1);
BLOCK_END(overPtr) = RMAGIC;
#endif
diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c
index cd6dc38..d1866c8 100644
--- a/generic/tclAssembly.c
+++ b/generic/tclAssembly.c
@@ -20,12 +20,13 @@
*- break and continue - if exception ranges can be sorted out.
*- foreach_start4, foreach_step4
*- returnImm, returnStk
- *- expandStart, expandStkTop, invokeExpanded
+ *- expandStart, expandStkTop, invokeExpanded, expandDrop
*- dictFirst, dictNext, dictDone
*- dictUpdateStart, dictUpdateEnd
*- jumpTable testing
*- syntax (?)
*- returnCodeBranch
+ *- tclooNext, tclooNextClass
*/
#include "tclInt.h"
@@ -49,7 +50,7 @@ typedef enum BasicBlockCatchState {
BBCS_UNKNOWN = 0, /* Catch context has not yet been identified */
BBCS_NONE, /* Block is outside of any catch */
BBCS_INCATCH, /* Block is within a catch context */
- BBCS_CAUGHT, /* Block is within a catch context and
+ BBCS_CAUGHT /* Block is within a catch context and
* may be executed after an exception fires */
} BasicBlockCatchState;
@@ -120,7 +121,7 @@ enum BasicBlockFlags {
* marking it as the start of a 'catch'
* sequence. The 'jumpTarget' is the exception
* exit from the catch block. */
- BB_ENDCATCH = (1 << 5), /* Block ends with an 'endCatch' instruction,
+ BB_ENDCATCH = (1 << 5) /* Block ends with an 'endCatch' instruction,
* unwinding the catch from the exception
* stack. */
};
@@ -183,7 +184,7 @@ typedef enum TalInstType {
* produces N */
ASSEM_SINT1, /* One 1-byte signed-integer operand
* (INCR_STK_IMM) */
- ASSEM_SINT4_LVT4, /* Signed 4-byte integer operand followed by
+ ASSEM_SINT4_LVT4 /* Signed 4-byte integer operand followed by
* LVT entry. Fixed arity */
} TalInstType;
@@ -265,7 +266,7 @@ static int CheckStrictlyPositive(Tcl_Interp*, int);
static ByteCode * CompileAssembleObj(Tcl_Interp *interp,
Tcl_Obj *objPtr);
static void CompileEmbeddedScript(AssemblyEnv*, Tcl_Token*,
- TalInstDesc*);
+ const TalInstDesc*);
static int DefineLabel(AssemblyEnv* envPtr, const char* label);
static void DeleteMirrorJumpTable(JumptableInfo* jtPtr);
static void DupAssembleCodeInternalRep(Tcl_Obj* src,
@@ -324,33 +325,10 @@ static const Tcl_ObjType assembleCodeType = {
};
/*
- * TIP #280: Remember the per-word line information of the current command. An
- * index is used instead of a pointer as recursive compilation may reallocate,
- * i.e. move, the array. This is also the reason to save the nuloc now, it may
- * change during the course of the function.
- *
- * Macro to encapsulate the variable definition and setup.
- */
-
-#define DefineLineInformation \
- ExtCmdLoc *mapPtr = envPtr->extCmdMapPtr; \
- int eclIndex = mapPtr->nuloc - 1
-
-#define SetLineInformation(word) \
- envPtr->line = mapPtr->loc[eclIndex].line[(word)]; \
- envPtr->clNext = mapPtr->loc[eclIndex].next[(word)]
-
-/*
- * Flags bits used by PushVarName.
- */
-
-#define TCL_NO_LARGE_INDEX 1 /* Do not return localIndex value > 255 */
-
-/*
* Source instructions recognized in the Tcl Assembly Language (TAL)
*/
-TalInstDesc TalInstructionTable[] = {
+static const TalInstDesc TalInstructionTable[] = {
/* PUSH must be first, see the code near the end of TclAssembleCode */
{"push", ASSEM_PUSH, (INST_PUSH1<<8
| INST_PUSH4), 0, 1},
@@ -362,18 +340,29 @@ TalInstDesc TalInstructionTable[] = {
| INST_APPEND_ARRAY4), 2, 1},
{"appendArrayStk", ASSEM_1BYTE, INST_APPEND_ARRAY_STK, 3, 1},
{"appendStk", ASSEM_1BYTE, INST_APPEND_STK, 2, 1},
+ {"arrayExistsImm", ASSEM_LVT4, INST_ARRAY_EXISTS_IMM, 0, 1},
+ {"arrayExistsStk", ASSEM_1BYTE, INST_ARRAY_EXISTS_STK, 1, 1},
+ {"arrayMakeImm", ASSEM_LVT4, INST_ARRAY_MAKE_IMM, 0, 0},
+ {"arrayMakeStk", ASSEM_1BYTE, INST_ARRAY_MAKE_STK, 1, 0},
{"beginCatch", ASSEM_BEGIN_CATCH,
INST_BEGIN_CATCH4, 0, 0},
{"bitand", ASSEM_1BYTE, INST_BITAND, 2, 1},
{"bitnot", ASSEM_1BYTE, INST_BITNOT, 1, 1},
{"bitor", ASSEM_1BYTE, INST_BITOR, 2, 1},
{"bitxor", ASSEM_1BYTE, INST_BITXOR, 2, 1},
- {"concat", ASSEM_CONCAT1, INST_CONCAT1, INT_MIN,1},
+ {"concat", ASSEM_CONCAT1, INST_STR_CONCAT1, INT_MIN,1},
+ {"concatStk", ASSEM_LIST, INST_CONCAT_STK, INT_MIN,1},
+ {"coroName", ASSEM_1BYTE, INST_COROUTINE_NAME, 0, 1},
+ {"currentNamespace",ASSEM_1BYTE, INST_NS_CURRENT, 0, 1},
{"dictAppend", ASSEM_LVT4, INST_DICT_APPEND, 2, 1},
+ {"dictExists", ASSEM_DICT_GET, INST_DICT_EXISTS, INT_MIN,1},
+ {"dictExpand", ASSEM_1BYTE, INST_DICT_EXPAND, 3, 1},
{"dictGet", ASSEM_DICT_GET, INST_DICT_GET, INT_MIN,1},
{"dictIncrImm", ASSEM_SINT4_LVT4,
INST_DICT_INCR_IMM, 1, 1},
{"dictLappend", ASSEM_LVT4, INST_DICT_LAPPEND, 2, 1},
+ {"dictRecombineStk",ASSEM_1BYTE, INST_DICT_RECOMBINE_STK,3, 0},
+ {"dictRecombineImm",ASSEM_LVT4, INST_DICT_RECOMBINE_IMM,2, 0},
{"dictSet", ASSEM_DICT_SET, INST_DICT_SET, INT_MIN,1},
{"dictUnset", ASSEM_DICT_UNSET,
INST_DICT_UNSET, INT_MIN,1},
@@ -400,9 +389,10 @@ TalInstDesc TalInstructionTable[] = {
{"incrArrayStkImm", ASSEM_SINT1, INST_INCR_ARRAY_STK_IMM,2, 1},
{"incrImm", ASSEM_LVT1_SINT1,
INST_INCR_SCALAR1_IMM, 0, 1},
- {"incrStk", ASSEM_1BYTE, INST_INCR_SCALAR_STK, 2, 1},
- {"incrStkImm", ASSEM_SINT1, INST_INCR_SCALAR_STK_IMM,
- 1, 1},
+ {"incrStk", ASSEM_1BYTE, INST_INCR_STK, 2, 1},
+ {"incrStkImm", ASSEM_SINT1, INST_INCR_STK_IMM, 1, 1},
+ {"infoLevelArgs", ASSEM_1BYTE, INST_INFO_LEVEL_ARGS, 1, 1},
+ {"infoLevelNumber", ASSEM_1BYTE, INST_INFO_LEVEL_NUM, 0, 1},
{"invokeStk", ASSEM_INVOKE, (INST_INVOKE_STK1 << 8
| INST_INVOKE_STK4), INT_MIN,1},
{"jump", ASSEM_JUMP, INST_JUMP1, 0, 0},
@@ -425,6 +415,7 @@ TalInstDesc TalInstructionTable[] = {
{"lindexMulti", ASSEM_LINDEX_MULTI,
INST_LIST_INDEX_MULTI, INT_MIN,1},
{"list", ASSEM_LIST, INST_LIST, INT_MIN,1},
+ {"listConcat", ASSEM_1BYTE, INST_LIST_CONCAT, 2, 1},
{"listIn", ASSEM_1BYTE, INST_LIST_IN, 2, 1},
{"listIndex", ASSEM_1BYTE, INST_LIST_INDEX, 2, 1},
{"listIndexImm", ASSEM_INDEX, INST_LIST_INDEX_IMM, 1, 1},
@@ -435,7 +426,7 @@ TalInstDesc TalInstructionTable[] = {
{"loadArray", ASSEM_LVT, (INST_LOAD_ARRAY1<<8
| INST_LOAD_ARRAY4), 1, 1},
{"loadArrayStk", ASSEM_1BYTE, INST_LOAD_ARRAY_STK, 2, 1},
- {"loadStk", ASSEM_1BYTE, INST_LOAD_SCALAR_STK, 1, 1},
+ {"loadStk", ASSEM_1BYTE, INST_LOAD_STK, 1, 1},
{"lor", ASSEM_1BYTE, INST_LOR, 2, 1},
{"lsetFlat", ASSEM_LSET_FLAT,INST_LSET_FLAT, INT_MIN,1},
{"lsetList", ASSEM_1BYTE, INST_LSET_LIST, 3, 1},
@@ -447,6 +438,8 @@ TalInstDesc TalInstructionTable[] = {
{"nop", ASSEM_1BYTE, INST_NOP, 0, 0},
{"not", ASSEM_1BYTE, INST_LNOT, 1, 1},
{"nsupvar", ASSEM_LVT4, INST_NSUPVAR, 2, 1},
+ {"numericType", ASSEM_1BYTE, INST_NUM_TYPE, 1, 1},
+ {"originCmd", ASSEM_1BYTE, INST_ORIGIN_COMMAND, 1, 1},
{"over", ASSEM_OVER, INST_OVER, INT_MIN,-1-1},
{"pop", ASSEM_1BYTE, INST_POP, 1, 0},
{"pushReturnCode", ASSEM_1BYTE, INST_PUSH_RETURN_CODE, 0, 1},
@@ -454,6 +447,7 @@ TalInstDesc TalInstructionTable[] = {
0, 1},
{"pushResult", ASSEM_1BYTE, INST_PUSH_RESULT, 0, 1},
{"regexp", ASSEM_REGEXP, INST_REGEXP, 2, 1},
+ {"resolveCmd", ASSEM_1BYTE, INST_RESOLVE_COMMAND, 1, 1},
{"reverse", ASSEM_REVERSE, INST_REVERSE, INT_MIN,-1-0},
{"rshift", ASSEM_1BYTE, INST_RSHIFT, 2, 1},
{"store", ASSEM_LVT, (INST_STORE_SCALAR1<<8
@@ -461,14 +455,31 @@ TalInstDesc TalInstructionTable[] = {
{"storeArray", ASSEM_LVT, (INST_STORE_ARRAY1<<8
| INST_STORE_ARRAY4), 2, 1},
{"storeArrayStk", ASSEM_1BYTE, INST_STORE_ARRAY_STK, 3, 1},
- {"storeStk", ASSEM_1BYTE, INST_STORE_SCALAR_STK, 2, 1},
+ {"storeStk", ASSEM_1BYTE, INST_STORE_STK, 2, 1},
+ {"strcaseLower", ASSEM_1BYTE, INST_STR_LOWER, 1, 1},
+ {"strcaseTitle", ASSEM_1BYTE, INST_STR_TITLE, 1, 1},
+ {"strcaseUpper", ASSEM_1BYTE, INST_STR_UPPER, 1, 1},
{"strcmp", ASSEM_1BYTE, INST_STR_CMP, 2, 1},
+ {"strcat", ASSEM_CONCAT1, INST_STR_CONCAT1, INT_MIN,1},
{"streq", ASSEM_1BYTE, INST_STR_EQ, 2, 1},
+ {"strfind", ASSEM_1BYTE, INST_STR_FIND, 2, 1},
{"strindex", ASSEM_1BYTE, INST_STR_INDEX, 2, 1},
{"strlen", ASSEM_1BYTE, INST_STR_LEN, 1, 1},
+ {"strmap", ASSEM_1BYTE, INST_STR_MAP, 3, 1},
{"strmatch", ASSEM_BOOL, INST_STR_MATCH, 2, 1},
{"strneq", ASSEM_1BYTE, INST_STR_NEQ, 2, 1},
+ {"strrange", ASSEM_1BYTE, INST_STR_RANGE, 3, 1},
+ {"strreplace", ASSEM_1BYTE, INST_STR_REPLACE, 4, 1},
+ {"strrfind", ASSEM_1BYTE, INST_STR_FIND_LAST, 2, 1},
+ {"strtrim", ASSEM_1BYTE, INST_STR_TRIM, 2, 1},
+ {"strtrimLeft", ASSEM_1BYTE, INST_STR_TRIM_LEFT, 2, 1},
+ {"strtrimRight", ASSEM_1BYTE, INST_STR_TRIM_RIGHT, 2, 1},
{"sub", ASSEM_1BYTE, INST_SUB, 2, 1},
+ {"tclooClass", ASSEM_1BYTE, INST_TCLOO_CLASS, 1, 1},
+ {"tclooIsObject", ASSEM_1BYTE, INST_TCLOO_IS_OBJECT, 1, 1},
+ {"tclooNamespace", ASSEM_1BYTE, INST_TCLOO_NS, 1, 1},
+ {"tclooSelf", ASSEM_1BYTE, INST_TCLOO_SELF, 0, 1},
+ {"tryCvtToBoolean", ASSEM_1BYTE, INST_TRY_CVT_TO_BOOLEAN,1, 2},
{"tryCvtToNumeric", ASSEM_1BYTE, INST_TRY_CVT_TO_NUMERIC,1, 1},
{"uminus", ASSEM_1BYTE, INST_UMINUS, 1, 1},
{"unset", ASSEM_BOOL_LVT4,INST_UNSET_SCALAR, 0, 0},
@@ -478,6 +489,8 @@ TalInstDesc TalInstructionTable[] = {
{"uplus", ASSEM_1BYTE, INST_UPLUS, 1, 1},
{"upvar", ASSEM_LVT4, INST_UPVAR, 2, 1},
{"variable", ASSEM_LVT4, INST_VARIABLE, 1, 0},
+ {"verifyDict", ASSEM_1BYTE, INST_DICT_VERIFY, 1, 0},
+ {"yield", ASSEM_1BYTE, INST_YIELD, 1, 1},
{NULL, 0, 0, 0, 0}
};
@@ -489,14 +502,25 @@ TalInstDesc TalInstructionTable[] = {
* The instructions must be in ascending order by numeric operation code.
*/
-static unsigned char NonThrowingByteCodes[] = {
+static const unsigned char NonThrowingByteCodes[] = {
INST_PUSH1, INST_PUSH4, INST_POP, INST_DUP, /* 1-4 */
INST_JUMP1, INST_JUMP4, /* 34-35 */
INST_END_CATCH, INST_PUSH_RESULT, INST_PUSH_RETURN_CODE, /* 70-72 */
+ INST_LIST, /* 79 */
INST_OVER, /* 95 */
INST_PUSH_RETURN_OPTIONS, /* 108 */
INST_REVERSE, /* 126 */
- INST_NOP /* 132 */
+ INST_NOP, /* 132 */
+ INST_STR_MAP, /* 143 */
+ INST_STR_FIND, /* 144 */
+ INST_COROUTINE_NAME, /* 149 */
+ INST_NS_CURRENT, /* 151 */
+ INST_INFO_LEVEL_NUM, /* 152 */
+ INST_RESOLVE_COMMAND, /* 154 */
+ INST_STR_TRIM, INST_STR_TRIM_LEFT, INST_STR_TRIM_RIGHT, /* 166-168 */
+ INST_CONCAT_STK, /* 169 */
+ INST_STR_UPPER, INST_STR_LOWER, INST_STR_TITLE, /* 170-172 */
+ INST_NUM_TYPE /* 180 */
};
/*
@@ -644,7 +668,7 @@ BBEmitOpcode(
}
TclEmitInt1(op, envPtr);
- envPtr->atCmdStart = ((op) == INST_START_CMD);
+ TclUpdateAtCmdStart(op, envPtr);
BBUpdateStackReqs(bbPtr, tblIdx, count);
}
@@ -676,7 +700,7 @@ BBEmitInstInt4(
* BBEmitInst1or4 --
*
* Emits a 1- or 4-byte operation according to the magnitude of the
- * operand
+ * operand.
*
*-----------------------------------------------------------------------------
*/
@@ -705,7 +729,7 @@ BBEmitInst1or4(
} else {
TclEmitInt4(param, envPtr);
}
- envPtr->atCmdStart = ((op) == INST_START_CMD);
+ TclUpdateAtCmdStart(op, envPtr);
BBUpdateStackReqs(bbPtr, tblIdx, count);
}
@@ -769,12 +793,10 @@ TclNRAssembleObjCmd(
if (codePtr == NULL) {
Tcl_AddErrorInfo(interp, "\n (\"");
- Tcl_AddErrorInfo(interp, Tcl_GetString(objv[0]));
+ Tcl_AppendObjToErrorInfo(interp, objv[0]);
Tcl_AddErrorInfo(interp, "\" body, line ");
backtrace = Tcl_NewIntObj(Tcl_GetErrorLine(interp));
- Tcl_IncrRefCount(backtrace);
- Tcl_AddErrorInfo(interp, Tcl_GetString(backtrace));
- Tcl_DecrRefCount(backtrace);
+ Tcl_AppendObjToErrorInfo(interp, backtrace);
Tcl_AddErrorInfo(interp, ")");
return TCL_ERROR;
}
@@ -812,16 +834,11 @@ CompileAssembleObj(
CompileEnv compEnv; /* Compilation environment structure */
register ByteCode *codePtr = NULL;
/* Bytecode resulting from the assembly */
- register const AuxData * auxDataPtr;
- /* Pointer to an auxiliary data element
- * in a compilation environment being
- * destroyed. */
Namespace* namespacePtr; /* Namespace in which variable and command
* names in the bytecode resolve */
int status; /* Status return from Tcl_AssembleCode */
const char* source; /* String representation of the source code */
int sourceLen; /* Length of the source code in bytes */
- int i;
/*
@@ -831,7 +848,7 @@ CompileAssembleObj(
if (objPtr->typePtr == &assembleCodeType) {
namespacePtr = iPtr->varFramePtr->nsPtr;
- codePtr = objPtr->internalRep.otherValuePtr;
+ codePtr = objPtr->internalRep.twoPtrValue.ptr1;
if (((Interp *) *codePtr->interpHandle == iPtr)
&& (codePtr->compileEpoch == iPtr->compileEpoch)
&& (codePtr->nsPtr == namespacePtr)
@@ -859,44 +876,6 @@ CompileAssembleObj(
/*
* Assembly failed. Clean up and report the error.
*/
-
- /*
- * Free any literals that were constructed for the assembly.
- */
- for (i = 0; i < compEnv.literalArrayNext; i++) {
- TclReleaseLiteral(interp, compEnv.literalArrayPtr[i].objPtr);
- }
-
- /*
- * Free any auxiliary data that was attached to the bytecode
- * under construction.
- */
-
- for (i = 0; i < compEnv.auxDataArrayNext; i++) {
- auxDataPtr = compEnv.auxDataArrayPtr + i;
- if (auxDataPtr->type->freeProc != NULL) {
- (auxDataPtr->type->freeProc)(auxDataPtr->clientData);
- }
- }
-
- /*
- * TIP 280. If there is extended command line information,
- * we need to clean it up.
- */
-
- if (compEnv.extCmdMapPtr != NULL) {
- if (compEnv.extCmdMapPtr->type == TCL_LOCATION_SOURCE) {
- Tcl_DecrRefCount(compEnv.extCmdMapPtr->path);
- }
- for (i = 0; i < compEnv.extCmdMapPtr->nuloc; ++i) {
- ckfree(compEnv.extCmdMapPtr->loc[i].line);
- }
- if (compEnv.extCmdMapPtr->loc != NULL) {
- ckfree(compEnv.extCmdMapPtr->loc);
- }
- Tcl_DeleteHashTable(&(compEnv.extCmdMapPtr->litInfo));
- }
-
TclFreeCompileEnv(&compEnv);
return NULL;
}
@@ -916,7 +895,7 @@ CompileAssembleObj(
* Record the local variable context to which the bytecode pertains
*/
- codePtr = objPtr->internalRep.otherValuePtr;
+ codePtr = objPtr->internalRep.twoPtrValue.ptr1;
if (iPtr->varFramePtr->localCachePtr) {
codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr;
codePtr->localCachePtr->refCount++;
@@ -969,6 +948,10 @@ TclCompileAssembleCmd(
{
Tcl_Token *tokenPtr; /* Token in the input script */
+ int numCommands = envPtr->numCommands;
+ int offset = envPtr->codeNext - envPtr->codeStart;
+ int depth = envPtr->currStackDepth;
+
/*
* Make sure that the command has a single arg that is a simple word.
*/
@@ -982,10 +965,23 @@ TclCompileAssembleCmd(
}
/*
- * Compile the code and return any error from the compilation.
+ * Compile the code and convert any error from the compilation into
+ * bytecode reporting the error;
*/
- return TclAssembleCode(envPtr, tokenPtr[1].start, tokenPtr[1].size, 0);
+ if (TCL_ERROR == TclAssembleCode(envPtr, tokenPtr[1].start,
+ tokenPtr[1].size, TCL_EVAL_DIRECT)) {
+
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (\"%.*s\" body, line %d)",
+ parsePtr->tokenPtr->size, parsePtr->tokenPtr->start,
+ Tcl_GetErrorLine(interp)));
+ envPtr->numCommands = numCommands;
+ envPtr->codeNext = envPtr->codeStart + offset;
+ envPtr->currStackDepth = depth;
+ TclCompileSyntaxError(interp, envPtr);
+ }
+ return TCL_OK;
}
/*
@@ -1024,8 +1020,6 @@ TclAssembleCode(
const char* instPtr = codePtr;
/* Where to start looking for a line of code */
- int instLen; /* Length in bytes of the current line of
- * code */
const char* nextPtr; /* Pointer to the end of the line of code */
int bytesLeft = codeLen; /* Number of bytes of source code remaining to
* be parsed */
@@ -1039,10 +1033,6 @@ TclAssembleCode(
*/
status = Tcl_ParseCommand(interp, instPtr, bytesLeft, 0, parsePtr);
- instLen = parsePtr->commandSize;
- if (parsePtr->term == parsePtr->commandStart + instLen - 1) {
- --instLen;
- }
/*
* Report errors in the parse.
@@ -1051,7 +1041,7 @@ TclAssembleCode(
if (status != TCL_OK) {
if (flags & TCL_EVAL_DIRECT) {
Tcl_LogCommandInfo(interp, codePtr, parsePtr->commandStart,
- instLen);
+ parsePtr->term + 1 - parsePtr->commandStart);
}
FreeAssemblyEnv(assemEnvPtr);
return TCL_ERROR;
@@ -1071,6 +1061,13 @@ TclAssembleCode(
*/
if (parsePtr->numWords > 0) {
+ int instLen = parsePtr->commandSize;
+ /* Length in bytes of the current command */
+
+ if (parsePtr->term == parsePtr->commandStart + instLen - 1) {
+ --instLen;
+ }
+
/*
* If tracing, show each line assembled as it happens.
*/
@@ -1146,7 +1143,7 @@ NewAssemblyEnv(
assemEnvPtr->envPtr = envPtr;
assemEnvPtr->parsePtr = parsePtr;
- assemEnvPtr->cmdLine = envPtr->line;
+ assemEnvPtr->cmdLine = 1;
assemEnvPtr->clNext = envPtr->clNext;
/*
@@ -1765,7 +1762,7 @@ static void
CompileEmbeddedScript(
AssemblyEnv* assemEnvPtr, /* Assembly environment */
Tcl_Token* tokenPtr, /* Tcl_Token containing the script */
- TalInstDesc* instPtr) /* Instruction that determines whether
+ const TalInstDesc* instPtr) /* Instruction that determines whether
* the script is 'expr' or 'eval' */
{
CompileEnv* envPtr = assemEnvPtr->envPtr;
@@ -2638,6 +2635,7 @@ AllocBB(
bb->minStackDepth = 0;
bb->maxStackDepth = 0;
bb->finalStackDepth = 0;
+ bb->catchDepth = 0;
bb->enclosingCatch = NULL;
bb->foreignExceptionBase = -1;
bb->foreignExceptionCount = 0;
@@ -3068,7 +3066,7 @@ ResolveJumpTableTargets(
auxDataIndex = TclGetInt4AtPtr(envPtr->codeStart + bbPtr->jumpOffset + 1);
DEBUG_PRINT("bbPtr = %p jumpOffset = %d auxDataIndex = %d\n",
bbPtr, bbPtr->jumpOffset, auxDataIndex);
- realJumpTablePtr = envPtr->auxDataArrayPtr[auxDataIndex].clientData;
+ realJumpTablePtr = TclFetchAuxData(envPtr, auxDataIndex);
realJumpHashPtr = &realJumpTablePtr->hashTable;
/*
@@ -4241,11 +4239,11 @@ AddBasicBlockRangeToErrorInfo(
Tcl_AddErrorInfo(interp, "\n in assembly code between lines ");
lineNo = Tcl_NewIntObj(bbPtr->startLine);
Tcl_IncrRefCount(lineNo);
- Tcl_AddErrorInfo(interp, Tcl_GetString(lineNo));
+ Tcl_AppendObjToErrorInfo(interp, lineNo);
Tcl_AddErrorInfo(interp, " and ");
if (bbPtr->successor1 != NULL) {
Tcl_SetIntObj(lineNo, bbPtr->successor1->startLine);
- Tcl_AddErrorInfo(interp, Tcl_GetString(lineNo));
+ Tcl_AppendObjToErrorInfo(interp, lineNo);
} else {
Tcl_AddErrorInfo(interp, "end of assembly code");
}
@@ -4309,14 +4307,13 @@ static void
FreeAssembleCodeInternalRep(
Tcl_Obj *objPtr)
{
- ByteCode *codePtr = objPtr->internalRep.otherValuePtr;
+ ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
codePtr->refCount--;
if (codePtr->refCount <= 0) {
TclCleanupByteCode(codePtr);
}
objPtr->typePtr = NULL;
- objPtr->internalRep.otherValuePtr = NULL;
}
/*
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index f0f0c0f..2a334c4 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -81,8 +81,6 @@ TCL_DECLARE_MUTEX(cancelLock)
* are used to save the evaluation state between NR calls to each coro.
*/
-static const CorContext NULL_CONTEXT = {NULL, NULL, NULL, NULL};
-
#define SAVE_CONTEXT(context) \
(context).framePtr = iPtr->framePtr; \
(context).varFramePtr = iPtr->varFramePtr; \
@@ -129,15 +127,12 @@ static Tcl_ObjCmdProc ExprSqrtFunc;
static Tcl_ObjCmdProc ExprSrandFunc;
static Tcl_ObjCmdProc ExprUnaryFunc;
static Tcl_ObjCmdProc ExprWideFunc;
-static Tcl_Obj * GetCommandSource(Interp *iPtr, int objc,
- Tcl_Obj *const objv[], int lookup);
static void MathFuncWrongNumArgs(Tcl_Interp *interp, int expected,
int actual, Tcl_Obj *const *objv);
-static Tcl_NRPostProc NRCoroutineActivateCallback;
static Tcl_NRPostProc NRCoroutineCallerCallback;
static Tcl_NRPostProc NRCoroutineExitCallback;
-static Tcl_NRPostProc NRRunObjProc;
-static Tcl_NRPostProc NRTailcallEval;
+static int NRCommand(ClientData data[], Tcl_Interp *interp, int result);
+
static Tcl_ObjCmdProc OldMathFuncProc;
static void OldMathFuncDeleteProc(ClientData clientData);
static void ProcessUnexpectedResult(Tcl_Interp *interp,
@@ -151,8 +146,8 @@ static inline Command * TEOV_LookupCmdFromObj(Tcl_Interp *interp,
static int TEOV_NotFound(Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[], Namespace *lookupNsPtr);
static int TEOV_RunEnterTraces(Tcl_Interp *interp,
- Command **cmdPtrPtr, int objc,
- Tcl_Obj *const objv[], Namespace *lookupNsPtr);
+ Command **cmdPtrPtr, Tcl_Obj *commandPtr, int objc,
+ Tcl_Obj *const objv[]);
static Tcl_NRPostProc RewindCoroutineCallback;
static Tcl_NRPostProc TailcallCleanup;
static Tcl_NRPostProc TEOEx_ByteCodeCallback;
@@ -162,11 +157,11 @@ static Tcl_NRPostProc TEOV_Exception;
static Tcl_NRPostProc TEOV_NotFoundCallback;
static Tcl_NRPostProc TEOV_RestoreVarFrame;
static Tcl_NRPostProc TEOV_RunLeaveTraces;
-static Tcl_NRPostProc YieldToCallback;
+static Tcl_NRPostProc EvalObjvCore;
+static Tcl_NRPostProc Dispatch;
-static void ClearTailcall(Tcl_Interp *interp,
- struct NRE_callback *tailcallPtr);
static Tcl_ObjCmdProc NRCoroInjectObjCmd;
+static Tcl_NRPostProc NRPostInvoke;
MODULE_SCOPE const TclStubs tclStubs;
@@ -190,11 +185,16 @@ typedef struct {
Tcl_ObjCmdProc *objProc; /* Object-based function for command. */
CompileProc *compileProc; /* Function called to compile command. */
Tcl_ObjCmdProc *nreProc; /* NR-based function for command */
- int isSafe; /* If non-zero, command will be present in
- * safe interpreter. Otherwise it will be
- * hidden. */
+ int flags; /* Various flag bits, as defined below. */
} CmdInfo;
+#define CMD_IS_SAFE 1 /* Whether this command is part of the set of
+ * commands present by default in a safe
+ * interpreter. */
+/* CMD_COMPILES_EXPANDED - Whether the compiler for this command can handle
+ * expansion for itself rather than needing the generic layer to take care of
+ * it for it. Defined in tclInt.h. */
+
/*
* The built-in commands, and the functions that implement them:
*/
@@ -204,93 +204,95 @@ static const CmdInfo builtInCmds[] = {
* Commands in the generic core.
*/
- {"append", Tcl_AppendObjCmd, TclCompileAppendCmd, NULL, 1},
- {"apply", Tcl_ApplyObjCmd, NULL, TclNRApplyObjCmd, 1},
- {"break", Tcl_BreakObjCmd, TclCompileBreakCmd, NULL, 1},
+ {"append", Tcl_AppendObjCmd, TclCompileAppendCmd, NULL, CMD_IS_SAFE},
+ {"apply", Tcl_ApplyObjCmd, NULL, TclNRApplyObjCmd, CMD_IS_SAFE},
+ {"break", Tcl_BreakObjCmd, TclCompileBreakCmd, NULL, CMD_IS_SAFE},
#ifndef EXCLUDE_OBSOLETE_COMMANDS
- {"case", Tcl_CaseObjCmd, NULL, NULL, 1},
+ {"case", Tcl_CaseObjCmd, NULL, NULL, CMD_IS_SAFE},
#endif
- {"catch", Tcl_CatchObjCmd, TclCompileCatchCmd, TclNRCatchObjCmd, 1},
- {"concat", Tcl_ConcatObjCmd, NULL, NULL, 1},
- {"continue", Tcl_ContinueObjCmd, TclCompileContinueCmd, NULL, 1},
- {"coroutine", NULL, NULL, TclNRCoroutineObjCmd, 1},
- {"error", Tcl_ErrorObjCmd, TclCompileErrorCmd, NULL, 1},
- {"eval", Tcl_EvalObjCmd, NULL, NULL, 1},
- {"expr", Tcl_ExprObjCmd, TclCompileExprCmd, TclNRExprObjCmd, 1},
- {"for", Tcl_ForObjCmd, TclCompileForCmd, TclNRForObjCmd, 1},
- {"foreach", Tcl_ForeachObjCmd, TclCompileForeachCmd, TclNRForeachCmd, 1},
- {"format", Tcl_FormatObjCmd, NULL, NULL, 1},
- {"global", Tcl_GlobalObjCmd, TclCompileGlobalCmd, NULL, 1},
- {"if", Tcl_IfObjCmd, TclCompileIfCmd, TclNRIfObjCmd, 1},
- {"incr", Tcl_IncrObjCmd, TclCompileIncrCmd, NULL, 1},
- {"join", Tcl_JoinObjCmd, NULL, NULL, 1},
- {"lappend", Tcl_LappendObjCmd, TclCompileLappendCmd, NULL, 1},
- {"lassign", Tcl_LassignObjCmd, TclCompileLassignCmd, NULL, 1},
- {"lindex", Tcl_LindexObjCmd, TclCompileLindexCmd, NULL, 1},
- {"linsert", Tcl_LinsertObjCmd, NULL, NULL, 1},
- {"list", Tcl_ListObjCmd, TclCompileListCmd, NULL, 1},
- {"llength", Tcl_LlengthObjCmd, TclCompileLlengthCmd, NULL, 1},
- {"lrange", Tcl_LrangeObjCmd, NULL, NULL, 1},
- {"lrepeat", Tcl_LrepeatObjCmd, NULL, NULL, 1},
- {"lreplace", Tcl_LreplaceObjCmd, NULL, NULL, 1},
- {"lreverse", Tcl_LreverseObjCmd, NULL, NULL, 1},
- {"lsearch", Tcl_LsearchObjCmd, NULL, NULL, 1},
- {"lset", Tcl_LsetObjCmd, TclCompileLsetCmd, NULL, 1},
- {"lsort", Tcl_LsortObjCmd, NULL, NULL, 1},
- {"package", Tcl_PackageObjCmd, NULL, NULL, 1},
- {"proc", Tcl_ProcObjCmd, NULL, NULL, 1},
- {"regexp", Tcl_RegexpObjCmd, TclCompileRegexpCmd, NULL, 1},
- {"regsub", Tcl_RegsubObjCmd, NULL, NULL, 1},
- {"rename", Tcl_RenameObjCmd, NULL, NULL, 1},
- {"return", Tcl_ReturnObjCmd, TclCompileReturnCmd, NULL, 1},
- {"scan", Tcl_ScanObjCmd, NULL, NULL, 1},
- {"set", Tcl_SetObjCmd, TclCompileSetCmd, NULL, 1},
- {"split", Tcl_SplitObjCmd, NULL, NULL, 1},
- {"subst", Tcl_SubstObjCmd, TclCompileSubstCmd, TclNRSubstObjCmd, 1},
- {"switch", Tcl_SwitchObjCmd, TclCompileSwitchCmd, TclNRSwitchObjCmd, 1},
- {"tailcall", NULL, NULL, TclNRTailcallObjCmd, 1},
- {"throw", Tcl_ThrowObjCmd, TclCompileThrowCmd, NULL, 1},
- {"trace", Tcl_TraceObjCmd, NULL, NULL, 1},
- {"try", Tcl_TryObjCmd, TclCompileTryCmd, TclNRTryObjCmd, 1},
- {"unset", Tcl_UnsetObjCmd, TclCompileUnsetCmd, NULL, 1},
- {"uplevel", Tcl_UplevelObjCmd, NULL, TclNRUplevelObjCmd, 1},
- {"upvar", Tcl_UpvarObjCmd, TclCompileUpvarCmd, NULL, 1},
- {"variable", Tcl_VariableObjCmd, TclCompileVariableCmd, NULL, 1},
- {"while", Tcl_WhileObjCmd, TclCompileWhileCmd, TclNRWhileObjCmd, 1},
- {"yield", NULL, NULL, TclNRYieldObjCmd, 1},
+ {"catch", Tcl_CatchObjCmd, TclCompileCatchCmd, TclNRCatchObjCmd, CMD_IS_SAFE},
+ {"concat", Tcl_ConcatObjCmd, TclCompileConcatCmd, NULL, CMD_IS_SAFE},
+ {"continue", Tcl_ContinueObjCmd, TclCompileContinueCmd, NULL, CMD_IS_SAFE},
+ {"coroutine", NULL, NULL, TclNRCoroutineObjCmd, CMD_IS_SAFE},
+ {"error", Tcl_ErrorObjCmd, TclCompileErrorCmd, NULL, CMD_IS_SAFE},
+ {"eval", Tcl_EvalObjCmd, NULL, TclNREvalObjCmd, CMD_IS_SAFE},
+ {"expr", Tcl_ExprObjCmd, TclCompileExprCmd, TclNRExprObjCmd, CMD_IS_SAFE},
+ {"for", Tcl_ForObjCmd, TclCompileForCmd, TclNRForObjCmd, CMD_IS_SAFE},
+ {"foreach", Tcl_ForeachObjCmd, TclCompileForeachCmd, TclNRForeachCmd, CMD_IS_SAFE},
+ {"format", Tcl_FormatObjCmd, TclCompileFormatCmd, NULL, CMD_IS_SAFE},
+ {"global", Tcl_GlobalObjCmd, TclCompileGlobalCmd, NULL, CMD_IS_SAFE},
+ {"if", Tcl_IfObjCmd, TclCompileIfCmd, TclNRIfObjCmd, CMD_IS_SAFE},
+ {"incr", Tcl_IncrObjCmd, TclCompileIncrCmd, NULL, CMD_IS_SAFE},
+ {"join", Tcl_JoinObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"lappend", Tcl_LappendObjCmd, TclCompileLappendCmd, NULL, CMD_IS_SAFE},
+ {"lassign", Tcl_LassignObjCmd, TclCompileLassignCmd, NULL, CMD_IS_SAFE},
+ {"lindex", Tcl_LindexObjCmd, TclCompileLindexCmd, NULL, CMD_IS_SAFE},
+ {"linsert", Tcl_LinsertObjCmd, TclCompileLinsertCmd, NULL, CMD_IS_SAFE},
+ {"list", Tcl_ListObjCmd, TclCompileListCmd, NULL, CMD_IS_SAFE|CMD_COMPILES_EXPANDED},
+ {"llength", Tcl_LlengthObjCmd, TclCompileLlengthCmd, NULL, CMD_IS_SAFE},
+ {"lmap", Tcl_LmapObjCmd, TclCompileLmapCmd, TclNRLmapCmd, CMD_IS_SAFE},
+ {"lrange", Tcl_LrangeObjCmd, TclCompileLrangeCmd, NULL, CMD_IS_SAFE},
+ {"lrepeat", Tcl_LrepeatObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"lreplace", Tcl_LreplaceObjCmd, TclCompileLreplaceCmd, NULL, CMD_IS_SAFE},
+ {"lreverse", Tcl_LreverseObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"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},
+ {"proc", Tcl_ProcObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"regexp", Tcl_RegexpObjCmd, TclCompileRegexpCmd, NULL, CMD_IS_SAFE},
+ {"regsub", Tcl_RegsubObjCmd, TclCompileRegsubCmd, NULL, CMD_IS_SAFE},
+ {"rename", Tcl_RenameObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"return", Tcl_ReturnObjCmd, TclCompileReturnCmd, NULL, CMD_IS_SAFE},
+ {"scan", Tcl_ScanObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"set", Tcl_SetObjCmd, TclCompileSetCmd, NULL, CMD_IS_SAFE},
+ {"split", Tcl_SplitObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"subst", Tcl_SubstObjCmd, TclCompileSubstCmd, TclNRSubstObjCmd, CMD_IS_SAFE},
+ {"switch", Tcl_SwitchObjCmd, TclCompileSwitchCmd, TclNRSwitchObjCmd, CMD_IS_SAFE},
+ {"tailcall", NULL, TclCompileTailcallCmd, TclNRTailcallObjCmd, CMD_IS_SAFE},
+ {"throw", Tcl_ThrowObjCmd, TclCompileThrowCmd, NULL, CMD_IS_SAFE},
+ {"trace", Tcl_TraceObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"try", Tcl_TryObjCmd, TclCompileTryCmd, TclNRTryObjCmd, CMD_IS_SAFE},
+ {"unset", Tcl_UnsetObjCmd, TclCompileUnsetCmd, NULL, CMD_IS_SAFE},
+ {"uplevel", Tcl_UplevelObjCmd, NULL, TclNRUplevelObjCmd, CMD_IS_SAFE},
+ {"upvar", Tcl_UpvarObjCmd, TclCompileUpvarCmd, NULL, CMD_IS_SAFE},
+ {"variable", Tcl_VariableObjCmd, TclCompileVariableCmd, NULL, CMD_IS_SAFE},
+ {"while", Tcl_WhileObjCmd, TclCompileWhileCmd, TclNRWhileObjCmd, CMD_IS_SAFE},
+ {"yield", NULL, TclCompileYieldCmd, TclNRYieldObjCmd, CMD_IS_SAFE},
+ {"yieldto", NULL, TclCompileYieldToCmd, TclNRYieldToObjCmd, CMD_IS_SAFE},
/*
* Commands in the OS-interface. Note that many of these are unsafe.
*/
- {"after", Tcl_AfterObjCmd, NULL, NULL, 1},
+ {"after", Tcl_AfterObjCmd, NULL, NULL, CMD_IS_SAFE},
{"cd", Tcl_CdObjCmd, NULL, NULL, 0},
- {"close", Tcl_CloseObjCmd, NULL, NULL, 1},
- {"eof", Tcl_EofObjCmd, NULL, NULL, 1},
+ {"close", Tcl_CloseObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"eof", Tcl_EofObjCmd, NULL, NULL, CMD_IS_SAFE},
{"encoding", Tcl_EncodingObjCmd, NULL, NULL, 0},
{"exec", Tcl_ExecObjCmd, NULL, NULL, 0},
{"exit", Tcl_ExitObjCmd, NULL, NULL, 0},
- {"fblocked", Tcl_FblockedObjCmd, NULL, NULL, 1},
+ {"fblocked", Tcl_FblockedObjCmd, NULL, NULL, CMD_IS_SAFE},
{"fconfigure", Tcl_FconfigureObjCmd, NULL, NULL, 0},
- {"fcopy", Tcl_FcopyObjCmd, NULL, NULL, 1},
- {"fileevent", Tcl_FileEventObjCmd, NULL, NULL, 1},
- {"flush", Tcl_FlushObjCmd, NULL, NULL, 1},
- {"gets", Tcl_GetsObjCmd, NULL, NULL, 1},
+ {"fcopy", Tcl_FcopyObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"fileevent", Tcl_FileEventObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"flush", Tcl_FlushObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"gets", Tcl_GetsObjCmd, NULL, NULL, CMD_IS_SAFE},
{"glob", Tcl_GlobObjCmd, NULL, NULL, 0},
{"load", Tcl_LoadObjCmd, NULL, NULL, 0},
{"open", Tcl_OpenObjCmd, NULL, NULL, 0},
- {"pid", Tcl_PidObjCmd, NULL, NULL, 1},
- {"puts", Tcl_PutsObjCmd, NULL, NULL, 1},
+ {"pid", Tcl_PidObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"puts", Tcl_PutsObjCmd, NULL, NULL, CMD_IS_SAFE},
{"pwd", Tcl_PwdObjCmd, NULL, NULL, 0},
- {"read", Tcl_ReadObjCmd, NULL, NULL, 1},
- {"seek", Tcl_SeekObjCmd, NULL, NULL, 1},
+ {"read", Tcl_ReadObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"seek", Tcl_SeekObjCmd, NULL, NULL, CMD_IS_SAFE},
{"socket", Tcl_SocketObjCmd, NULL, NULL, 0},
{"source", Tcl_SourceObjCmd, NULL, TclNRSourceObjCmd, 0},
- {"tell", Tcl_TellObjCmd, NULL, NULL, 1},
- {"time", Tcl_TimeObjCmd, NULL, NULL, 1},
+ {"tell", Tcl_TellObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"time", Tcl_TimeObjCmd, NULL, NULL, CMD_IS_SAFE},
{"unload", Tcl_UnloadObjCmd, NULL, NULL, 0},
- {"update", Tcl_UpdateObjCmd, NULL, NULL, 1},
- {"vwait", Tcl_VwaitObjCmd, NULL, NULL, 1},
+ {"update", Tcl_UpdateObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"vwait", Tcl_VwaitObjCmd, NULL, NULL, CMD_IS_SAFE},
{NULL, NULL, NULL, NULL, 0}
};
@@ -484,6 +486,18 @@ Tcl_CreateInterp(void)
Tcl_Panic("Tcl_CallFrame must not be smaller than CallFrame");
}
+#if defined(_WIN32) && !defined(_WIN64)
+ if (sizeof(time_t) != 4) {
+ /*NOTREACHED*/
+ Tcl_Panic("<time.h> is not compatible with MSVC");
+ }
+ if ((TclOffset(Tcl_StatBuf,st_atime) != 32)
+ || (TclOffset(Tcl_StatBuf,st_ctime) != 40)) {
+ /*NOTREACHED*/
+ Tcl_Panic("<sys/stat.h> is not compatible with MSVC");
+ }
+#endif
+
if (cancelTableInitialized == 0) {
Tcl_MutexLock(&cancelLock);
if (cancelTableInitialized == 0) {
@@ -512,6 +526,9 @@ Tcl_CreateInterp(void)
iPtr->hiddenCmdTablePtr = NULL;
iPtr->interpInfo = NULL;
+ TCL_CT_ASSERT(sizeof(iPtr->extra) <= sizeof(Tcl_HashTable));
+ iPtr->extra.optimizer = TclOptimizeBytecode;
+
iPtr->numLevels = 0;
iPtr->maxNestingDepth = MAX_NESTING_DEPTH;
iPtr->framePtr = NULL; /* Initialise as soon as :: is available */
@@ -771,6 +788,9 @@ Tcl_CreateInterp(void)
cmdPtr->deleteProc = NULL;
cmdPtr->deleteData = NULL;
cmdPtr->flags = 0;
+ if (cmdInfoPtr->flags & CMD_COMPILES_EXPANDED) {
+ cmdPtr->flags |= CMD_COMPILES_EXPANDED;
+ }
cmdPtr->importRefPtr = NULL;
cmdPtr->tracePtr = NULL;
cmdPtr->nreProc = cmdInfoPtr->nreProc;
@@ -830,13 +850,9 @@ Tcl_CreateInterp(void)
TclNRAssembleObjCmd, NULL, NULL);
cmdPtr->compileProc = &TclCompileAssembleCmd;
- Tcl_NRCreateCommand(interp, "::tcl::unsupported::yieldTo", NULL,
- TclNRYieldToObjCmd, NULL, NULL);
- Tcl_NRCreateCommand(interp, "::tcl::unsupported::yieldm", NULL,
- TclNRYieldObjCmd, INT2PTR(CORO_ACTIVATE_YIELDM), NULL);
Tcl_NRCreateCommand(interp, "::tcl::unsupported::inject", NULL,
NRCoroInjectObjCmd, NULL, NULL);
-
+
#ifdef USE_DTRACE
/*
* Register the tcl::dtrace command.
@@ -1007,7 +1023,7 @@ TclHideUnsafeCommands(
return TCL_ERROR;
}
for (cmdInfoPtr = builtInCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
- if (!cmdInfoPtr->isSafe) {
+ if (!(cmdInfoPtr->flags & CMD_IS_SAFE)) {
Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name);
}
}
@@ -1560,12 +1576,16 @@ DeleteInterpProc(
hPtr != NULL;
hPtr = Tcl_NextHashEntry(&search)) {
CmdFrame *cfPtr = Tcl_GetHashValue(hPtr);
+ Proc *procPtr = (Proc *) Tcl_GetHashKey(iPtr->linePBodyPtr, hPtr);
- if (cfPtr->type == TCL_LOCATION_SOURCE) {
- Tcl_DecrRefCount(cfPtr->data.eval.path);
+ procPtr->iPtr = NULL;
+ if (cfPtr) {
+ if (cfPtr->type == TCL_LOCATION_SOURCE) {
+ Tcl_DecrRefCount(cfPtr->data.eval.path);
+ }
+ ckfree(cfPtr->line);
+ ckfree(cfPtr);
}
- ckfree(cfPtr->line);
- ckfree(cfPtr);
Tcl_DeleteHashEntry(hPtr);
}
Tcl_DeleteHashTable(iPtr->linePBodyPtr);
@@ -1592,8 +1612,6 @@ DeleteInterpProc(
ckfree(eclPtr->loc);
}
- Tcl_DeleteHashTable(&eclPtr->litInfo);
-
ckfree(eclPtr);
Tcl_DeleteHashEntry(hPtr);
}
@@ -1707,9 +1725,9 @@ Tcl_HideCommand(
*/
if (strstr(hiddenCmdToken, "::") != NULL) {
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"cannot use namespace qualifiers in hidden command"
- " token (rename)", NULL);
+ " token (rename)", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "HIDDENTOKEN", NULL);
return TCL_ERROR;
}
@@ -1732,8 +1750,9 @@ Tcl_HideCommand(
*/
if (cmdPtr->nsPtr != iPtr->globalNsPtr) {
- Tcl_AppendResult(interp, "can only hide global namespace commands"
- " (use rename then hide)", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "can only hide global namespace commands (use rename then hide)",
+ -1));
Tcl_SetErrorCode(interp, "TCL", "HIDE", "NON_GLOBAL", NULL);
return TCL_ERROR;
}
@@ -1757,8 +1776,9 @@ Tcl_HideCommand(
hPtr = Tcl_CreateHashEntry(hiddenCmdTablePtr, hiddenCmdToken, &isNew);
if (!isNew) {
- Tcl_AppendResult(interp, "hidden command named \"", hiddenCmdToken,
- "\" already exists", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "hidden command named \"%s\" already exists",
+ hiddenCmdToken));
Tcl_SetErrorCode(interp, "TCL", "HIDE", "ALREADY_HIDDEN", NULL);
return TCL_ERROR;
}
@@ -1860,8 +1880,9 @@ Tcl_ExposeCommand(
*/
if (strstr(cmdName, "::") != NULL) {
- Tcl_AppendResult(interp, "cannot expose to a namespace "
- "(use expose to toplevel, then rename)", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "cannot expose to a namespace (use expose to toplevel, then rename)",
+ -1));
Tcl_SetErrorCode(interp, "TCL", "EXPOSE", "NON_GLOBAL", NULL);
return TCL_ERROR;
}
@@ -1876,8 +1897,8 @@ Tcl_ExposeCommand(
hPtr = Tcl_FindHashEntry(hiddenCmdTablePtr, hiddenCmdToken);
}
if (hPtr == NULL) {
- Tcl_AppendResult(interp, "unknown hidden command \"", hiddenCmdToken,
- "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown hidden command \"%s\"", hiddenCmdToken));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "HIDDENTOKEN",
hiddenCmdToken, NULL);
return TCL_ERROR;
@@ -1896,9 +1917,9 @@ Tcl_ExposeCommand(
* than 'nicely' erroring out ?
*/
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"trying to expose a non-global command namespace command",
- NULL);
+ -1));
return TCL_ERROR;
}
@@ -1915,13 +1936,24 @@ Tcl_ExposeCommand(
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, cmdName, &isNew);
if (!isNew) {
- Tcl_AppendResult(interp, "exposed command \"", cmdName,
- "\" already exists", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "exposed command \"%s\" already exists", cmdName));
Tcl_SetErrorCode(interp, "TCL", "EXPOSE", "COMMAND_EXISTS", NULL);
return TCL_ERROR;
}
/*
+ * Command resolvers (per-interp, per-namespace) might have resolved to a
+ * command for the given namespace scope with this command not being
+ * registered with the namespace's command table. During BC compilation,
+ * the so-resolved command turns into a CmdName literal. Without
+ * invalidating a possible CmdName literal here explicitly, such literals
+ * keep being reused while pointing to overhauled commands.
+ */
+
+ TclInvalidateCmdLiteral(interp, cmdName, nsPtr);
+
+ /*
* The list of command exported from the namespace might have changed.
* However, we do not need to recompute this just yet; next time we need
* the info will be soon enough.
@@ -2053,10 +2085,19 @@ Tcl_CreateCommand(
*/
cmdPtr = Tcl_GetHashValue(hPtr);
- oldRefPtr = cmdPtr->importRefPtr;
- cmdPtr->importRefPtr = NULL;
+ cmdPtr->refCount++;
+ if (cmdPtr->importRefPtr) {
+ cmdPtr->flags |= CMD_REDEF_IN_PROGRESS;
+ }
Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
+
+ if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) {
+ oldRefPtr = cmdPtr->importRefPtr;
+ cmdPtr->importRefPtr = NULL;
+ }
+ TclCleanupCommandMacro(cmdPtr);
+
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
if (!isNew) {
/*
@@ -2069,6 +2110,18 @@ Tcl_CreateCommand(
}
} else {
/*
+ * Command resolvers (per-interp, per-namespace) might have resolved
+ * to a command for the given namespace scope with this command not
+ * being registered with the namespace's command table. During BC
+ * compilation, the so-resolved command turns into a CmdName literal.
+ * Without invalidating a possible CmdName literal here explicitly,
+ * such literals keep being reused while pointing to overhauled
+ * commands.
+ */
+
+ TclInvalidateCmdLiteral(interp, tail, nsPtr);
+
+ /*
* The list of command exported from the namespace might have changed.
* However, we do not need to recompute this just yet; next time we
* need the info will be soon enough.
@@ -2133,12 +2186,9 @@ Tcl_CreateCommand(
* future calls to Tcl_GetCommandName.
*
* Side effects:
- * If no command named "cmdName" already exists for interp, one is
- * created. Otherwise, if a command does exist, then if the object-based
- * Tcl_ObjCmdProc is TclInvokeStringCommand, we assume Tcl_CreateCommand
- * was called previously for the same command and just set its
- * Tcl_ObjCmdProc to the argument "proc"; otherwise, we delete the old
- * command.
+ * If a command named "cmdName" already exists for interp, it is
+ * first deleted. Then the new command is created from the arguments.
+ * [***] (See below for exception).
*
* In the future, during bytecode evaluation when "cmdName" is seen as
* the name of a command by Tcl_EvalObj or Tcl_Eval, the object-based
@@ -2205,17 +2255,22 @@ Tcl_CreateObjCommand(
if (!isNew) {
cmdPtr = Tcl_GetHashValue(hPtr);
+ /* Command already exists. */
+
/*
- * Command already exists. If its object-based Tcl_ObjCmdProc is
- * TclInvokeStringCommand, we just set its Tcl_ObjCmdProc to the
- * argument "proc". Otherwise, we delete the old command.
+ * [***] This is wrong. See Tcl Bug a16752c252.
+ * However, this buggy behavior is kept under particular
+ * circumstances to accommodate deployed binaries of the
+ * "tclcompiler" program. http://sourceforge.net/projects/tclpro/
+ * that crash if the bug is fixed.
*/
- if (cmdPtr->objProc == TclInvokeStringCommand) {
+ if (cmdPtr->objProc == TclInvokeStringCommand
+ && cmdPtr->clientData == clientData
+ && cmdPtr->deleteData == clientData
+ && cmdPtr->deleteProc == deleteProc) {
cmdPtr->objProc = proc;
cmdPtr->objClientData = clientData;
- cmdPtr->deleteProc = deleteProc;
- cmdPtr->deleteData = clientData;
return (Tcl_Command) cmdPtr;
}
@@ -2226,10 +2281,19 @@ Tcl_CreateObjCommand(
* intact.
*/
- oldRefPtr = cmdPtr->importRefPtr;
- cmdPtr->importRefPtr = NULL;
+ cmdPtr->refCount++;
+ if (cmdPtr->importRefPtr) {
+ cmdPtr->flags |= CMD_REDEF_IN_PROGRESS;
+ }
Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
+
+ if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) {
+ oldRefPtr = cmdPtr->importRefPtr;
+ cmdPtr->importRefPtr = NULL;
+ }
+ TclCleanupCommandMacro(cmdPtr);
+
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
if (!isNew) {
/*
@@ -2242,6 +2306,18 @@ Tcl_CreateObjCommand(
}
} else {
/*
+ * Command resolvers (per-interp, per-namespace) might have resolved
+ * to a command for the given namespace scope with this command not
+ * being registered with the namespace's command table. During BC
+ * compilation, the so-resolved command turns into a CmdName literal.
+ * Without invalidating a possible CmdName literal here explicitly,
+ * such literals keep being reused while pointing to overhauled
+ * commands.
+ */
+
+ TclInvalidateCmdLiteral(interp, tail, nsPtr);
+
+ /*
* The list of command exported from the namespace might have changed.
* However, we do not need to recompute this just yet; next time we
* need the info will be soon enough.
@@ -2356,8 +2432,8 @@ TclInvokeStringCommand(
* A standard Tcl string result value.
*
* Side effects:
- * Besides those side effects of the called Tcl_CmdProc,
- * TclInvokeStringCommand allocates and frees storage.
+ * Besides those side effects of the called Tcl_ObjCmdProc,
+ * TclInvokeObjectCommand allocates and frees storage.
*
*----------------------------------------------------------------------
*/
@@ -2461,9 +2537,10 @@ TclRenameCommand(
cmd = Tcl_FindCommand(interp, oldName, NULL, /*flags*/ 0);
cmdPtr = (Command *) cmd;
if (cmdPtr == NULL) {
- Tcl_AppendResult(interp, "can't ",
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't %s \"%s\": command doesn't exist",
((newName == NULL)||(*newName == '\0'))? "delete":"rename",
- " \"", oldName, "\": command doesn't exist", NULL);
+ oldName));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", oldName, NULL);
return TCL_ERROR;
}
@@ -2493,15 +2570,15 @@ TclRenameCommand(
TCL_CREATE_NS_IF_UNKNOWN, &newNsPtr, &dummy1, &dummy2, &newTail);
if ((newNsPtr == NULL) || (newTail == NULL)) {
- Tcl_AppendResult(interp, "can't rename to \"", newName,
- "\": bad command name", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't rename to \"%s\": bad command name", newName));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL);
result = TCL_ERROR;
goto done;
}
if (Tcl_FindHashEntry(&newNsPtr->cmdTable, newTail) != NULL) {
- Tcl_AppendResult(interp, "can't rename to \"", newName,
- "\": command already exists", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't rename to \"%s\": command already exists", newName));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "RENAME",
"TARGET_EXISTS", NULL);
result = TCL_ERROR;
@@ -2551,6 +2628,17 @@ TclRenameCommand(
TclInvalidateNsCmdLookup(cmdPtr->nsPtr);
/*
+ * Command resolvers (per-interp, per-namespace) might have resolved to a
+ * command for the given namespace scope with this command not being
+ * registered with the namespace's command table. During BC compilation,
+ * the so-resolved command turns into a CmdName literal. Without
+ * invalidating a possible CmdName literal here explicitly, such literals
+ * keep being reused while pointing to overhauled commands.
+ */
+
+ TclInvalidateCmdLiteral(interp, newTail, cmdPtr->nsPtr);
+
+ /*
* Script for rename traces can delete the command "oldName". Therefore
* increment the reference count for cmdPtr so that it's Command structure
* is freed only towards the end of this function by calling
@@ -2565,7 +2653,7 @@ TclRenameCommand(
Tcl_DStringInit(&newFullName);
Tcl_DStringAppend(&newFullName, newNsPtr->fullName, -1);
if (newNsPtr != iPtr->globalNsPtr) {
- Tcl_DStringAppend(&newFullName, "::", 2);
+ TclDStringAppendLiteral(&newFullName, "::");
}
Tcl_DStringAppend(&newFullName, newTail, -1);
cmdPtr->refCount++;
@@ -3047,12 +3135,13 @@ Tcl_DeleteCommandFromToken(
* commands were created that refer back to this command. Delete these
* imported commands now.
*/
-
- for (refPtr = cmdPtr->importRefPtr; refPtr != NULL;
- refPtr = nextRefPtr) {
- nextRefPtr = refPtr->nextPtr;
- importCmd = (Tcl_Command) refPtr->importedCmdPtr;
- Tcl_DeleteCommandFromToken(interp, importCmd);
+ if (!(cmdPtr->flags & CMD_REDEF_IN_PROGRESS)) {
+ for (refPtr = cmdPtr->importRefPtr; refPtr != NULL;
+ refPtr = nextRefPtr) {
+ nextRefPtr = refPtr->nextPtr;
+ importCmd = (Tcl_Command) refPtr->importedCmdPtr;
+ Tcl_DeleteCommandFromToken(interp, importCmd);
+ }
}
/*
@@ -3081,8 +3170,8 @@ Tcl_DeleteCommandFromToken(
* from a CmdName Tcl object in some ByteCode code sequence. In that case,
* delay the cleanup until all references are either discarded (when a
* ByteCode is freed) or replaced by a new reference (when a cached
- * CmdName Command reference is found to be invalid and TclNRExecuteByteCode
- * looks up the command in the command hashtable).
+ * CmdName Command reference is found to be invalid and
+ * TclNRExecuteByteCode looks up the command in the command hashtable).
*/
TclCleanupCommandMacro(cmdPtr);
@@ -3288,66 +3377,6 @@ CancelEvalProc(
/*
*----------------------------------------------------------------------
*
- * GetCommandSource --
- *
- * This function returns a Tcl_Obj with the full source string for the
- * command. This insures that traces get a correct NUL-terminated command
- * string. The Tcl_Obj has refCount==1.
- *
- * *** MAINTAINER WARNING ***
- * The returned Tcl_Obj is all wrong for any purpose but getting the
- * source string for an objc/objv command line in the stringRep (no
- * stringRep if no source is available) and the corresponding substituted
- * version in the List intrep.
- * This means that the intRep and stringRep DO NOT COINCIDE! Using these
- * Tcl_Objs normally is likely to break things.
- *
- *----------------------------------------------------------------------
- */
-
-static Tcl_Obj *
-GetCommandSource(
- Interp *iPtr,
- int objc,
- Tcl_Obj *const objv[],
- int lookup)
-{
- Tcl_Obj *objPtr, *obj2Ptr;
- CmdFrame *cfPtr = iPtr->cmdFramePtr;
- const char *command = NULL;
- int numChars;
-
- objPtr = Tcl_NewListObj(objc, objv);
- if (lookup && cfPtr && (cfPtr->numLevels == iPtr->numLevels-1)) {
- switch (cfPtr->type) {
- case TCL_LOCATION_EVAL:
- case TCL_LOCATION_SOURCE:
- command = cfPtr->cmd.str.cmd;
- numChars = cfPtr->cmd.str.len;
- break;
- case TCL_LOCATION_BC:
- case TCL_LOCATION_PREBC:
- command = TclGetSrcInfoForCmd(iPtr, &numChars);
- break;
- case TCL_LOCATION_EVAL_LIST:
- /* Got it already */
- break;
- }
- if (command) {
- obj2Ptr = Tcl_NewStringObj(command, numChars);
- objPtr->bytes = obj2Ptr->bytes;
- objPtr->length = numChars;
- obj2Ptr->bytes = NULL;
- Tcl_DecrRefCount(obj2Ptr);
- }
- }
- Tcl_IncrRefCount(objPtr);
- return objPtr;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* TclCleanupCommand --
*
* This function frees up a Command structure unless it is still
@@ -3423,7 +3452,7 @@ Tcl_CreateMathFunc(
data->clientData = clientData;
Tcl_DStringInit(&bigName);
- Tcl_DStringAppend(&bigName, "::tcl::mathfunc::", -1);
+ TclDStringAppendLiteral(&bigName, "::tcl::mathfunc::");
Tcl_DStringAppend(&bigName, name, -1);
Tcl_CreateObjCommand(interp, Tcl_DStringValue(&bigName),
@@ -3491,9 +3520,9 @@ OldMathFuncProc(
* We have a non-numeric argument.
*/
- Tcl_SetResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"argument to math function didn't have numeric value",
- TCL_STATIC);
+ -1));
TclCheckBadOctal(interp, Tcl_GetString(valuePtr));
ckfree(args);
return TCL_ERROR;
@@ -3706,41 +3735,28 @@ Tcl_ListMathFuncs(
Tcl_Interp *interp,
const char *pattern)
{
- Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
- Namespace *nsPtr;
- Namespace *dummy1NsPtr;
- Namespace *dummy2NsPtr;
- const char *dummyNamePtr;
- Tcl_Obj *result = Tcl_NewObj();
-
- TclGetNamespaceForQualName(interp, "::tcl::mathfunc",
- globalNsPtr, TCL_FIND_ONLY_NS | TCL_GLOBAL_ONLY,
- &nsPtr, &dummy1NsPtr, &dummy2NsPtr, &dummyNamePtr);
- if (nsPtr == NULL) {
- return result;
+ Tcl_Obj *script = Tcl_NewStringObj("::info functions ", -1);
+ Tcl_Obj *result;
+ Tcl_InterpState state;
+
+ if (pattern) {
+ Tcl_Obj *patternObj = Tcl_NewStringObj(pattern, -1);
+ Tcl_Obj *arg = Tcl_NewListObj(1, &patternObj);
+
+ Tcl_AppendObjToObj(script, arg);
+ Tcl_DecrRefCount(arg); /* Should tear down patternObj too */
}
- if ((pattern != NULL) && TclMatchIsTrivial(pattern)) {
- if (Tcl_FindHashEntry(&nsPtr->cmdTable, pattern) != NULL) {
- Tcl_ListObjAppendElement(NULL, result,
- Tcl_NewStringObj(pattern, -1));
- }
+ state = Tcl_SaveInterpState(interp, TCL_OK);
+ Tcl_IncrRefCount(script);
+ if (TCL_OK == Tcl_EvalObjEx(interp, script, 0)) {
+ result = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
} else {
- Tcl_HashSearch cmdHashSearch;
- Tcl_HashEntry *cmdHashEntry =
- Tcl_FirstHashEntry(&nsPtr->cmdTable,&cmdHashSearch);
-
- for (; cmdHashEntry != NULL;
- cmdHashEntry = Tcl_NextHashEntry(&cmdHashSearch)) {
- const char *cmdNamePtr =
- Tcl_GetHashKey(&nsPtr->cmdTable, cmdHashEntry);
-
- if (pattern == NULL || Tcl_StringMatch(cmdNamePtr, pattern)) {
- Tcl_ListObjAppendElement(NULL, result,
- Tcl_NewStringObj(cmdNamePtr, -1));
- }
- }
+ result = Tcl_NewObj();
}
+ Tcl_DecrRefCount(script);
+ Tcl_RestoreInterpState(interp, state);
+
return result;
}
@@ -3780,9 +3796,8 @@ TclInterpReady(
*/
if (iPtr->flags & DELETED) {
- /* JJM - Superfluous Tcl_ResetResult call removed. */
- Tcl_AppendResult(interp,
- "attempt to call eval in deleted interpreter", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to call eval in deleted interpreter", -1));
Tcl_SetErrorCode(interp, "TCL", "IDELETE",
"attempt to call eval in deleted interpreter", NULL);
return TCL_ERROR;
@@ -3810,8 +3825,8 @@ TclInterpReady(
return TCL_OK;
}
- Tcl_AppendResult(interp,
- "too many nested evaluations (infinite loop?)", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "too many nested evaluations (infinite loop?)", -1));
Tcl_SetErrorCode(interp, "TCL", "LIMIT", "STACK", NULL);
return TCL_ERROR;
}
@@ -3945,8 +3960,7 @@ Tcl_Canceled(
}
}
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, message, NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(message, -1));
Tcl_SetErrorCode(interp, "TCL", "CANCEL", id, message, NULL);
}
@@ -4123,43 +4137,39 @@ TclNREvalObjv(
* requested Command struct to be invoked. */
{
Interp *iPtr = (Interp *) interp;
- int result;
- Namespace *lookupNsPtr = iPtr->lookupNsPtr;
- Command **cmdPtrPtr;
-
- iPtr->lookupNsPtr = NULL;
/*
- * Push a callback with cleanup tasks for commands; the cmdPtr at data[0]
- * will be filled later when the command is found: save its address at
- * objProcPtr.
- *
* data[1] stores a marker for use by tailcalls; it will be set to 1 by
* command redirectors (imports, alias, ensembles) so that tailcalls
* finishes the source command and not just the target.
*/
- if (iPtr->evalFlags & TCL_EVAL_REDIRECT) {
- TclNRAddCallback(interp, NRCommand, NULL, INT2PTR(1), INT2PTR(objc), objv);
- iPtr->evalFlags &= ~TCL_EVAL_REDIRECT;
+ if (iPtr->deferredCallbacks) {
+ iPtr->deferredCallbacks = NULL;
} else {
- TclNRAddCallback(interp, NRCommand, NULL, NULL, INT2PTR(objc), objv);
+ TclNRAddCallback(interp, NRCommand, NULL, NULL, NULL, NULL);
}
- cmdPtrPtr = (Command **) &(TOP_CB(interp)->data[0]);
-
- TclNRSpliceDeferred(interp);
iPtr->numLevels++;
- result = TclInterpReady(interp);
-
- if ((result != TCL_OK) || (objc == 0)) {
- return result;
- }
-
- if (cmdPtr) {
- goto commandFound;
- }
+ TclNRAddCallback(interp, EvalObjvCore, cmdPtr, INT2PTR(flags),
+ INT2PTR(objc), objv);
+ return TCL_OK;
+}
+static int
+EvalObjvCore(
+ ClientData data[],
+ Tcl_Interp *interp,
+ int result)
+{
+ Command *cmdPtr = NULL, *preCmdPtr = data[0];
+ int flags = PTR2INT(data[1]);
+ int objc = PTR2INT(data[2]);
+ Tcl_Obj **objv = data[3];
+ Interp *iPtr = (Interp *) interp;
+ Namespace *lookupNsPtr = NULL;
+ int enterTracesDone = 0;
+
/*
* Push records for task to be done on return, in INVERSE order. First, if
* needed, the exception handlers (as they should happen last).
@@ -4169,61 +4179,150 @@ TclNREvalObjv(
TEOV_PushExceptionHandlers(interp, objc, objv, flags);
}
+ if (TCL_OK != TclInterpReady(interp)) {
+ return TCL_ERROR;
+ }
+
+ if (objc == 0) {
+ return TCL_OK;
+ }
+
+ if (TclLimitExceeded(iPtr->limit)) {
+ return TCL_ERROR;
+ }
+
/*
* Configure evaluation context to match the requested flags.
*/
- if ((flags & TCL_EVAL_INVOKE) || lookupNsPtr) {
- if (!lookupNsPtr) {
- lookupNsPtr = iPtr->globalNsPtr;
- }
+ if (iPtr->lookupNsPtr) {
+
+ /*
+ * Capture the namespace we should do command name resolution in, as
+ * instructed by our caller sneaking it in to us in a private interp
+ * field. Clear that field right away so we cannot possibly have its
+ * use leak where it should not. The sneaky message pass is done.
+ *
+ * Use of this mechanism overrides the TCL_EVAL_GLOBAL flag.
+ * TODO: Is that a bug?
+ */
+
+ lookupNsPtr = iPtr->lookupNsPtr;
+ iPtr->lookupNsPtr = NULL;
+ } else if (flags & TCL_EVAL_INVOKE) {
+ lookupNsPtr = iPtr->globalNsPtr;
} else {
- if (flags & TCL_EVAL_GLOBAL) {
- TEOV_SwitchVarFrame(interp);
- lookupNsPtr = iPtr->globalNsPtr;
- }
/*
* TCL_EVAL_INVOKE was not set: clear rewrite rules
*/
iPtr->ensembleRewrite.sourceObjs = NULL;
+
+ if (flags & TCL_EVAL_GLOBAL) {
+ TEOV_SwitchVarFrame(interp);
+ lookupNsPtr = iPtr->globalNsPtr;
+ }
}
/*
- * Lookup the command
+ * Lookup the Command to dispatch.
*/
- cmdPtr = TEOV_LookupCmdFromObj(interp, objv[0], lookupNsPtr);
- if (!cmdPtr) {
- return TEOV_NotFound(interp, objc, objv, lookupNsPtr);
+ reresolve:
+ assert(cmdPtr == NULL);
+ if (preCmdPtr) {
+ /* Caller gave it to us */
+ if (!(preCmdPtr->flags & CMD_IS_DELETED)) {
+ /* So long as it exists, use it. */
+ cmdPtr = preCmdPtr;
+ } else if (flags & TCL_EVAL_NORESOLVE) {
+ /*
+ * When it's been deleted, and we're told not to attempt
+ * resolving it ourselves, all we can do is raise an error.
+ */
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "attempt to invoke a deleted command"));
+ Tcl_SetErrorCode(interp, "TCL", "EVAL", "DELETEDCOMMAND", NULL);
+ return TCL_ERROR;
+ }
}
-
- iPtr->cmdCount++;
- if (TclLimitExceeded(iPtr->limit)) {
- return TCL_ERROR;
+ if (cmdPtr == NULL) {
+ cmdPtr = TEOV_LookupCmdFromObj(interp, objv[0], lookupNsPtr);
+ if (!cmdPtr) {
+ return TEOV_NotFound(interp, objc, objv, lookupNsPtr);
+ }
}
- /*
- * Found a command! The real work begins now ...
- */
+ if (enterTracesDone || iPtr->tracePtr
+ || (cmdPtr->flags & CMD_HAS_EXEC_TRACES)) {
- commandFound:
- if (iPtr->tracePtr || (cmdPtr->flags & CMD_HAS_EXEC_TRACES)) {
- /*
- * Call enter traces. They will schedule a call to the leave traces if
- * necessary.
- */
+ Tcl_Obj *commandPtr = TclGetSourceFromFrame(
+ flags & TCL_EVAL_SOURCE_IN_FRAME ? iPtr->cmdFramePtr : NULL,
+ objc, objv);
+ Tcl_IncrRefCount(commandPtr);
- result = TEOV_RunEnterTraces(interp, &cmdPtr, objc, objv, lookupNsPtr);
- if (!cmdPtr) {
- return TEOV_NotFound(interp, objc, objv, lookupNsPtr);
- }
- if (result != TCL_OK) {
- return result;
+ if (!enterTracesDone) {
+
+ int code = TEOV_RunEnterTraces(interp, &cmdPtr, commandPtr,
+ objc, objv);
+
+ /*
+ * Send any exception from enter traces back as an exception
+ * raised by the traced command.
+ * TODO: Is this a bug? Letting an execution trace BREAK or
+ * CONTINUE or RETURN in the place of the traced command?
+ * Would either converting all exceptions to TCL_ERROR, or
+ * just swallowing them be better? (Swallowing them has the
+ * problem of permanently hiding program errors.)
+ */
+
+ if (code != TCL_OK) {
+ Tcl_DecrRefCount(commandPtr);
+ return code;
+ }
+
+ /*
+ * If the enter traces made the resolved cmdPtr unusable, go
+ * back and resolve again, but next time don't run enter
+ * traces again.
+ */
+
+ if (cmdPtr == NULL) {
+ enterTracesDone = 1;
+ Tcl_DecrRefCount(commandPtr);
+ goto reresolve;
+ }
}
+
+ /*
+ * Schedule leave traces. Raise the refCount on the resolved
+ * cmdPtr, so that when it passes to the leave traces we know
+ * it's still valid.
+ */
+
+ cmdPtr->refCount++;
+ TclNRAddCallback(interp, TEOV_RunLeaveTraces, INT2PTR(objc),
+ commandPtr, cmdPtr, objv);
}
+ TclNRAddCallback(interp, Dispatch,
+ cmdPtr->nreProc ? cmdPtr->nreProc : cmdPtr->objProc,
+ cmdPtr->objClientData, INT2PTR(objc), objv);
+ return TCL_OK;
+}
+
+static int
+Dispatch(
+ ClientData data[],
+ Tcl_Interp *interp,
+ int result)
+{
+ Tcl_ObjCmdProc *objProc = data[0];
+ ClientData clientData = data[1];
+ int objc = PTR2INT(data[2]);
+ Tcl_Obj **objv = data[3];
+ Interp *iPtr = (Interp *) interp;
#ifdef USE_DTRACE
if (TCL_DTRACE_CMD_ARGS_ENABLED()) {
@@ -4244,42 +4343,18 @@ TclNREvalObjv(
TCL_DTRACE_CMD_INFO(a[0], a[1], a[2], a[3], i[0], i[1], a[4], a[5]);
TclDecrRefCount(info);
}
- if (TCL_DTRACE_CMD_RETURN_ENABLED() || TCL_DTRACE_CMD_RESULT_ENABLED()) {
+ if ((TCL_DTRACE_CMD_RETURN_ENABLED() || TCL_DTRACE_CMD_RESULT_ENABLED())
+ && objc) {
TclNRAddCallback(interp, DTraceCmdReturn, objv[0], NULL, NULL, NULL);
}
- if (TCL_DTRACE_CMD_ENTRY_ENABLED()) {
+ if (TCL_DTRACE_CMD_ENTRY_ENABLED() && objc) {
TCL_DTRACE_CMD_ENTRY(TclGetString(objv[0]), objc - 1,
(Tcl_Obj **)(objv + 1));
}
#endif /* USE_DTRACE */
- /*
- * Fix the original callback to point to the now known cmdPtr. Insure that
- * the Command struct lives until the command returns.
- */
-
- *cmdPtrPtr = cmdPtr;
- cmdPtr->refCount++;
-
- /*
- * Find the objProc to call: nreProc if available, objProc otherwise. Push
- * a callback to do the actual running.
- */
-
- if (cmdPtr->nreProc) {
- TclNRAddCallback(interp, NRRunObjProc, cmdPtr,
- INT2PTR(objc), (ClientData) objv, NULL);
- return TCL_OK;
- } else {
- return cmdPtr->objProc(cmdPtr->objClientData, interp, objc, objv);
- }
-}
-void
-TclPushTailcallPoint(
- Tcl_Interp *interp)
-{
- TclNRAddCallback(interp, NRCommand, NULL, NULL, NULL, NULL);
- ((Interp *) interp)->numLevels++;
+ iPtr->cmdCount++;
+ return objProc(clientData, interp, objc, objv);
}
int
@@ -4318,20 +4393,23 @@ TclNRRunCallbacks(
return result;
}
-int
+static int
NRCommand(
ClientData data[],
Tcl_Interp *interp,
int result)
{
Interp *iPtr = (Interp *) interp;
- Command *cmdPtr = data[0];
- /* int cmdStart = PTR2INT(data[1]); NOT USED HERE */
- if (cmdPtr) {
- TclCleanupCommandMacro(cmdPtr);
+ iPtr->numLevels--;
+
+ /*
+ * If there is a tailcall, schedule it
+ */
+
+ if (data[1] && (data[1] != INT2PTR(1))) {
+ TclNRAddCallback(interp, TclNRTailcallEval, data[1], NULL, NULL, NULL);
}
- ((Interp *)interp)->numLevels--;
/* OPT ??
* Do not interrupt a series of cleanups with async or limit checks:
@@ -4350,22 +4428,6 @@ NRCommand(
return result;
}
-
-static int
-NRRunObjProc(
- ClientData data[],
- Tcl_Interp *interp,
- int result)
-{
- /* OPT: do not call? */
-
- Command* cmdPtr = data[0];
- int objc = PTR2INT(data[1]);
- Tcl_Obj **objv = data[2];
-
- return cmdPtr->nreProc(cmdPtr->objClientData, interp, objc, objv);
-}
-
/*
*----------------------------------------------------------------------
@@ -4569,8 +4631,8 @@ TEOV_NotFound(
cmdPtr = TEOV_LookupCmdFromObj(interp, newObjv[0], lookupNsPtr);
if (cmdPtr == NULL) {
- Tcl_AppendResult(interp, "invalid command name \"",
- TclGetString(objv[0]), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid command name \"%s\"", TclGetString(objv[0])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND",
TclGetString(objv[0]), NULL);
@@ -4590,9 +4652,9 @@ TEOV_NotFound(
savedNsPtr = varFramePtr->nsPtr;
varFramePtr->nsPtr = lookupNsPtr;
}
- TclNRDeferCallback(interp, TEOV_NotFoundCallback, INT2PTR(handlerObjc),
+ TclSkipTailcall(interp);
+ TclNRAddCallback(interp, TEOV_NotFoundCallback, INT2PTR(handlerObjc),
newObjv, savedNsPtr, NULL);
- iPtr->evalFlags |= TCL_EVAL_REDIRECT;
return TclNREvalObjv(interp, newObjc, newObjv, TCL_EVAL_NOERR, NULL);
}
@@ -4629,27 +4691,21 @@ static int
TEOV_RunEnterTraces(
Tcl_Interp *interp,
Command **cmdPtrPtr,
+ Tcl_Obj *commandPtr,
int objc,
- Tcl_Obj *const objv[],
- Namespace *lookupNsPtr)
+ Tcl_Obj *const objv[])
{
Interp *iPtr = (Interp *) interp;
Command *cmdPtr = *cmdPtrPtr;
- int traceCode = TCL_OK;
- int cmdEpoch = cmdPtr->cmdEpoch;
- int newEpoch;
- const char *command;
- int length;
- Tcl_Obj *commandPtr;
-
- commandPtr = GetCommandSource(iPtr, objc, objv, 1);
- command = Tcl_GetStringFromObj(commandPtr, &length);
+ int newEpoch, cmdEpoch = cmdPtr->cmdEpoch;
+ int length, traceCode = TCL_OK;
+ const char *command = Tcl_GetStringFromObj(commandPtr, &length);
/*
* Call trace functions.
* Execute any command or execution traces. Note that we bump up the
- * command's reference count for the duration of the calling of the traces
- * so that the structure doesn't go away underneath our feet.
+ * command's reference count for the duration of the calling of the
+ * traces so that the structure doesn't go away underneath our feet.
*/
cmdPtr->refCount++;
@@ -4664,29 +4720,22 @@ TEOV_RunEnterTraces(
newEpoch = cmdPtr->cmdEpoch;
TclCleanupCommandMacro(cmdPtr);
- /*
- * If the traces modified/deleted the command or any existing traces, they
- * will update the command's epoch. We need to lookup again, but do not
- * run enter traces on the newly found cmdPtr.
- */
-
- if (cmdEpoch != newEpoch) {
- cmdPtr = TEOV_LookupCmdFromObj(interp, objv[0], lookupNsPtr);
- *cmdPtrPtr = cmdPtr;
+ if (traceCode != TCL_OK) {
+ if (traceCode == TCL_ERROR) {
+ Tcl_Obj *info;
+
+ TclNewLiteralStringObj(info, "\n (enter trace on \"");
+ Tcl_AppendLimitedToObj(info, command, length, 55, "...");
+ Tcl_AppendToObj(info, "\")", 2);
+ Tcl_AppendObjToErrorInfo(interp, info);
+ iPtr->flags |= ERR_ALREADY_LOGGED;
+ }
+ return traceCode;
}
-
- if (cmdPtr) {
- /*
- * Command was found: push a record to schedule the leave traces.
- */
-
- TclNRAddCallback(interp, TEOV_RunLeaveTraces, INT2PTR(traceCode),
- commandPtr, cmdPtr, NULL);
- cmdPtr->refCount++;
- } else {
- Tcl_DecrRefCount(commandPtr);
+ if (cmdEpoch != newEpoch) {
+ *cmdPtrPtr = NULL;
}
- return traceCode;
+ return TCL_OK;
}
static int
@@ -4696,20 +4745,16 @@ TEOV_RunLeaveTraces(
int result)
{
Interp *iPtr = (Interp *) interp;
- const char *command;
- int length, objc;
- Tcl_Obj **objv;
- int traceCode = PTR2INT(data[0]);
+ int traceCode = TCL_OK;
+ int objc = PTR2INT(data[0]);
Tcl_Obj *commandPtr = data[1];
Command *cmdPtr = data[2];
-
- command = Tcl_GetStringFromObj(commandPtr, &length);
- if (TCL_OK != Tcl_ListObjGetElements(interp, commandPtr, &objc, &objv)) {
- Tcl_Panic("Who messed with commandPtr?");
- }
+ Tcl_Obj **objv = data[3];
+ int length;
+ const char *command = Tcl_GetStringFromObj(commandPtr, &length);
if (!(cmdPtr->flags & CMD_IS_DELETED)) {
- if ((cmdPtr->flags & CMD_HAS_EXEC_TRACES) && traceCode == TCL_OK){
+ if (cmdPtr->flags & CMD_HAS_EXEC_TRACES){
traceCode = TclCheckExecutionTraces(interp, command, length,
cmdPtr, result, TCL_TRACE_LEAVE_EXEC, objc, objv);
}
@@ -4718,7 +4763,6 @@ TEOV_RunLeaveTraces(
cmdPtr, result, TCL_TRACE_LEAVE_EXEC, objc, objv);
}
}
- Tcl_DecrRefCount(commandPtr);
/*
* As cmdPtr is set, TclNRRunCallbacks is about to reduce the numlevels.
@@ -4729,8 +4773,18 @@ TEOV_RunLeaveTraces(
TclCleanupCommandMacro(cmdPtr);
if (traceCode != TCL_OK) {
- return traceCode;
+ if (traceCode == TCL_ERROR) {
+ Tcl_Obj *info;
+
+ TclNewLiteralStringObj(info, "\n (leave trace on \"");
+ Tcl_AppendLimitedToObj(info, command, length, 55, "...");
+ Tcl_AppendToObj(info, "\")", 2);
+ Tcl_AppendObjToErrorInfo(interp, info);
+ iPtr->flags |= ERR_ALREADY_LOGGED;
+ }
+ result = traceCode;
}
+ Tcl_DecrRefCount(commandPtr);
return result;
}
@@ -4746,7 +4800,6 @@ TEOV_LookupCmdFromObj(
if (lookupNsPtr) {
iPtr->varFramePtr->nsPtr = lookupNsPtr;
- iPtr->lookupNsPtr = NULL;
}
cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, namePtr);
iPtr->varFramePtr->nsPtr = savedNsPtr;
@@ -4965,31 +5018,22 @@ TclEvalEx(
/*
* TIP #280 Initialize tracking. Do not push on the frame stack yet.
*
- * We may continue counting based on a specific context (CTX), or open a
- * new context, either for a sourced script, or 'eval'. For sourced files
- * we always have a path object, even if nothing was specified in the
- * interp itself. That makes code using it simpler as NULL checks can be
- * left out. Sourced file without path in the 'scriptFile' is possible
- * during Tcl initialization.
+ * We open a new context, either for a sourced script, or 'eval'.
+ * For sourced files we always have a path object, even if nothing was
+ * specified in the interp itself. That makes code using it simpler as
+ * NULL checks can be left out. Sourced file without path in the
+ * 'scriptFile' is possible during Tcl initialization.
*/
eeFramePtr->level = iPtr->cmdFramePtr ? iPtr->cmdFramePtr->level + 1 : 1;
- eeFramePtr->numLevels = iPtr->numLevels;
eeFramePtr->framePtr = iPtr->framePtr;
eeFramePtr->nextPtr = iPtr->cmdFramePtr;
eeFramePtr->nline = 0;
eeFramePtr->line = NULL;
+ eeFramePtr->cmdObj = NULL;
iPtr->cmdFramePtr = eeFramePtr;
- if (iPtr->evalFlags & TCL_EVAL_CTX) {
- /*
- * Path information comes out of the context.
- */
-
- eeFramePtr->type = TCL_LOCATION_SOURCE;
- eeFramePtr->data.eval.path = iPtr->invokeCmdFramePtr->data.eval.path;
- Tcl_IncrRefCount(eeFramePtr->data.eval.path);
- } else if (iPtr->evalFlags & TCL_EVAL_FILE) {
+ if (iPtr->evalFlags & TCL_EVAL_FILE) {
/*
* Set up for a sourced file.
*/
@@ -5032,7 +5076,9 @@ TclEvalEx(
do {
if (Tcl_ParseCommand(interp, p, bytesLeft, 0, parsePtr) != TCL_OK) {
code = TCL_ERROR;
- goto error;
+ Tcl_LogCommandInfo(interp, script, parsePtr->commandStart,
+ parsePtr->term + 1 - parsePtr->commandStart);
+ goto posterror;
}
/*
@@ -5198,23 +5244,28 @@ TclEvalEx(
* have been executed.
*/
- eeFramePtr->cmd.str.cmd = parsePtr->commandStart;
- eeFramePtr->cmd.str.len = parsePtr->commandSize;
+ eeFramePtr->cmd = parsePtr->commandStart;
+ eeFramePtr->len = parsePtr->commandSize;
if (parsePtr->term ==
parsePtr->commandStart + parsePtr->commandSize - 1) {
- eeFramePtr->cmd.str.len--;
+ eeFramePtr->len--;
}
eeFramePtr->nline = objectsUsed;
eeFramePtr->line = lines;
TclArgumentEnter(interp, objv, objectsUsed, eeFramePtr);
- code = Tcl_EvalObjv(interp, objectsUsed, objv, TCL_EVAL_NOERR);
+ code = Tcl_EvalObjv(interp, objectsUsed, objv,
+ TCL_EVAL_NOERR | TCL_EVAL_SOURCE_IN_FRAME);
TclArgumentRelease(interp, objv, objectsUsed);
eeFramePtr->line = NULL;
eeFramePtr->nline = 0;
+ if (eeFramePtr->cmdObj) {
+ Tcl_DecrRefCount(eeFramePtr->cmdObj);
+ eeFramePtr->cmdObj = NULL;
+ }
if (code != TCL_OK) {
goto error;
@@ -5288,6 +5339,7 @@ TclEvalEx(
Tcl_LogCommandInfo(interp, script, parsePtr->commandStart,
commandLength);
}
+ posterror:
iPtr->flags &= ~ERR_ALREADY_LOGGED;
/*
@@ -5562,76 +5614,88 @@ TclArgumentBCEnter(
int objc,
void *codePtr,
CmdFrame *cfPtr,
+ int cmd,
int pc)
{
+ ExtCmdLoc *eclPtr;
+ int word;
+ ECL *ePtr;
+ CFWordBC *lastPtr = NULL;
Interp *iPtr = (Interp *) interp;
Tcl_HashEntry *hePtr =
Tcl_FindHashEntry(iPtr->lineBCPtr, (char *) codePtr);
- ExtCmdLoc *eclPtr;
if (!hePtr) {
return;
}
eclPtr = Tcl_GetHashValue(hePtr);
- hePtr = Tcl_FindHashEntry(&eclPtr->litInfo, INT2PTR(pc));
- if (hePtr) {
- int word;
- int cmd = PTR2INT(Tcl_GetHashValue(hePtr));
- ECL *ePtr = &eclPtr->loc[cmd];
- CFWordBC *lastPtr = NULL;
+ ePtr = &eclPtr->loc[cmd];
- /*
- * A few truths ...
- * (1) ePtr->nline == objc
- * (2) (ePtr->line[word] < 0) => !literal, for all words
- * (3) (word == 0) => !literal
- *
- * Item (2) is why we can use objv to get the literals, and do not
- * have to save them at compile time.
- */
+ /*
+ * ePtr->nline is the number of words originally parsed.
+ *
+ * objc is the number of elements getting invoked.
+ *
+ * If they are not the same, we arrived here by compiling an
+ * ensemble dispatch. Ensemble subcommands that lead to script
+ * evaluation are not supposed to get compiled, because a command
+ * such as [info level] in the script can expose some of the dispatch
+ * shenanigans. This means that we don't have to tend to the
+ * housekeeping, and can escape now.
+ */
+
+ if (ePtr->nline != objc) {
+ return;
+ }
- if (ePtr->nline != objc) {
- Tcl_Panic ("TIP 280 data structure inconsistency");
- }
+ /*
+ * Having disposed of the ensemble cases, we can state...
+ * A few truths ...
+ * (1) ePtr->nline == objc
+ * (2) (ePtr->line[word] < 0) => !literal, for all words
+ * (3) (word == 0) => !literal
+ *
+ * Item (2) is why we can use objv to get the literals, and do not
+ * have to save them at compile time.
+ */
- for (word = 1; word < objc; word++) {
- if (ePtr->line[word] >= 0) {
- int isnew;
- Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(iPtr->lineLABCPtr,
- objv[word], &isnew);
- CFWordBC *cfwPtr = ckalloc(sizeof(CFWordBC));
-
- cfwPtr->framePtr = cfPtr;
- cfwPtr->obj = objv[word];
- cfwPtr->pc = pc;
- cfwPtr->word = word;
- cfwPtr->nextPtr = lastPtr;
- lastPtr = cfwPtr;
-
- if (isnew) {
- /*
- * The word is not on the stack yet, remember the current
- * location and initialize references.
- */
-
- cfwPtr->prevPtr = NULL;
- } else {
- /*
- * The object is already on the stack, however it may have
- * a different location now (literal sharing may map
- * multiple location to a single Tcl_Obj*. Save the old
- * information in the new structure.
- */
-
- cfwPtr->prevPtr = Tcl_GetHashValue(hPtr);
- }
+ for (word = 1; word < objc; word++) {
+ if (ePtr->line[word] >= 0) {
+ int isnew;
+ Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(iPtr->lineLABCPtr,
+ objv[word], &isnew);
+ CFWordBC *cfwPtr = ckalloc(sizeof(CFWordBC));
+
+ cfwPtr->framePtr = cfPtr;
+ cfwPtr->obj = objv[word];
+ cfwPtr->pc = pc;
+ cfwPtr->word = word;
+ cfwPtr->nextPtr = lastPtr;
+ lastPtr = cfwPtr;
+
+ if (isnew) {
+ /*
+ * The word is not on the stack yet, remember the current
+ * location and initialize references.
+ */
+
+ cfwPtr->prevPtr = NULL;
+ } else {
+ /*
+ * The object is already on the stack, however it may have
+ * a different location now (literal sharing may map
+ * multiple location to a single Tcl_Obj*. Save the old
+ * information in the new structure.
+ */
- Tcl_SetHashValue(hPtr, cfwPtr);
+ cfwPtr->prevPtr = Tcl_GetHashValue(hPtr);
}
- } /* for */
- cfPtr->litarg = lastPtr;
- } /* if */
+ Tcl_SetHashValue(hPtr, cfwPtr);
+ }
+ } /* for */
+
+ cfPtr->litarg = lastPtr;
}
/*
@@ -5779,6 +5843,7 @@ TclArgumentGet(
*----------------------------------------------------------------------
*/
+#undef Tcl_Eval
int
Tcl_Eval(
Tcl_Interp *interp, /* Token for command interpreter (returned by
@@ -5840,6 +5905,11 @@ Tcl_GlobalEvalObj(
* compiled into bytecodes if necessary, unless TCL_EVAL_DIRECT is
* specified.
*
+ * If the flag TCL_EVAL_DIRECT is passed in, the value of invoker
+ * must be NULL. Support for non-NULL invokers in that mode has
+ * been removed since it was unused and untested. Failure to
+ * follow this limitation will lead to an assertion panic.
+ *
* Results:
* The return value is one of the return codes defined in tcl.h (such as
* TCL_OK), and the interpreter's result contains a value to supplement
@@ -5903,18 +5973,17 @@ TclNREvalObjEx(
/*
* This function consists of three independent blocks for: direct
- * evaluation of canonical lists, compileation and bytecode execution and
+ * evaluation of canonical lists, compilation and bytecode execution and
* finally direct evaluation. Precisely one of these blocks will be run.
*/
if (TclListObjIsCanonical(objPtr)) {
- Tcl_Obj *listPtr = objPtr;
CmdFrame *eoFramePtr = NULL;
int objc;
- Tcl_Obj **objv;
+ Tcl_Obj *listPtr, **objv;
/*
- * Pure List Optimization (no string representation). In this case, we
+ * Canonical List Optimization: In this case, we
* can safely use Tcl_EvalObjv instead and get an appreciable
* improvement in execution speed. This is because it allows us to
* avoid a setFromAny step that would just pack everything into a
@@ -5922,11 +5991,6 @@ TclNREvalObjEx(
*
* This also preserves any associations between list elements and
* location information for such elements.
- *
- * This restriction has been relaxed a bit by storing in lists whether
- * they are "canonical" or not (a canonical list being one that is
- * either pure or that has its string rep derived by
- * UpdateStringOfList from the internal rep).
*/
/*
@@ -5935,13 +5999,13 @@ TclNREvalObjEx(
* we always make a copy. The callback takes care od the refCounts for
* both listPtr and objPtr.
*
+ * TODO: Create a test to demo this need, or eliminate it.
* FIXME OPT: preserve just the internal rep?
*/
Tcl_IncrRefCount(objPtr);
listPtr = TclListObjCopy(interp, objPtr);
Tcl_IncrRefCount(listPtr);
- TclDecrRefCount(objPtr);
if (word != INT_MIN) {
/*
@@ -5964,21 +6028,25 @@ TclNREvalObjEx(
eoFramePtr->nline = 0;
eoFramePtr->line = NULL;
- eoFramePtr->type = TCL_LOCATION_EVAL_LIST;
+ eoFramePtr->type = TCL_LOCATION_EVAL;
eoFramePtr->level = (iPtr->cmdFramePtr == NULL?
1 : iPtr->cmdFramePtr->level + 1);
- eoFramePtr->numLevels = iPtr->numLevels;
eoFramePtr->framePtr = iPtr->framePtr;
eoFramePtr->nextPtr = iPtr->cmdFramePtr;
- eoFramePtr->cmd.listPtr = listPtr;
+ eoFramePtr->cmdObj = objPtr;
+ eoFramePtr->cmd = NULL;
+ eoFramePtr->len = 0;
eoFramePtr->data.eval.path = NULL;
iPtr->cmdFramePtr = eoFramePtr;
+
+ flags |= TCL_EVAL_SOURCE_IN_FRAME;
}
- TclNRDeferCallback(interp, TEOEx_ListCallback, listPtr, eoFramePtr,
- NULL, NULL);
+ TclMarkTailcall(interp);
+ TclNRAddCallback(interp, TEOEx_ListCallback, listPtr, eoFramePtr,
+ objPtr, NULL);
ListObjGetElements(listPtr, objc, objv);
return TclNREvalObjv(interp, objc, objv, flags, NULL);
@@ -6018,14 +6086,6 @@ TclNREvalObjEx(
* We're not supposed to use the compiler or byte-code
* interpreter. Let Tcl_EvalEx evaluate the command directly (and
* probably more slowly).
- *
- * TIP #280. Propagate context as much as we can. Especially if the
- * script to evaluate is a single literal it makes sense to look if
- * our context is one with absolute line numbers we can then track
- * into the literal itself too.
- *
- * See also tclCompile.c, TclInitCompileEnv, for the equivalent code
- * in the bytecode compiler.
*/
const char *script;
@@ -6049,92 +6109,19 @@ TclNREvalObjEx(
*/
ContLineLoc *saveCLLocPtr = iPtr->scriptCLLocPtr;
- ContLineLoc *clLocPtr = TclContinuationsGet(objPtr);
-
- if (clLocPtr) {
- iPtr->scriptCLLocPtr = clLocPtr;
- Tcl_Preserve(iPtr->scriptCLLocPtr);
- } else {
- iPtr->scriptCLLocPtr = NULL;
- }
-
- Tcl_IncrRefCount(objPtr);
- if (invoker == NULL) {
- /*
- * No context, force opening of our own.
- */
-
- script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
- result = Tcl_EvalEx(interp, script, numSrcBytes, flags);
- } else {
- /*
- * We have an invoker, describing the command asking for the
- * evaluation of a subordinate script. This script may originate
- * in a literal word, or from a variable, etc. Using the line
- * array we now check if we have good line information for the
- * relevant word. The type of context is relevant as well. In a
- * non-'source' context we don't have to try tracking lines.
- *
- * First see if the word exists and is a literal. If not we go
- * through the easy dynamic branch. No need to perform more
- * complex invokations.
- */
- int pc = 0;
- CmdFrame *ctxPtr = TclStackAlloc(interp, sizeof(CmdFrame));
+ assert(invoker == NULL);
- *ctxPtr = *invoker;
- if (invoker->type == TCL_LOCATION_BC) {
- /*
- * Note: Type BC => ctxPtr->data.eval.path is not used.
- * ctxPtr->data.tebc.codePtr is used instead.
- */
-
- TclGetSrcInfoForPc(ctxPtr);
- pc = 1;
- }
-
- script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
-
- if ((invoker->nline <= word) ||
- (invoker->line[word] < 0) ||
- (ctxPtr->type != TCL_LOCATION_SOURCE)) {
- /*
- * Dynamic script, or dynamic context, force our own context.
- */
-
- result = Tcl_EvalEx(interp, script, numSrcBytes, flags);
- } else {
- /*
- * Absolute context to reuse.
- */
-
- iPtr->invokeCmdFramePtr = ctxPtr;
- iPtr->evalFlags |= TCL_EVAL_CTX;
+ iPtr->scriptCLLocPtr = TclContinuationsGet(objPtr);
- result = TclEvalEx(interp, script, numSrcBytes, flags,
- ctxPtr->line[word], NULL, script);
- }
- if (pc && (ctxPtr->type == TCL_LOCATION_SOURCE)) {
- /*
- * Death of SrcInfo reference.
- */
+ Tcl_IncrRefCount(objPtr);
- Tcl_DecrRefCount(ctxPtr->data.eval.path);
- }
- TclStackFree(interp, ctxPtr);
- }
+ script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
+ result = Tcl_EvalEx(interp, script, numSrcBytes, flags);
- /*
- * Now release the lock on the continuation line information, if any,
- * and restore the caller's settings.
- */
+ TclDecrRefCount(objPtr);
- if (iPtr->scriptCLLocPtr) {
- Tcl_Release(iPtr->scriptCLLocPtr);
- }
iPtr->scriptCLLocPtr = saveCLLocPtr;
- TclDecrRefCount(objPtr);
return result;
}
}
@@ -6194,6 +6181,7 @@ TEOEx_ListCallback(
Interp *iPtr = (Interp *) interp;
Tcl_Obj *listPtr = data[0];
CmdFrame *eoFramePtr = data[1];
+ Tcl_Obj *objPtr = data[2];
/*
* Remove the cmdFrame
@@ -6203,6 +6191,7 @@ TEOEx_ListCallback(
iPtr->cmdFramePtr = eoFramePtr->nextPtr;
TclStackFree(interp, eoFramePtr);
}
+ TclDecrRefCount(objPtr);
TclDecrRefCount(listPtr);
return result;
@@ -6238,11 +6227,11 @@ ProcessUnexpectedResult(
Tcl_ResetResult(interp);
if (returnCode == TCL_BREAK) {
- Tcl_AppendResult(interp,
- "invoked \"break\" outside of a loop", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "invoked \"break\" outside of a loop", -1));
} else if (returnCode == TCL_CONTINUE) {
- Tcl_AppendResult(interp,
- "invoked \"continue\" outside of a loop", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "invoked \"continue\" outside of a loop", -1));
} else {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"command returned bad code: %d", returnCode));
@@ -6565,29 +6554,32 @@ TclObjInvoke(
* TCL_INVOKE_HIDDEN, TCL_INVOKE_NO_UNKNOWN,
* or TCL_INVOKE_NO_TRACEBACK. */
{
- register Interp *iPtr = (Interp *) interp;
- Tcl_HashTable *hTblPtr; /* Table of hidden commands. */
- const char *cmdName; /* Name of the command from objv[0]. */
- Tcl_HashEntry *hPtr = NULL;
- Command *cmdPtr;
- int result;
-
if (interp == NULL) {
return TCL_ERROR;
}
-
if ((objc < 1) || (objv == NULL)) {
- Tcl_AppendResult(interp, "illegal argument vector", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "illegal argument vector", -1));
return TCL_ERROR;
}
-
if ((flags & TCL_INVOKE_HIDDEN) == 0) {
Tcl_Panic("TclObjInvoke: called without TCL_INVOKE_HIDDEN");
}
+ return Tcl_NRCallObjProc(interp, TclNRInvoke, NULL, objc, objv);
+}
- if (TclInterpReady(interp) == TCL_ERROR) {
- return TCL_ERROR;
- }
+int
+TclNRInvoke(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ register Interp *iPtr = (Interp *) interp;
+ Tcl_HashTable *hTblPtr; /* Table of hidden commands. */
+ const char *cmdName; /* Name of the command from objv[0]. */
+ Tcl_HashEntry *hPtr = NULL;
+ Command *cmdPtr;
cmdName = TclGetString(objv[0]);
hTblPtr = iPtr->hiddenCmdTablePtr;
@@ -6595,44 +6587,35 @@ TclObjInvoke(
hPtr = Tcl_FindHashEntry(hTblPtr, cmdName);
}
if (hPtr == NULL) {
- Tcl_AppendResult(interp, "invalid hidden command name \"",
- cmdName, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid hidden command name \"%s\"", cmdName));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "HIDDENTOKEN", cmdName,
NULL);
return TCL_ERROR;
}
cmdPtr = Tcl_GetHashValue(hPtr);
- /*
- * Invoke the command function.
- */
-
- iPtr->cmdCount++;
- if (cmdPtr->objProc != NULL) {
- result = cmdPtr->objProc(cmdPtr->objClientData, interp, objc, objv);
- } else {
- result = Tcl_NRCallObjProc(interp, cmdPtr->nreProc,
- cmdPtr->objClientData, objc, objv);
- }
+ /* Avoid the exception-handling brain damage when numLevels == 0 . */
+ iPtr->numLevels++;
+ Tcl_NRAddCallback(interp, NRPostInvoke, NULL, NULL, NULL, NULL);
/*
- * If an error occurred, record information about what was being executed
- * when the error occurred.
+ * Normal command resolution of objv[0] isn't going to find cmdPtr.
+ * That's the whole point of **hidden** commands. So tell the
+ * Eval core machinery not to even try (and risk finding something wrong).
*/
- if ((result == TCL_ERROR)
- && ((flags & TCL_INVOKE_NO_TRACEBACK) == 0)
- && ((iPtr->flags & ERR_ALREADY_LOGGED) == 0)) {
- int length;
- Tcl_Obj *command = Tcl_NewListObj(objc, objv);
- const char *cmdString;
+ return TclNREvalObjv(interp, objc, objv, TCL_EVAL_NORESOLVE, cmdPtr);
+}
- Tcl_IncrRefCount(command);
- cmdString = Tcl_GetStringFromObj(command, &length);
- Tcl_LogCommandInfo(interp, cmdString, cmdString, length);
- Tcl_DecrRefCount(command);
- iPtr->flags &= ~ERR_ALREADY_LOGGED;
- }
+static int
+NRPostInvoke(
+ ClientData clientData[],
+ Tcl_Interp *interp,
+ int result)
+{
+ Interp *iPtr = (Interp *)interp;
+ iPtr->numLevels--;
return result;
}
@@ -6709,6 +6692,7 @@ Tcl_ExprString(
*----------------------------------------------------------------------
*/
+#undef Tcl_AddObjErrorInfo
void
Tcl_AppendObjToErrorInfo(
Tcl_Interp *interp, /* Interpreter to which error information
@@ -6742,6 +6726,7 @@ Tcl_AppendObjToErrorInfo(
*----------------------------------------------------------------------
*/
+#undef Tcl_AddErrorInfo
void
Tcl_AddErrorInfo(
Tcl_Interp *interp, /* Interpreter to which error information
@@ -6922,6 +6907,7 @@ Tcl_VarEval(
*----------------------------------------------------------------------
*/
+#undef Tcl_GlobalEval
int
Tcl_GlobalEval(
Tcl_Interp *interp, /* Interpreter in which to evaluate
@@ -7222,7 +7208,8 @@ ExprIsqrtFunc(
return TCL_OK;
negarg:
- Tcl_SetResult(interp, "square root of negative argument", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "square root of negative argument", -1));
Tcl_SetErrorCode(interp, "ARITH", "DOMAIN",
"domain error: argument not in valid range", NULL);
return TCL_ERROR;
@@ -7439,7 +7426,7 @@ ExprAbsFunc(
return TCL_OK;
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if (type == TCL_NUMBER_WIDE) {
Tcl_WideInt w = *((const Tcl_WideInt *) ptr);
@@ -8079,39 +8066,11 @@ Tcl_NRCallObjProc(
int objc,
Tcl_Obj *const objv[])
{
- int result = TCL_OK;
NRE_callback *rootPtr = TOP_CB(interp);
-#ifdef USE_DTRACE
- if (TCL_DTRACE_CMD_ARGS_ENABLED()) {
- const char *a[10];
- int i = 0;
-
- while (i < 10) {
- a[i] = i < objc ? TclGetString(objv[i]) : NULL; i++;
- }
- TCL_DTRACE_CMD_ARGS(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
- a[8], a[9]);
- }
- if (TCL_DTRACE_CMD_INFO_ENABLED() && ((Interp *) interp)->cmdFramePtr) {
- Tcl_Obj *info = TclInfoFrame(interp, ((Interp *) interp)->cmdFramePtr);
- const char *a[6]; int i[2];
-
- TclDTraceInfo(info, a, i);
- TCL_DTRACE_CMD_INFO(a[0], a[1], a[2], a[3], i[0], i[1], a[4], a[5]);
- TclDecrRefCount(info);
- }
- if ((TCL_DTRACE_CMD_RETURN_ENABLED() || TCL_DTRACE_CMD_RESULT_ENABLED())
- && objc) {
- TclNRAddCallback(interp, DTraceCmdReturn, objv[0], NULL, NULL, NULL);
- }
- if (TCL_DTRACE_CMD_ENTRY_ENABLED() && objc) {
- TCL_DTRACE_CMD_ENTRY(TclGetString(objv[0]), objc - 1,
- (Tcl_Obj **)(objv + 1));
- }
-#endif /* USE_DTRACE */
- result = objProc(clientData, interp, objc, objv);
- return TclNRRunCallbacks(interp, result, rootPtr);
+ TclNRAddCallback(interp, Dispatch, objProc, clientData,
+ INT2PTR(objc), objv);
+ return TclNRRunCallbacks(interp, TCL_OK, rootPtr);
}
/*
@@ -8204,7 +8163,8 @@ Tcl_NRCmdSwap(
Tcl_Obj *const objv[],
int flags)
{
- return TclNREvalObjv(interp, objc, objv, flags, (Command *) cmd);
+ return TclNREvalObjv(interp, objc, objv, flags|TCL_EVAL_NOERR,
+ (Command *) cmd);
}
/*****************************************************************************
@@ -8232,29 +8192,58 @@ Tcl_NRCmdSwap(
*/
void
-TclSpliceTailcall(
+TclMarkTailcall(
+ Tcl_Interp *interp)
+{
+ Interp *iPtr = (Interp *) interp;
+
+ if (iPtr->deferredCallbacks == NULL) {
+ TclNRAddCallback(interp, NRCommand, NULL, NULL,
+ NULL, NULL);
+ iPtr->deferredCallbacks = TOP_CB(interp);
+ }
+}
+
+void
+TclSkipTailcall(
+ Tcl_Interp *interp)
+{
+ Interp *iPtr = (Interp *) interp;
+
+ TclMarkTailcall(interp);
+ iPtr->deferredCallbacks->data[1] = INT2PTR(1);
+}
+
+void
+TclPushTailcallPoint(
+ Tcl_Interp *interp)
+{
+ TclNRAddCallback(interp, NRCommand, NULL, NULL, NULL, NULL);
+ ((Interp *) interp)->numLevels++;
+}
+
+void
+TclSetTailcall(
Tcl_Interp *interp,
- NRE_callback *tailcallPtr)
+ Tcl_Obj *listPtr)
{
/*
* Find the splicing spot: right before the NRCommand of the thing
- * being tailcalled. Note that we skip NRCommands marked in data[1]
+ * being tailcalled. Note that we skip NRCommands marked by a 1 in data[1]
* (used by command redirectors).
*/
NRE_callback *runPtr;
for (runPtr = TOP_CB(interp); runPtr; runPtr = runPtr->nextPtr) {
- if (((runPtr->procPtr) == NRCommand) && !runPtr->data[1]) {
+ if (((runPtr->procPtr) == NRCommand) && !runPtr->data[1]) {
break;
}
}
if (!runPtr) {
Tcl_Panic("tailcall cannot find the right splicing spot: should not happen!");
}
-
- tailcallPtr->nextPtr = runPtr->nextPtr;
- runPtr->nextPtr = tailcallPtr;
+ runPtr->data[1] = listPtr;
}
int
@@ -8271,10 +8260,9 @@ TclNRTailcallObjCmd(
return TCL_ERROR;
}
- if (!iPtr->varFramePtr->isProcCallFrame) { /* or is upleveled */
- Tcl_SetResult(interp,
- "tailcall can only be called from a proc or lambda",
- TCL_STATIC);
+ if (!(iPtr->varFramePtr->isProcCallFrame & 1)) { /* or is upleveled */
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "tailcall can only be called from a proc or lambda", -1));
Tcl_SetErrorCode(interp, "TCL", "TAILCALL", "ILLEGAL", NULL);
return TCL_ERROR;
}
@@ -8285,7 +8273,7 @@ TclNRTailcallObjCmd(
*/
if (iPtr->varFramePtr->tailcallPtr) {
- ClearTailcall(interp, iPtr->varFramePtr->tailcallPtr);
+ Tcl_DecrRefCount(iPtr->varFramePtr->tailcallPtr);
iPtr->varFramePtr->tailcallPtr = NULL;
}
@@ -8300,39 +8288,39 @@ TclNRTailcallObjCmd(
Tcl_Obj *listPtr, *nsObjPtr;
Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
Tcl_Namespace *ns1Ptr;
- NRE_callback *tailcallPtr;
+
+ /* 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-1, objv+1);
- Tcl_IncrRefCount(listPtr);
+ 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");
}
- Tcl_IncrRefCount(nsObjPtr);
-
- TclNRAddCallback(interp, NRTailcallEval, listPtr, nsObjPtr, NULL, NULL);
- tailcallPtr = TOP_CB(interp);
- TOP_CB(interp) = tailcallPtr->nextPtr;
- iPtr->varFramePtr->tailcallPtr = tailcallPtr;
+ TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
+
+ iPtr->varFramePtr->tailcallPtr = listPtr;
}
return TCL_RETURN;
}
int
-NRTailcallEval(
+TclNRTailcallEval(
ClientData data[],
Tcl_Interp *interp,
int result)
{
Interp *iPtr = (Interp *) interp;
- Tcl_Obj *listPtr = data[0];
- Tcl_Obj *nsObjPtr = data[1];
+ Tcl_Obj *listPtr = data[0], *nsObjPtr;
Tcl_Namespace *nsPtr;
int objc;
Tcl_Obj **objv;
+ Tcl_ListObjGetElements(interp, listPtr, &objc, &objv);
+ nsObjPtr = objv[0];
+
if (result == TCL_OK) {
result = TclGetNamespaceFromObj(interp, nsObjPtr, &nsPtr);
}
@@ -8342,7 +8330,7 @@ NRTailcallEval(
* Tailcall execution was preempted, eg by an intervening catch or by
* a now-gone namespace: cleanup and return.
*/
-
+
TailcallCleanup(data, interp, result);
return result;
}
@@ -8351,10 +8339,10 @@ NRTailcallEval(
* Perform the tailcall
*/
- TclNRDeferCallback(interp, TailcallCleanup, listPtr, nsObjPtr, NULL,NULL);
+ TclMarkTailcall(interp);
+ TclNRAddCallback(interp, TailcallCleanup, listPtr, NULL, NULL,NULL);
iPtr->lookupNsPtr = (Namespace *) nsPtr;
- ListObjGetElements(listPtr, objc, objv);
- return TclNREvalObjv(interp, objc, objv, 0, NULL);
+ return TclNREvalObjv(interp, objc-1, objv+1, 0, NULL);
}
static int
@@ -8364,19 +8352,9 @@ TailcallCleanup(
int result)
{
Tcl_DecrRefCount((Tcl_Obj *) data[0]);
- Tcl_DecrRefCount((Tcl_Obj *) data[1]);
return result;
}
-static void
-ClearTailcall(
- Tcl_Interp *interp,
- NRE_callback *tailcallPtr)
-{
- TailcallCleanup(tailcallPtr->data, interp, TCL_OK);
- TCLNR_FREE(interp, tailcallPtr);
-}
-
void
Tcl_NRAddCallback(
@@ -8425,14 +8403,15 @@ TclNRYieldObjCmd(
Tcl_Obj *const objv[])
{
CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
+
if (objc > 2) {
Tcl_WrongNumArgs(interp, 1, objv, "?returnValue?");
return TCL_ERROR;
}
if (!corPtr) {
- Tcl_SetResult(interp, "yield can only be called in a coroutine",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "yield can only be called in a coroutine", -1));
Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD", NULL);
return TCL_ERROR;
}
@@ -8442,7 +8421,7 @@ TclNRYieldObjCmd(
}
NRE_ASSERT(!COR_IS_SUSPENDED(corPtr));
- TclNRAddCallback(interp, NRCoroutineActivateCallback, corPtr,
+ TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
clientData, NULL, NULL);
return TCL_OK;
}
@@ -8456,8 +8435,7 @@ TclNRYieldToObjCmd(
{
CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
Tcl_Obj *listPtr, *nsObjPtr;
- Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
- Tcl_Namespace *ns1Ptr;
+ Tcl_Namespace *nsPtr = TclGetCurrentNamespace(interp);
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "command ?arg ...?");
@@ -8465,61 +8443,39 @@ TclNRYieldToObjCmd(
}
if (!corPtr) {
- Tcl_SetResult(interp, "yieldTo can only be called in a coroutine",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "yieldto can only be called in a coroutine", -1));
Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD", NULL);
return TCL_ERROR;
}
+ if (((Namespace *) nsPtr)->flags & NS_DYING) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "yieldto called in deleted namespace", -1));
+ Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "YIELDTO_IN_DELETED",
+ NULL);
+ return TCL_ERROR;
+ }
+
/*
* Add the tailcall in the caller env, then just yield.
*
* This is essentially code from TclNRTailcallObjCmd
*/
- listPtr = Tcl_NewListObj(objc-1, objv+1);
- Tcl_IncrRefCount(listPtr);
-
+ listPtr = Tcl_NewListObj(objc, objv);
nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
- if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr))
- || (nsPtr != ns1Ptr)) {
- Tcl_Panic("yieldTo failed to find the proper namespace");
- }
- Tcl_IncrRefCount(nsObjPtr);
+ TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
/*
* Add the callback in the caller's env, then instruct TEBC to yield.
*/
iPtr->execEnvPtr = corPtr->callerEEPtr;
- TclNRAddCallback(interp, YieldToCallback, corPtr, listPtr, nsObjPtr,
- NULL);
+ TclSetTailcall(interp, listPtr);
iPtr->execEnvPtr = corPtr->eePtr;
- return TclNRYieldObjCmd(clientData, interp, 1, objv);
-}
-
-static int
-YieldToCallback(
- ClientData data[],
- Tcl_Interp *interp,
- int result)
-{
- /* CoroutineData *corPtr = data[0];*/
- Tcl_Obj *listPtr = data[1];
- ClientData nsPtr = data[2];
- NRE_callback *cbPtr;
-
- /*
- * yieldTo: invoke the command using tailcall tech.
- */
-
- TclNRAddCallback(interp, NRTailcallEval, listPtr, nsPtr, NULL, NULL);
- cbPtr = TOP_CB(interp);
- TOP_CB(interp) = cbPtr->nextPtr;
-
- TclSpliceTailcall(interp, cbPtr);
- return TCL_OK;
+ return TclNRYieldObjCmd(INT2PTR(CORO_ACTIVATE_YIELDM), interp, 1, objv);
}
static int
@@ -8546,7 +8502,7 @@ RewindCoroutine(
corPtr->eePtr->rewind = 1;
TclNRAddCallback(interp, RewindCoroutineCallback, state,
NULL, NULL, NULL);
- return NRInterpCoroutine(corPtr, interp, 0, NULL);
+ return TclNRInterpCoroutine(corPtr, interp, 0, NULL);
}
static void
@@ -8594,7 +8550,7 @@ NRCoroutineCallerCallback(
NRE_ASSERT(COR_IS_SUSPENDED(corPtr));
SAVE_CONTEXT(corPtr->running);
RESTORE_CONTEXT(corPtr->caller);
-
+
if (cmdPtr->flags & CMD_IS_DELETED) {
/*
* The command was deleted while it was running: wind down the
@@ -8656,20 +8612,25 @@ NRCoroutineExitCallback(
return result;
}
-
/*
- * NRCoroutineActivateCallback --
+ *----------------------------------------------------------------------
*
- * This is the workhorse for coroutines: it implements both yield and resume.
+ * TclNRCoroutineActivateCallback --
*
- * It is important that both be implemented in the same callback: the
- * detection of the impossibility to suspend due to a busy C-stack relies on
- * the precise position of a local variable in the stack. We do not want the
- * compiler to play tricks on us, either by moving things around or inlining.
+ * This is the workhorse for coroutines: it implements both yield and
+ * resume.
+ *
+ * It is important that both be implemented in the same callback: the
+ * detection of the impossibility to suspend due to a busy C-stack relies
+ * on the precise position of a local variable in the stack. We do not
+ * want the compiler to play tricks on us, either by moving things around
+ * or inlining.
+ *
+ *----------------------------------------------------------------------
*/
-static int
-NRCoroutineActivateCallback(
+int
+TclNRCoroutineActivateCallback(
ClientData data[],
Tcl_Interp *interp,
int result)
@@ -8682,18 +8643,18 @@ NRCoroutineActivateCallback(
if (!corPtr->stackLevel) {
/*
* -- Coroutine is suspended --
- * Push the callback to restore the caller's context on yield or return
+ * Push the callback to restore the caller's context on yield or
+ * return.
*/
- TclNRAddCallback(interp, NRCoroutineCallerCallback, corPtr, NULL, NULL,
- NULL);
+ TclNRAddCallback(interp, NRCoroutineCallerCallback, corPtr,
+ NULL, NULL, NULL);
/*
* Record the stackLevel at which the resume is happening, then swap
- * the interp's environment to make it suitable to run this
- * coroutine.
+ * the interp's environment to make it suitable to run this coroutine.
*/
-
+
corPtr->stackLevel = stackLevel;
numLevels = corPtr->auxNumLevels;
corPtr->auxNumLevels = iPtr->numLevels;
@@ -8703,29 +8664,27 @@ NRCoroutineActivateCallback(
RESTORE_CONTEXT(corPtr->running);
iPtr->execEnvPtr = corPtr->eePtr;
iPtr->numLevels += numLevels;
-
- return TCL_OK;
} else {
/*
* Coroutine is active: yield
*/
if (corPtr->stackLevel != stackLevel) {
- Tcl_SetResult(interp, "cannot yield: C stack busy",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "cannot yield: C stack busy", -1));
Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "CANT_YIELD",
NULL);
return TCL_ERROR;
}
-
- if (type == CORO_ACTIVATE_YIELD) {
+
+ if (type == CORO_ACTIVATE_YIELD) {
corPtr->nargs = COROUTINE_ARGUMENTS_SINGLE_OPTIONAL;
} else if (type == CORO_ACTIVATE_YIELDM) {
corPtr->nargs = COROUTINE_ARGUMENTS_ARBITRARY;
} else {
Tcl_Panic("Yield received an option which is not implemented");
}
-
+
corPtr->stackLevel = NULL;
numLevels = iPtr->numLevels;
@@ -8733,10 +8692,20 @@ NRCoroutineActivateCallback(
corPtr->auxNumLevels = numLevels - corPtr->auxNumLevels;
iPtr->execEnvPtr = corPtr->callerEEPtr;
- return TCL_OK;
}
+
+ return TCL_OK;
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * NRCoroInjectObjCmd --
+ *
+ * Implementation of [::tcl::unsupported::inject] command.
+ *
+ *----------------------------------------------------------------------
+ */
static int
NRCoroInjectObjCmd(
@@ -8748,7 +8717,7 @@ NRCoroInjectObjCmd(
Command *cmdPtr;
CoroutineData *corPtr;
ExecEnv *savedEEPtr = iPtr->execEnvPtr;
-
+
/*
* Usage more or less like tailcall:
* inject coroName cmd ?arg1 arg2 ...?
@@ -8760,31 +8729,36 @@ NRCoroInjectObjCmd(
}
cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objv[1]);
- if ((!cmdPtr) || (cmdPtr->nreProc != NRInterpCoroutine)) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj("can only inject a command into a coroutine", -1));
+ if ((!cmdPtr) || (cmdPtr->nreProc != TclNRInterpCoroutine)) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "can only inject a command into a coroutine", -1));
+ Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COROUTINE",
+ TclGetString(objv[1]), NULL);
return TCL_ERROR;
}
- corPtr = (CoroutineData *) cmdPtr->objClientData;
+ corPtr = cmdPtr->objClientData;
if (!COR_IS_SUSPENDED(corPtr)) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj("can only inject a command into a suspended coroutine", -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "can only inject a command into a suspended coroutine", -1));
+ Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ACTIVE", NULL);
return TCL_ERROR;
}
/*
* Add the callback to the coro's execEnv, so that it is the first thing
- * to happen when the coro is resumed
+ * to happen when the coro is resumed.
*/
-
+
iPtr->execEnvPtr = corPtr->eePtr;
- Tcl_NREvalObj(interp, Tcl_NewListObj(objc-2, objv+2), 0);
+ TclNREvalObjEx(interp, Tcl_NewListObj(objc-2, objv+2), 0, NULL, INT_MIN);
iPtr->execEnvPtr = savedEEPtr;
-
+
return TCL_OK;
}
-
+
int
-NRInterpCoroutine(
+TclNRInterpCoroutine(
ClientData clientData,
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
@@ -8793,9 +8767,9 @@ NRInterpCoroutine(
CoroutineData *corPtr = clientData;
if (!COR_IS_SUSPENDED(corPtr)) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "coroutine \"", Tcl_GetString(objv[0]),
- "\" is already running", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "coroutine \"%s\" is already running",
+ Tcl_GetString(objv[0])));
Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "BUSY", NULL);
return TCL_ERROR;
}
@@ -8831,11 +8805,22 @@ NRInterpCoroutine(
break;
}
- TclNRAddCallback(interp, NRCoroutineActivateCallback, corPtr,
+ TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
NULL, NULL, NULL);
return TCL_OK;
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNRCoroutineObjCmd --
+ *
+ * Implementation of [coroutine] command; see documentation for
+ * description of what this does.
+ *
+ *----------------------------------------------------------------------
+ */
+
int
TclNRCoroutineObjCmd(
ClientData dummy, /* Not used. */
@@ -8849,7 +8834,7 @@ TclNRCoroutineObjCmd(
Namespace *nsPtr, *altNsPtr, *cxtNsPtr;
Tcl_DString ds;
Namespace *lookupNsPtr = iPtr->varFramePtr->nsPtr;
-
+
if (objc < 3) {
Tcl_WrongNumArgs(interp, 1, objv, "name cmd ?arg ...?");
return TCL_ERROR;
@@ -8865,22 +8850,24 @@ TclNRCoroutineObjCmd(
&nsPtr, &altNsPtr, &cxtNsPtr, &procName);
if (nsPtr == NULL) {
- Tcl_AppendResult(interp, "can't create procedure \"", fullName,
- "\": unknown namespace", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't create procedure \"%s\": unknown namespace",
+ fullName));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", NULL);
return TCL_ERROR;
}
if (procName == NULL) {
- Tcl_AppendResult(interp, "can't create procedure \"", fullName,
- "\": bad procedure name", 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_AppendResult(interp, "can't create procedure \"", procName,
- "\" in non-global namespace with name starting with \":\"",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't create procedure \"%s\" in non-global namespace with"
+ " name starting with \":\"", procName));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", procName, NULL);
return TCL_ERROR;
}
@@ -8895,12 +8882,12 @@ TclNRCoroutineObjCmd(
Tcl_DStringInit(&ds);
if (nsPtr != iPtr->globalNsPtr) {
Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
- Tcl_DStringAppend(&ds, "::", 2);
+ TclDStringAppendLiteral(&ds, "::");
}
Tcl_DStringAppend(&ds, procName, -1);
cmdPtr = (Command *) Tcl_NRCreateCommand(interp, Tcl_DStringValue(&ds),
- /*objProc*/ NULL, NRInterpCoroutine, corPtr, DeleteCoroutine);
+ /*objProc*/ NULL, TclNRInterpCoroutine, corPtr, DeleteCoroutine);
Tcl_DStringFree(&ds);
corPtr->cmdPtr = cmdPtr;
@@ -8944,17 +8931,16 @@ TclNRCoroutineObjCmd(
corPtr->running.lineLABCPtr = corPtr->lineLABCPtr;
corPtr->stackLevel = NULL;
corPtr->auxNumLevels = 0;
- iPtr->numLevels--;
-
+
/*
* Create the coro's execEnv, switch to it to push the exit and coro
- * command callbacks, then switch back.
+ * command callbacks, then switch back.
*/
corPtr->eePtr = TclCreateExecEnv(interp, CORO_STACK_INITIAL_SIZE);
corPtr->callerEEPtr = iPtr->execEnvPtr;
corPtr->eePtr->corPtr = corPtr;
-
+
SAVE_CONTEXT(corPtr->caller);
corPtr->callerEEPtr = iPtr->execEnvPtr;
RESTORE_CONTEXT(corPtr->running);
@@ -8963,19 +8949,20 @@ TclNRCoroutineObjCmd(
TclNRAddCallback(interp, NRCoroutineExitCallback, corPtr,
NULL, NULL, NULL);
+ /* insure 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--;
SAVE_CONTEXT(corPtr->running);
RESTORE_CONTEXT(corPtr->caller);
iPtr->execEnvPtr = corPtr->callerEEPtr;
-
+
/*
- * Now just resume the coroutine. Take care to insure that the command is
- * looked up in the correct namespace.
+ * Now just resume the coroutine.
*/
- TclNRAddCallback(interp, NRCoroutineActivateCallback, corPtr,
+ TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
NULL, NULL, NULL);
return TCL_OK;
}
diff --git a/generic/tclBinary.c b/generic/tclBinary.c
index 0a340f2..981f174 100644
--- a/generic/tclBinary.c
+++ b/generic/tclBinary.c
@@ -87,10 +87,13 @@ static int BinaryDecodeHex(ClientData clientData,
static int BinaryEncode64(ClientData clientData,
Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
-static int BinaryDecodeUu(ClientData clientData,
+static int BinaryDecode64(ClientData clientData,
Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
-static int BinaryDecode64(ClientData clientData,
+static int BinaryEncodeUu(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+static int BinaryDecodeUu(ClientData clientData,
Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
@@ -128,6 +131,30 @@ static const char B64Digits[65] = {
};
/*
+ * How to construct the ensembles.
+ */
+
+static const EnsembleImplMap binaryMap[] = {
+ { "format", BinaryFormatCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0 },
+ { "scan", BinaryScanCmd, TclCompileBasicMin2ArgCmd, NULL, NULL, 0 },
+ { "encode", NULL, NULL, NULL, NULL, 0 },
+ { "decode", NULL, NULL, NULL, NULL, 0 },
+ { NULL, NULL, NULL, NULL, NULL, 0 }
+};
+static const EnsembleImplMap encodeMap[] = {
+ { "hex", BinaryEncodeHex, TclCompileBasic1ArgCmd, NULL, NULL, 0 },
+ { "uuencode", BinaryEncodeUu, NULL, NULL, NULL, 0 },
+ { "base64", BinaryEncode64, NULL, NULL, NULL, 0 },
+ { NULL, NULL, NULL, NULL, NULL, 0 }
+};
+static const EnsembleImplMap decodeMap[] = {
+ { "hex", BinaryDecodeHex, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
+ { "uuencode", BinaryDecodeUu, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
+ { "base64", BinaryDecode64, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
+ { NULL, NULL, NULL, NULL, NULL, 0 }
+};
+
+/*
* The following object type represents an array of bytes. An array of bytes
* is not equivalent to an internationalized string. Conceptually, a string is
* an array of 16-bit quantities organized as a sequence of properly formed
@@ -180,9 +207,10 @@ typedef struct ByteArray {
#define BYTEARRAY_SIZE(len) \
((unsigned) (TclOffset(ByteArray, bytes) + (len)))
#define GET_BYTEARRAY(objPtr) \
- ((ByteArray *) (objPtr)->internalRep.otherValuePtr)
+ ((ByteArray *) (objPtr)->internalRep.twoPtrValue.ptr1)
#define SET_BYTEARRAY(objPtr, baPtr) \
- (objPtr)->internalRep.otherValuePtr = (void *) (baPtr)
+ (objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (baPtr)
+
/*
*----------------------------------------------------------------------
@@ -301,17 +329,18 @@ Tcl_SetByteArrayObj(
Tcl_Panic("%s called with shared object", "Tcl_SetByteArrayObj");
}
TclFreeIntRep(objPtr);
- Tcl_InvalidateStringRep(objPtr);
+ TclInvalidateStringRep(objPtr);
- length = (length < 0) ? 0 : length;
+ if (length < 0) {
+ length = 0;
+ }
byteArrayPtr = ckalloc(BYTEARRAY_SIZE(length));
- memset(byteArrayPtr, 0, BYTEARRAY_SIZE(length));
byteArrayPtr->used = length;
byteArrayPtr->allocated = length;
- if (bytes && length) {
+
+ if ((bytes != NULL) && (length > 0)) {
memcpy(byteArrayPtr->bytes, bytes, (size_t) length);
}
-
objPtr->typePtr = &tclByteArrayType;
SET_BYTEARRAY(objPtr, byteArrayPtr);
}
@@ -395,7 +424,7 @@ Tcl_SetByteArrayLength(
byteArrayPtr->allocated = length;
SET_BYTEARRAY(objPtr, byteArrayPtr);
}
- Tcl_InvalidateStringRep(objPtr);
+ TclInvalidateStringRep(objPtr);
byteArrayPtr->used = length;
return byteArrayPtr->bytes;
}
@@ -581,9 +610,7 @@ UpdateStringOfByteArray(
*
* This function appends an array of bytes to a byte array object. Note
* that the object *must* be unshared, and the array of bytes *must not*
- * refer to the object being appended to. Also the caller must have
- * already checked that the final length of the bytearray after the
- * append operations is complete will not overflow the int range.
+ * refer to the object being appended to.
*
* Results:
* None.
@@ -602,6 +629,7 @@ TclAppendBytesToByteArray(
int len)
{
ByteArray *byteArrayPtr;
+ int needed;
if (Tcl_IsShared(objPtr)) {
Tcl_Panic("%s called with shared object","TclAppendBytesToByteArray");
@@ -610,64 +638,57 @@ TclAppendBytesToByteArray(
Tcl_Panic("%s must be called with definite number of bytes to append",
"TclAppendBytesToByteArray");
}
+ if (len == 0) {
+ /* Append zero bytes is a no-op. */
+ return;
+ }
if (objPtr->typePtr != &tclByteArrayType) {
SetByteArrayFromAny(NULL, objPtr);
}
byteArrayPtr = GET_BYTEARRAY(objPtr);
+ if (len > INT_MAX - byteArrayPtr->used) {
+ Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+ }
+
+ needed = byteArrayPtr->used + len;
/*
* If we need to, resize the allocated space in the byte array.
*/
- if (byteArrayPtr->used + len > byteArrayPtr->allocated) {
- unsigned int attempt, used = byteArrayPtr->used;
- ByteArray *tmpByteArrayPtr = NULL;
-
- attempt = byteArrayPtr->allocated;
- if (attempt < 1) {
- /*
- * No allocated bytes, so must be none used too. We use this
- * method to calculate how many bytes to allocate because we can
- * end up with a zero-length buffer otherwise, when doubling can
- * cause trouble. [Bug 3067036]
- */
+ if (needed > byteArrayPtr->allocated) {
+ ByteArray *ptr = NULL;
+ int attempt;
- attempt = len + 1;
- } else {
- do {
- attempt *= 2;
- } while (attempt < used+len);
+ if (needed <= INT_MAX/2) {
+ /* Try to allocate double the total space that is needed. */
+ attempt = 2 * needed;
+ ptr = attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt));
}
-
- if (BYTEARRAY_SIZE(attempt) > BYTEARRAY_SIZE(used)) {
- tmpByteArrayPtr = attemptckrealloc(byteArrayPtr,
- BYTEARRAY_SIZE(attempt));
+ if (ptr == NULL) {
+ /* Try to allocate double the increment that is needed (plus). */
+ unsigned int limit = INT_MAX - needed;
+ unsigned int extra = len + TCL_MIN_GROWTH;
+ int growth = (int) ((extra > limit) ? limit : extra);
+
+ attempt = needed + growth;
+ ptr = attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt));
}
-
- if (tmpByteArrayPtr == NULL) {
- attempt = used + len;
- if (BYTEARRAY_SIZE(attempt) < BYTEARRAY_SIZE(used)) {
- Tcl_Panic("attempt to allocate a bigger buffer than we can handle");
- }
- tmpByteArrayPtr = ckrealloc(byteArrayPtr,
- BYTEARRAY_SIZE(attempt));
+ if (ptr == NULL) {
+ /* Last chance: Try to allocate exactly what is needed. */
+ attempt = needed;
+ ptr = ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt));
}
-
- byteArrayPtr = tmpByteArrayPtr;
+ byteArrayPtr = ptr;
byteArrayPtr->allocated = attempt;
- byteArrayPtr->used = used;
SET_BYTEARRAY(objPtr, byteArrayPtr);
}
- /*
- * Do the append if there's any point.
- */
-
- if (len > 0) {
+ if (bytes) {
memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, len);
- byteArrayPtr->used += len;
- Tcl_InvalidateStringRep(objPtr);
}
+ byteArrayPtr->used += len;
+ TclInvalidateStringRep(objPtr);
}
/*
@@ -687,26 +708,6 @@ TclAppendBytesToByteArray(
*----------------------------------------------------------------------
*/
-static const EnsembleImplMap binaryMap[] = {
-{ "format", BinaryFormatCmd, NULL, NULL, NULL, 0 },
-{ "scan", BinaryScanCmd, NULL, NULL, NULL, 0 },
-{ "encode", NULL, NULL, NULL, NULL, 0 },
-{ "decode", NULL, NULL, NULL, NULL, 0 },
-{ NULL, NULL, NULL, NULL, NULL, 0 }
-};
-static const EnsembleImplMap encodeMap[] = {
-{ "hex", BinaryEncodeHex, NULL, NULL, (ClientData)HexDigits, 0 },
-{ "uuencode", BinaryEncode64, NULL, NULL, (ClientData)UueDigits, 0 },
-{ "base64", BinaryEncode64, NULL, NULL, (ClientData)B64Digits, 0 },
-{ NULL, NULL, NULL, NULL, NULL, 0 }
-};
-static const EnsembleImplMap decodeMap[] = {
-{ "hex", BinaryDecodeHex, NULL, NULL, NULL, 0 },
-{ "uuencode", BinaryDecodeUu, NULL, NULL, NULL, 0 },
-{ "base64", BinaryDecode64, NULL, NULL, NULL, 0 },
-{ NULL, NULL, NULL, NULL, NULL, 0 }
-};
-
Tcl_Command
TclInitBinaryCmd(
Tcl_Interp *interp)
@@ -870,9 +871,9 @@ BinaryFormatCmd(
if (count == BINARY_ALL) {
count = listc;
} else if (count > listc) {
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"number of elements in list does not match count",
- NULL);
+ -1));
return TCL_ERROR;
}
}
@@ -881,9 +882,8 @@ BinaryFormatCmd(
case 'x':
if (count == BINARY_ALL) {
- Tcl_AppendResult(interp,
- "cannot use \"*\" in format string with \"x\"",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "cannot use \"*\" in format string with \"x\"", -1));
return TCL_ERROR;
} else if (count == BINARY_NOCOUNT) {
count = 1;
@@ -1195,8 +1195,9 @@ BinaryFormatCmd(
badValue:
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "expected ", errorString,
- " string but got \"", errorValue, "\" instead", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "expected %s string but got \"%s\" instead",
+ errorString, errorValue));
return TCL_ERROR;
badCount:
@@ -1214,12 +1215,13 @@ BinaryFormatCmd(
Tcl_UtfToUniChar(errorString, &ch);
buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
- Tcl_AppendResult(interp, "bad field specifier \"", buf, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad field specifier \"%s\"", buf));
return TCL_ERROR;
}
error:
- Tcl_AppendResult(interp, errorString, NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(errorString, -1));
return TCL_ERROR;
}
@@ -1583,12 +1585,13 @@ BinaryScanCmd(
Tcl_UtfToUniChar(errorString, &ch);
buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
- Tcl_AppendResult(interp, "bad field specifier \"", buf, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad field specifier \"%s\"", buf));
return TCL_ERROR;
}
error:
- Tcl_AppendResult(interp, errorString, NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(errorString, -1));
return TCL_ERROR;
}
@@ -2304,7 +2307,6 @@ BinaryEncodeHex(
Tcl_Obj *resultObj = NULL;
unsigned char *data = NULL;
unsigned char *cursor = NULL;
- const char *digits = clientData;
int offset = 0, count = 0;
if (objc != 2) {
@@ -2316,8 +2318,8 @@ BinaryEncodeHex(
data = Tcl_GetByteArrayFromObj(objv[1], &count);
cursor = Tcl_SetByteArrayLength(resultObj, count * 2);
for (offset = 0; offset < count; ++offset) {
- *cursor++ = digits[((data[offset] >> 4) & 0x0f)];
- *cursor++ = digits[(data[offset] & 0x0f)];
+ *cursor++ = HexDigits[((data[offset] >> 4) & 0x0f)];
+ *cursor++ = HexDigits[(data[offset] & 0x0f)];
}
Tcl_SetObjResult(interp, resultObj);
return TCL_OK;
@@ -2354,7 +2356,7 @@ BinaryDecodeHex(
static const char *const optStrings[] = { "-strict", NULL };
if (objc < 2 || objc > 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "data");
+ Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
return TCL_ERROR;
}
for (i = 1; i < objc-1; ++i) {
@@ -2378,29 +2380,32 @@ BinaryDecodeHex(
while (data < dataend) {
value = 0;
for (i=0 ; i<2 ; i++) {
- if (data < dataend) {
- c = *data++;
-
- if (!isxdigit((int) c)) {
- if (strict || !isspace(c)) {
- goto badChar;
- }
- i--;
- continue;
- }
+ if (data >= dataend) {
value <<= 4;
- c -= '0';
- if (c > 9) {
- c += ('0' - 'A') + 10;
- }
- if (c > 16) {
- c += ('A' - 'a');
+ break;
+ }
+
+ c = *data++;
+ if (!isxdigit((int) c)) {
+ if (strict || !isspace(c)) {
+ goto badChar;
}
- value |= (c & 0xf);
- } else {
- value <<= 4;
- cut++;
+ i--;
+ continue;
}
+
+ value <<= 4;
+ c -= '0';
+ if (c > 9) {
+ c += ('0' - 'A') + 10;
+ }
+ if (c > 16) {
+ c += ('A' - 'a');
+ }
+ value |= (c & 0xf);
+ }
+ if (i < 2) {
+ cut++;
}
*cursor++ = UCHAR(value);
value = 0;
@@ -2428,7 +2433,7 @@ BinaryDecodeHex(
* This implements a generic 6 bit binary encoding. Input is broken into
* 6 bit chunks and a lookup table passed in via clientData is used to
* turn these values into output characters. This is used to implement
- * base64 and uuencode binary encodings.
+ * base64 binary encodings.
*
* Results:
* Interp result set to an encoded byte array object
@@ -2464,7 +2469,6 @@ BinaryEncode64(
{
Tcl_Obj *resultObj;
unsigned char *data, *cursor, *limit;
- const char *digits = clientData;
int maxlen = 0;
const char *wrapchar = "\n";
int wrapcharlen = 1;
@@ -2487,6 +2491,13 @@ BinaryEncode64(
if (Tcl_GetIntFromObj(interp, objv[i+1], &maxlen) != TCL_OK) {
return TCL_ERROR;
}
+ if (maxlen < 0) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "line length out of range", -1));
+ Tcl_SetErrorCode(interp, "TCL", "BINARY", "ENCODE",
+ "LINE_LENGTH", NULL);
+ return TCL_ERROR;
+ }
break;
case OPT_WRAPCHAR:
wrapchar = Tcl_GetStringFromObj(objv[i+1], &wrapcharlen);
@@ -2517,17 +2528,17 @@ BinaryEncode64(
for (i = 0; i < 3 && offset+i < count; ++i) {
d[i] = data[offset + i];
}
- OUTPUT(digits[d[0] >> 2]);
- OUTPUT(digits[((d[0] & 0x03) << 4) | (d[1] >> 4)]);
+ OUTPUT(B64Digits[d[0] >> 2]);
+ OUTPUT(B64Digits[((d[0] & 0x03) << 4) | (d[1] >> 4)]);
if (offset+1 < count) {
- OUTPUT(digits[((d[1] & 0x0f) << 2) | (d[2] >> 6)]);
+ OUTPUT(B64Digits[((d[1] & 0x0f) << 2) | (d[2] >> 6)]);
} else {
- OUTPUT(digits[64]);
+ OUTPUT(B64Digits[64]);
}
if (offset+2 < count) {
- OUTPUT(digits[d[2] & 0x3f]);
+ OUTPUT(B64Digits[d[2] & 0x3f]);
} else {
- OUTPUT(digits[64]);
+ OUTPUT(B64Digits[64]);
}
}
}
@@ -2539,6 +2550,125 @@ BinaryEncode64(
/*
*----------------------------------------------------------------------
*
+ * BinaryEncodeUu --
+ *
+ * This implements the uuencode binary encoding. Input is broken into 6
+ * bit chunks and a lookup table is used to turn these values into output
+ * characters. This differs from the generic code above in that line
+ * lengths are also encoded.
+ *
+ * Results:
+ * Interp result set to an encoded byte array object
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+BinaryEncodeUu(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ Tcl_Obj *resultObj;
+ unsigned char *data, *start, *cursor;
+ int offset, count, rawLength, n, i, j, bits, index;
+ int lineLength = 61;
+ const unsigned char SingleNewline[] = { (unsigned char) '\n' };
+ const unsigned char *wrapchar = SingleNewline;
+ int wrapcharlen = sizeof(SingleNewline);
+ enum { OPT_MAXLEN, OPT_WRAPCHAR };
+ static const char *const optStrings[] = { "-maxlen", "-wrapchar", NULL };
+
+ if (objc < 2 || objc%2 != 0) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "?-maxlen len? ?-wrapchar char? data");
+ return TCL_ERROR;
+ }
+ for (i = 1; i < objc-1; i += 2) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], optStrings, "option",
+ TCL_EXACT, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch (index) {
+ case OPT_MAXLEN:
+ if (Tcl_GetIntFromObj(interp, objv[i+1], &lineLength) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (lineLength < 3 || lineLength > 85) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "line length out of range", -1));
+ Tcl_SetErrorCode(interp, "TCL", "BINARY", "ENCODE",
+ "LINE_LENGTH", NULL);
+ return TCL_ERROR;
+ }
+ break;
+ case OPT_WRAPCHAR:
+ wrapchar = Tcl_GetByteArrayFromObj(objv[i+1], &wrapcharlen);
+ break;
+ }
+ }
+
+ /*
+ * Allocate the buffer. This is a little bit too long, but is "good
+ * enough".
+ */
+
+ resultObj = Tcl_NewObj();
+ offset = 0;
+ data = Tcl_GetByteArrayFromObj(objv[objc-1], &count);
+ rawLength = (lineLength - 1) * 3 / 4;
+ start = cursor = Tcl_SetByteArrayLength(resultObj,
+ (lineLength + wrapcharlen) *
+ ((count + (rawLength - 1)) / rawLength));
+ n = bits = 0;
+
+ /*
+ * Encode the data. Each output line first has the length of raw data
+ * encoded by the output line described in it by one encoded byte, then
+ * the encoded data follows (encoding each 6 bits as one character).
+ * Encoded lines are always terminated by a newline.
+ */
+
+ while (offset < count) {
+ int lineLen = count - offset;
+
+ if (lineLen > rawLength) {
+ lineLen = rawLength;
+ }
+ *cursor++ = UueDigits[lineLen];
+ for (i=0 ; i<lineLen ; i++) {
+ n <<= 8;
+ n |= data[offset++];
+ for (bits += 8; bits > 6 ; bits -= 6) {
+ *cursor++ = UueDigits[(n >> (bits-6)) & 0x3f];
+ }
+ }
+ if (bits > 0) {
+ n <<= 8;
+ *cursor++ = UueDigits[(n >> (bits + 2)) & 0x3f];
+ bits = 0;
+ }
+ for (j=0 ; j<wrapcharlen ; ++j) {
+ *cursor++ = wrapchar[j];
+ }
+ }
+
+ /*
+ * Fix the length of the output bytearray.
+ */
+
+ Tcl_SetByteArrayLength(resultObj, cursor-start);
+ Tcl_SetObjResult(interp, resultObj);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* BinaryDecodeUu --
*
* Decode a uuencoded string.
@@ -2562,13 +2692,13 @@ BinaryDecodeUu(
Tcl_Obj *resultObj = NULL;
unsigned char *data, *datastart, *dataend;
unsigned char *begin, *cursor;
- int i, index, size, count = 0, cut = 0, strict = 0;
- char c;
+ int i, index, size, count = 0, strict = 0, lineLen;
+ unsigned char c;
enum {OPT_STRICT };
static const char *const optStrings[] = { "-strict", NULL };
if (objc < 2 || objc > 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "data");
+ Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
return TCL_ERROR;
}
for (i = 1; i < objc-1; ++i) {
@@ -2589,44 +2719,112 @@ BinaryDecodeUu(
dataend = data + count;
size = ((count + 3) & ~3) * 3 / 4;
begin = cursor = Tcl_SetByteArrayLength(resultObj, size);
+ lineLen = -1;
+
+ /*
+ * The decoding loop. First, we get the length of line (strictly, the
+ * number of data bytes we expect to generate from the line) we're
+ * processing this time round if it is not already known (i.e., when the
+ * lineLen variable is set to the magic value, -1).
+ */
+
while (data < dataend) {
char d[4] = {0, 0, 0, 0};
+ if (lineLen < 0) {
+ c = *data++;
+ if (c < 32 || c > 96) {
+ if (strict || !isspace(c)) {
+ goto badUu;
+ }
+ i--;
+ continue;
+ }
+ lineLen = (c - 32) & 0x3f;
+ }
+
+ /*
+ * Now we read a four-character grouping.
+ */
+
for (i=0 ; i<4 ; i++) {
if (data < dataend) {
d[i] = c = *data++;
- if (c < 33 || c > 96) {
- if (strict || !isspace(UCHAR(c))) {
- goto badUu;
+ if (c < 32 || c > 96) {
+ if (strict) {
+ if (!isspace(c)) {
+ goto badUu;
+ } else if (c == '\n') {
+ goto shortUu;
+ }
}
i--;
continue;
}
- } else {
- cut++;
}
}
- if (cut > 3) {
- cut = 3;
+
+ /*
+ * Translate that grouping into (up to) three binary bytes output.
+ */
+
+ if (lineLen > 0) {
+ *cursor++ = (((d[0] - 0x20) & 0x3f) << 2)
+ | (((d[1] - 0x20) & 0x3f) >> 4);
+ if (--lineLen > 0) {
+ *cursor++ = (((d[1] - 0x20) & 0x3f) << 4)
+ | (((d[2] - 0x20) & 0x3f) >> 2);
+ if (--lineLen > 0) {
+ *cursor++ = (((d[2] - 0x20) & 0x3f) << 6)
+ | (((d[3] - 0x20) & 0x3f));
+ lineLen--;
+ }
+ }
+ }
+
+ /*
+ * If we've reached the end of the line, skip until we process a
+ * newline.
+ */
+
+ if (lineLen == 0 && data < dataend) {
+ lineLen = -1;
+ do {
+ c = *data++;
+ if (c == '\n') {
+ break;
+ } else if (c >= 32 && c <= 96) {
+ data--;
+ break;
+ } else if (strict || !isspace(c)) {
+ goto badUu;
+ }
+ } while (data < dataend);
}
- *cursor++ = (((d[0] - 0x20) & 0x3f) << 2)
- | (((d[1] - 0x20) & 0x3f) >> 4);
- *cursor++ = (((d[1] - 0x20) & 0x3f) << 4)
- | (((d[2] - 0x20) & 0x3f) >> 2);
- *cursor++ = (((d[2] - 0x20) & 0x3f) << 6)
- | (((d[3] - 0x20) & 0x3f));
}
- if (cut > size) {
- cut = size;
+
+ /*
+ * Sanity check, clean up and finish.
+ */
+
+ if (lineLen > 0 && strict) {
+ goto shortUu;
}
- Tcl_SetByteArrayLength(resultObj, cursor - begin - cut);
+ Tcl_SetByteArrayLength(resultObj, cursor - begin);
Tcl_SetObjResult(interp, resultObj);
return TCL_OK;
+ shortUu:
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("short uuencode data"));
+ Tcl_SetErrorCode(interp, "TCL", "BINARY", "DECODE", "SHORT", NULL);
+ TclDecrRefCount(resultObj);
+ return TCL_ERROR;
+
badUu:
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"invalid uuencode character \"%c\" at position %d",
c, (int) (data - datastart - 1)));
+ Tcl_SetErrorCode(interp, "TCL", "BINARY", "DECODE", "INVALID", NULL);
TclDecrRefCount(resultObj);
return TCL_ERROR;
}
@@ -2655,16 +2853,16 @@ BinaryDecode64(
Tcl_Obj *const objv[])
{
Tcl_Obj *resultObj = NULL;
- unsigned char *data, *datastart, *dataend, c;
+ unsigned char *data, *datastart, *dataend, c = '\0';
unsigned char *begin = NULL;
unsigned char *cursor = NULL;
int strict = 0;
int i, index, size, cut = 0, count = 0;
- enum {OPT_STRICT };
+ enum { OPT_STRICT };
static const char *const optStrings[] = { "-strict", NULL };
if (objc < 2 || objc > 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "data");
+ Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
return TCL_ERROR;
}
for (i = 1; i < objc-1; ++i) {
@@ -2688,43 +2886,85 @@ BinaryDecode64(
while (data < dataend) {
unsigned long value = 0;
- for (i=0 ; i<4 ; i++) {
+ /*
+ * Decode the current block. Each base64 block consists of four input
+ * characters A-Z, a-z, 0-9, +, or /. Each character supplies six bits
+ * of output data, so each block's output is 24 bits (three bytes) in
+ * length. The final block can be shorter by one or two bytes, denoted
+ * by the input ending with one or two ='s, respectively.
+ */
+
+ for (i = 0; i < 4; i++) {
+ /*
+ * Get the next input character. At end of input, pad with at most
+ * two ='s. If more than two ='s would be needed, instead discard
+ * the block read thus far.
+ */
+
if (data < dataend) {
c = *data++;
+ } else if (i > 1) {
+ c = '=';
+ } else {
+ cut += 3;
+ break;
+ }
- if (c >= 'A' && c <= 'Z') {
- value = (value << 6) | ((c - 'A') & 0x3f);
- } else if (c >= 'a' && c <= 'z') {
- value = (value << 6) | ((c - 'a' + 26) & 0x3f);
- } else if (c >= '0' && c <= '9') {
- value = (value << 6) | ((c - '0' + 52) & 0x3f);
- } else if (c == '+') {
- value = (value << 6) | 0x3e;
- } else if (c == '/') {
- value = (value << 6) | 0x3f;
- } else if (c == '=') {
- value <<= 6;
- if (cut < 2) {
- cut++;
- }
+ /*
+ * Load the character into the block value. Handle ='s specially
+ * because they're only valid as the last character or two of the
+ * final block of input. Unless strict mode is enabled, skip any
+ * input whitespace characters.
+ */
+
+ if (cut) {
+ if (c == '=' && i > 1) {
+ value <<= 6;
+ cut++;
+ } else if (!strict && isspace(c)) {
+ i--;
} else {
- if (strict || !isspace(c)) {
- goto bad64;
- }
- i--;
- continue;
+ goto bad64;
}
- } else {
+ } else if (c >= 'A' && c <= 'Z') {
+ value = (value << 6) | ((c - 'A') & 0x3f);
+ } else if (c >= 'a' && c <= 'z') {
+ value = (value << 6) | ((c - 'a' + 26) & 0x3f);
+ } else if (c >= '0' && c <= '9') {
+ value = (value << 6) | ((c - '0' + 52) & 0x3f);
+ } else if (c == '+') {
+ value = (value << 6) | 0x3e;
+ } else if (c == '/') {
+ value = (value << 6) | 0x3f;
+ } else if (c == '=') {
value <<= 6;
cut++;
+ } else if (strict || !isspace(c)) {
+ goto bad64;
+ } else {
+ i--;
}
}
*cursor++ = UCHAR((value >> 16) & 0xff);
*cursor++ = UCHAR((value >> 8) & 0xff);
*cursor++ = UCHAR(value & 0xff);
- }
- if (cut > size) {
- cut = size;
+
+ /*
+ * Since = is only valid within the final block, if it was encountered
+ * but there are still more input characters, confirm that strict mode
+ * is off and all subsequent characters are whitespace.
+ */
+
+ if (cut && data < dataend) {
+ if (strict) {
+ goto bad64;
+ }
+ for (; data < dataend; data++) {
+ if (!isspace(*data)) {
+ goto bad64;
+ }
+ }
+ }
}
Tcl_SetByteArrayLength(resultObj, cursor - begin - cut);
Tcl_SetObjResult(interp, resultObj);
diff --git a/generic/tclCkalloc.c b/generic/tclCkalloc.c
index 5b5a0d6..70e64f0 100644
--- a/generic/tclCkalloc.c
+++ b/generic/tclCkalloc.c
@@ -156,6 +156,10 @@ TclInitDbCkalloc(void)
if (!ckallocInit) {
ckallocInit = 1;
ckallocMutexPtr = Tcl_GetAllocMutex();
+#ifndef TCL_THREADS
+ /* Silence compiler warning */
+ (void)ckallocMutexPtr;
+#endif
}
}
@@ -170,11 +174,15 @@ TclInitDbCkalloc(void)
*/
int
-TclDumpMemoryInfo(ClientData clientData, int flags)
+TclDumpMemoryInfo(
+ ClientData clientData,
+ int flags)
{
char buf[1024];
- if (clientData == NULL) { return 0; }
+ if (clientData == NULL) {
+ return 0;
+ }
sprintf(buf,
"total mallocs %10d\n"
"total frees %10d\n"
@@ -815,15 +823,16 @@ MemoryCmd(
size_t len;
if (argc < 2) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " option [args..]\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "wrong # args: should be \"%s option [args..]\"", argv[0]));
return TCL_ERROR;
}
- if ((strcmp(argv[1],"active") == 0) || (strcmp(argv[1],"display") == 0)) {
+ if (strcmp(argv[1], "active") == 0 || strcmp(argv[1], "display") == 0) {
if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " ", argv[1], " file\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "wrong # args: should be \"%s %s file\"",
+ argv[0], argv[1]));
return TCL_ERROR;
}
fileName = Tcl_TranslateFileName(interp, argv[2], &buffer);
@@ -833,7 +842,8 @@ MemoryCmd(
result = Tcl_DumpActiveMemory(fileName);
Tcl_DStringFree(&buffer);
if (result != TCL_OK) {
- Tcl_AppendResult(interp, "error accessing ", argv[2], NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("error accessing %s: %s",
+ argv[2], Tcl_PosixError(interp)));
return TCL_ERROR;
}
return TCL_OK;
@@ -857,17 +867,17 @@ MemoryCmd(
"maximum bytes allocated", (unsigned long)maximum_bytes_malloced));
return TCL_OK;
}
- if (strcmp(argv[1],"init") == 0) {
+ if (strcmp(argv[1], "init") == 0) {
if (argc != 3) {
goto bad_suboption;
}
init_malloced_bodies = (strcmp(argv[2],"on") == 0);
return TCL_OK;
}
- if (strcmp(argv[1],"objs") == 0) {
+ if (strcmp(argv[1], "objs") == 0) {
if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " objs file\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "wrong # args: should be \"%s objs file\"", argv[0]));
return TCL_ERROR;
}
fileName = Tcl_TranslateFileName(interp, argv[2], &buffer);
@@ -876,7 +886,9 @@ MemoryCmd(
}
fileP = fopen(fileName, "w");
if (fileP == NULL) {
- Tcl_AppendResult(interp, "cannot open output file", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "cannot open output file: %s",
+ Tcl_PosixError(interp)));
return TCL_ERROR;
}
TclDbDumpActiveObjects(fileP);
@@ -886,8 +898,8 @@ MemoryCmd(
}
if (strcmp(argv[1],"onexit") == 0) {
if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " onexit file\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "wrong # args: should be \"%s onexit file\"", argv[0]));
return TCL_ERROR;
}
fileName = Tcl_TranslateFileName(interp, argv[2], &buffer);
@@ -901,8 +913,8 @@ MemoryCmd(
}
if (strcmp(argv[1],"tag") == 0) {
if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " tag string\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "wrong # args: should be \"%s tag string\"", argv[0]));
return TCL_ERROR;
}
if ((curTagPtr != NULL) && (curTagPtr->refCount == 0)) {
@@ -939,19 +951,20 @@ MemoryCmd(
return TCL_OK;
}
- Tcl_AppendResult(interp, "bad option \"", argv[1],
- "\": should be active, break_on_malloc, info, init, objs, onexit, "
- "tag, trace, trace_on_at_malloc, or validate", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad option \"%s\": should be active, break_on_malloc, info, "
+ "init, objs, onexit, tag, trace, trace_on_at_malloc, or validate",
+ argv[1]));
return TCL_ERROR;
argError:
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " ", argv[1], " count\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "wrong # args: should be \"%s %s count\"", argv[0], argv[1]));
return TCL_ERROR;
bad_suboption:
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " ", argv[1], " on|off\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "wrong # args: should be \"%s %s on|off\"", argv[0], argv[1]));
return TCL_ERROR;
}
@@ -981,8 +994,8 @@ CheckmemCmd(
const char *argv[]) /* String values of arguments. */
{
if (argc != 2) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " fileName\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "wrong # args: should be \"%s fileName\"", argv[0]));
return TCL_ERROR;
}
tclMemDumpFileName = dumpFile;
@@ -1250,7 +1263,9 @@ Tcl_ValidateAllMemory(
}
int
-TclDumpMemoryInfo(ClientData clientData, int flags)
+TclDumpMemoryInfo(
+ ClientData clientData,
+ int flags)
{
return 1;
}
diff --git a/generic/tclClock.c b/generic/tclClock.c
index 7fa4017..15f29e5 100644
--- a/generic/tclClock.c
+++ b/generic/tclClock.c
@@ -19,7 +19,7 @@
* Windows has mktime. The configurators do not check.
*/
-#ifdef __WIN32__
+#ifdef _WIN32
#define HAVE_MKTIME 1
#endif
@@ -548,18 +548,21 @@ ClockGetjuliandayfromerayearmonthdayObjCmd(
}
dict = objv[1];
if (Tcl_DictObjGet(interp, dict, literals[LIT_ERA], &fieldPtr) != TCL_OK
+ || fieldPtr == NULL
|| Tcl_GetIndexFromObj(interp, fieldPtr, eras, "era", TCL_EXACT,
&era) != TCL_OK
- || Tcl_DictObjGet(interp, dict, literals[LIT_YEAR],
- &fieldPtr) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_YEAR], &fieldPtr) != TCL_OK
+ || fieldPtr == NULL
|| TclGetIntFromObj(interp, fieldPtr, &fields.year) != TCL_OK
- || Tcl_DictObjGet(interp, dict, literals[LIT_MONTH],
- &fieldPtr) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_MONTH], &fieldPtr) != TCL_OK
+ || fieldPtr == NULL
|| TclGetIntFromObj(interp, fieldPtr, &fields.month) != TCL_OK
- || Tcl_DictObjGet(interp, dict, literals[LIT_DAYOFMONTH],
- &fieldPtr) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_DAYOFMONTH], &fieldPtr) != TCL_OK
+ || fieldPtr == NULL
|| TclGetIntFromObj(interp, fieldPtr, &fields.dayOfMonth)!=TCL_OK
|| TclGetIntFromObj(interp, objv[2], &changeover) != TCL_OK) {
+ if (fieldPtr == NULL)
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("expected key(s) not found in dictionary", -1));
return TCL_ERROR;
}
fields.era = era;
@@ -638,18 +641,21 @@ ClockGetjuliandayfromerayearweekdayObjCmd(
}
dict = objv[1];
if (Tcl_DictObjGet(interp, dict, literals[LIT_ERA], &fieldPtr) != TCL_OK
+ || fieldPtr == NULL
|| Tcl_GetIndexFromObj(interp, fieldPtr, eras, "era", TCL_EXACT,
&era) != TCL_OK
- || Tcl_DictObjGet(interp, dict, literals[LIT_ISO8601YEAR],
- &fieldPtr) != TCL_OK
- || TclGetIntFromObj(interp, fieldPtr, &fields.iso8601Year)!=TCL_OK
- || Tcl_DictObjGet(interp, dict, literals[LIT_ISO8601WEEK],
- &fieldPtr) != TCL_OK
- || TclGetIntFromObj(interp, fieldPtr, &fields.iso8601Week)!=TCL_OK
- || Tcl_DictObjGet(interp, dict, literals[LIT_DAYOFWEEK],
- &fieldPtr) != TCL_OK
- || TclGetIntFromObj(interp, fieldPtr, &fields.dayOfWeek) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_ISO8601YEAR], &fieldPtr) != TCL_OK
+ || fieldPtr == NULL
+ || TclGetIntFromObj(interp, fieldPtr, &(fields.iso8601Year)) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_ISO8601WEEK], &fieldPtr) != TCL_OK
+ || fieldPtr == NULL
+ || TclGetIntFromObj(interp, fieldPtr, &(fields.iso8601Week)) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_DAYOFWEEK], &fieldPtr) != TCL_OK
+ || fieldPtr == NULL
+ || TclGetIntFromObj(interp, fieldPtr, &(fields.dayOfWeek)) != TCL_OK
|| TclGetIntFromObj(interp, objv[2], &changeover) != TCL_OK) {
+ if (fieldPtr == NULL)
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("expected key(s) not found in dictionary", -1));
return TCL_ERROR;
}
fields.era = era;
@@ -878,8 +884,8 @@ ConvertLocalToUTCUsingC(
if (localErrno != 0
|| (fields->seconds == -1 && timeVal.tm_yday == -1)) {
- Tcl_SetResult(interp, "time value too large/small to represent",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "time value too large/small to represent", -1));
return TCL_ERROR;
}
return TCL_OK;
@@ -1018,17 +1024,17 @@ ConvertUTCToLocalUsingC(
tock = (time_t) fields->seconds;
if ((Tcl_WideInt) tock != fields->seconds) {
- Tcl_AppendResult(interp,
- "number too large to represent as a Posix time", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "number too large to represent as a Posix time", -1));
Tcl_SetErrorCode(interp, "CLOCK", "argTooLarge", NULL);
return TCL_ERROR;
}
TzsetIfNecessary();
timeVal = ThreadSafeLocalTime(&tock);
if (timeVal == NULL) {
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"localtime failed (clock value may be too "
- "large/small to represent)", NULL);
+ "large/small to represent)", -1));
Tcl_SetErrorCode(interp, "CLOCK", "localtimeFailed", NULL);
return TCL_ERROR;
}
diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c
index 765c9dc..d90a747 100644
--- a/generic/tclCmdAH.c
+++ b/generic/tclCmdAH.c
@@ -32,6 +32,9 @@ struct ForeachState {
int *argcList; /* Array of value list sizes. */
Tcl_Obj ***argvList; /* Array of value lists. */
Tcl_Obj **aCopyList; /* Copies of value list arguments. */
+ Tcl_Obj *resultList; /* List of result values from the loop body,
+ * or NULL if we're not collecting them
+ * ([lmap] vs [foreach]). */
};
/*
@@ -52,6 +55,8 @@ static int GetStatBuf(Tcl_Interp *interp, Tcl_Obj *pathPtr,
static const char * GetTypeFromMode(int mode);
static int StoreStatData(Tcl_Interp *interp, Tcl_Obj *varName,
Tcl_StatBuf *statPtr);
+static inline int EachloopCmd(Tcl_Interp *interp, int collect,
+ int objc, Tcl_Obj *const objv[]);
static Tcl_NRPostProc CatchObjCmdCallback;
static Tcl_NRPostProc ExprCallback;
static Tcl_NRPostProc ForSetupCallback;
@@ -61,6 +66,7 @@ static Tcl_NRPostProc ForPostNextCallback;
static Tcl_NRPostProc ForeachLoopStep;
static Tcl_NRPostProc EvalCmdErrMsg;
+static Tcl_ObjCmdProc BadFileSubcommand;
static Tcl_ObjCmdProc FileAttrAccessTimeCmd;
static Tcl_ObjCmdProc FileAttrIsDirectoryCmd;
static Tcl_ObjCmdProc FileAttrIsExecutableCmd;
@@ -188,12 +194,12 @@ Tcl_CaseObjCmd(
for (i = 0; i < caseObjc; i += 2) {
int patObjc, j;
const char **patObjv;
- const char *pat;
- unsigned char *p;
+ const char *pat, *p;
if (i == caseObjc-1) {
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "extra case pattern with no body", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "extra case pattern with no body", -1));
return TCL_ERROR;
}
@@ -203,8 +209,8 @@ Tcl_CaseObjCmd(
*/
pat = TclGetString(caseObjv[i]);
- for (p = (unsigned char *) pat; *p != '\0'; p++) {
- if (isspace(*p) || (*p == '\\')) { /* INTL: ISO space, UCHAR */
+ for (p = pat; *p != '\0'; p++) {
+ if (TclIsSpaceProc(*p) || (*p == '\\')) {
break;
}
}
@@ -354,7 +360,8 @@ CatchObjCmdCallback(
if (NULL == Tcl_ObjSetVar2(interp, optionVarNamePtr, NULL,
options, TCL_LEAVE_ERR_MSG)) {
- Tcl_DecrRefCount(options);
+ /* Do not decrRefCount 'options', it was already done by
+ * Tcl_ObjSetVar2 */
return TCL_ERROR;
}
}
@@ -408,8 +415,9 @@ Tcl_CdObjCmd(
} else {
result = Tcl_FSChdir(dir);
if (result != TCL_OK) {
- Tcl_AppendResult(interp, "couldn't change working directory to \"",
- TclGetString(dir), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't change working directory to \"%s\": %s",
+ TclGetString(dir), Tcl_PosixError(interp)));
result = TCL_ERROR;
}
}
@@ -563,9 +571,7 @@ Tcl_EncodingObjCmd(
* truncate the string at the first null byte.
*/
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)));
- Tcl_DStringFree(&ds);
+ Tcl_SetObjResult(interp, TclDStringToObj(&ds));
} else {
/*
* Store the result as binary data.
@@ -583,7 +589,7 @@ Tcl_EncodingObjCmd(
break;
}
case ENC_DIRS:
- return EncodingDirsObjCmd(dummy, interp, objc-1, objv+1);
+ return EncodingDirsObjCmd(dummy, interp, objc, objv);
case ENC_NAMES:
if (objc > 2) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
@@ -630,22 +636,27 @@ EncodingDirsObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "?dirList?");
+ Tcl_Obj *dirListObj;
+
+ if (objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?dirList?");
return TCL_ERROR;
}
- if (objc == 1) {
+ if (objc == 2) {
Tcl_SetObjResult(interp, Tcl_GetEncodingSearchPath());
return TCL_OK;
}
- if (Tcl_SetEncodingSearchPath(objv[1]) == TCL_ERROR) {
- Tcl_AppendResult(interp, "expected directory list but got \"",
- TclGetString(objv[1]), "\"", NULL);
+
+ dirListObj = objv[2];
+ if (Tcl_SetEncodingSearchPath(dirListObj) == TCL_ERROR) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "expected directory list but got \"%s\"",
+ TclGetString(dirListObj)));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "ENCODING", "BADPATH",
NULL);
return TCL_ERROR;
}
- Tcl_SetObjResult(interp, objv[1]);
+ Tcl_SetObjResult(interp, dirListObj);
return TCL_OK;
}
@@ -737,6 +748,16 @@ Tcl_EvalObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
+ return Tcl_NRCallObjProc(interp, TclNREvalObjCmd, dummy, objc, objv);
+}
+
+int
+TclNREvalObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
register Tcl_Obj *objPtr;
Interp *iPtr = (Interp *) interp;
CmdFrame *invoker = NULL;
@@ -928,40 +949,40 @@ TclInitFileCmd(
*/
static const EnsembleImplMap initMap[] = {
- {"atime", FileAttrAccessTimeCmd, NULL, NULL, NULL, 0},
- {"attributes", TclFileAttrsCmd, NULL, NULL, NULL, 0},
- {"channels", TclChannelNamesCmd, NULL, NULL, NULL, 0},
- {"copy", TclFileCopyCmd, NULL, NULL, NULL, 0},
- {"delete", TclFileDeleteCmd, NULL, NULL, NULL, 0},
- {"dirname", PathDirNameCmd, NULL, NULL, NULL, 0},
- {"executable", FileAttrIsExecutableCmd, NULL, NULL, NULL, 0},
- {"exists", FileAttrIsExistingCmd, NULL, NULL, NULL, 0},
- {"extension", PathExtensionCmd, NULL, NULL, NULL, 0},
- {"isdirectory", FileAttrIsDirectoryCmd, NULL, NULL, NULL, 0},
- {"isfile", FileAttrIsFileCmd, NULL, NULL, NULL, 0},
- {"join", PathJoinCmd, NULL, NULL, NULL, 0},
- {"link", TclFileLinkCmd, NULL, NULL, NULL, 0},
- {"lstat", FileAttrLinkStatCmd, NULL, NULL, NULL, 0},
- {"mtime", FileAttrModifyTimeCmd, NULL, NULL, NULL, 0},
- {"mkdir", TclFileMakeDirsCmd, NULL, NULL, NULL, 0},
- {"nativename", PathNativeNameCmd, NULL, NULL, NULL, 0},
- {"normalize", PathNormalizeCmd, NULL, NULL, NULL, 0},
- {"owned", FileAttrIsOwnedCmd, NULL, NULL, NULL, 0},
- {"pathtype", PathTypeCmd, NULL, NULL, NULL, 0},
- {"readable", FileAttrIsReadableCmd, NULL, NULL, NULL, 0},
- {"readlink", TclFileReadLinkCmd, NULL, NULL, NULL, 0},
- {"rename", TclFileRenameCmd, NULL, NULL, NULL, 0},
- {"rootname", PathRootNameCmd, NULL, NULL, NULL, 0},
- {"separator", FilesystemSeparatorCmd, NULL, NULL, NULL, 0},
- {"size", FileAttrSizeCmd, NULL, NULL, NULL, 0},
- {"split", PathSplitCmd, NULL, NULL, NULL, 0},
- {"stat", FileAttrStatCmd, NULL, NULL, NULL, 0},
- {"system", PathFilesystemCmd, NULL, NULL, NULL, 0},
- {"tail", PathTailCmd, NULL, NULL, NULL, 0},
- {"tempfile", TclFileTemporaryCmd, NULL, NULL, NULL, 0},
- {"type", FileAttrTypeCmd, NULL, NULL, NULL, 0},
- {"volumes", FilesystemVolumesCmd, NULL, NULL, NULL, 0},
- {"writable", FileAttrIsWritableCmd, NULL, NULL, NULL, 0},
+ {"atime", FileAttrAccessTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+ {"attributes", TclFileAttrsCmd, NULL, NULL, NULL, 0},
+ {"channels", TclChannelNamesCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+ {"copy", TclFileCopyCmd, NULL, NULL, NULL, 0},
+ {"delete", TclFileDeleteCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
+ {"dirname", PathDirNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"executable", FileAttrIsExecutableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"exists", FileAttrIsExistingCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"extension", PathExtensionCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"isdirectory", FileAttrIsDirectoryCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"isfile", FileAttrIsFileCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"join", PathJoinCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
+ {"link", TclFileLinkCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
+ {"lstat", FileAttrLinkStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"mtime", FileAttrModifyTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+ {"mkdir", TclFileMakeDirsCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
+ {"nativename", PathNativeNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"normalize", PathNormalizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"owned", FileAttrIsOwnedCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"pathtype", PathTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"readable", FileAttrIsReadableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"readlink", TclFileReadLinkCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"rename", TclFileRenameCmd, NULL, NULL, NULL, 0},
+ {"rootname", PathRootNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"separator", FilesystemSeparatorCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+ {"size", FileAttrSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"split", PathSplitCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"stat", FileAttrStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"system", PathFilesystemCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+ {"tail", PathTailCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"tempfile", TclFileTemporaryCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 0},
+ {"type", FileAttrTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"volumes", FilesystemVolumesCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
+ {"writable", FileAttrIsWritableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
};
return TclMakeEnsemble(interp, "file", initMap);
@@ -1032,9 +1053,9 @@ TclMakeFileCommandSafe(
Tcl_DString oldBuf, newBuf;
Tcl_DStringInit(&oldBuf);
- Tcl_DStringAppend(&oldBuf, "::tcl::file::", -1);
+ TclDStringAppendLiteral(&oldBuf, "::tcl::file::");
Tcl_DStringInit(&newBuf);
- Tcl_DStringAppend(&newBuf, "tcl:file:", -1);
+ TclDStringAppendLiteral(&newBuf, "tcl:file:");
for (i=0 ; unsafeInfo[i].cmdName != NULL ; i++) {
if (unsafeInfo[i].unsafe) {
const char *oldName, *newName;
@@ -1049,16 +1070,62 @@ TclMakeFileCommandSafe(
unsafeInfo[i].cmdName,
Tcl_GetString(Tcl_GetObjResult(interp)));
}
+ Tcl_CreateObjCommand(interp, oldName, BadFileSubcommand,
+ (ClientData) unsafeInfo[i].cmdName, NULL);
}
}
Tcl_DStringFree(&oldBuf);
Tcl_DStringFree(&newBuf);
+
+ /*
+ * Ugh. The [file] command is now actually safe, but it is assumed by
+ * scripts that it is not, which messes up security policies. [Bug
+ * 3211758]
+ */
+
+ if (Tcl_HideCommand(interp, "file", "file") != TCL_OK) {
+ Tcl_Panic("problem making 'file' safe: %s",
+ Tcl_GetString(Tcl_GetObjResult(interp)));
+ }
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
+ * BadFileSubcommand --
+ *
+ * Command used to act as a backstop implementation when subcommands of
+ * "file" are unsafe (the real implementations of the subcommands are
+ * hidden). The clientData is always the full official subcommand name.
+ *
+ * Results:
+ * A standard Tcl result (always a TCL_ERROR).
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+BadFileSubcommand(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ const char *subcommandName = (const char *) clientData;
+
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "not allowed to invoke subcommand %s of file", subcommandName));
+ Tcl_SetErrorCode(interp, "TCL", "SAFE", "SUBCOMMAND", NULL);
+ return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* FileAttrAccessTimeCmd --
*
* This function is invoked to process the "file atime" Tcl command. See
@@ -1106,9 +1173,9 @@ FileAttrAccessTimeCmd(
tval.modtime = buf.st_mtime;
if (Tcl_FSUtime(objv[1], &tval) != 0) {
- Tcl_AppendResult(interp, "could not set access time for file \"",
- TclGetString(objv[1]), "\": ", Tcl_PosixError(interp),
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not set access time for file \"%s\": %s",
+ TclGetString(objv[1]), Tcl_PosixError(interp)));
return TCL_ERROR;
}
@@ -1178,9 +1245,9 @@ FileAttrModifyTimeCmd(
tval.modtime = newTime;
if (Tcl_FSUtime(objv[1], &tval) != 0) {
- Tcl_AppendResult(interp, "could not set modification time for "
- "file \"", TclGetString(objv[1]), "\": ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not set modification time for file \"%s\": %s",
+ TclGetString(objv[1]), Tcl_PosixError(interp)));
return TCL_ERROR;
}
@@ -1523,7 +1590,7 @@ FileAttrIsOwnedCmd(
* test for equivalence to the current user.
*/
-#ifdef __WIN32__
+#if defined(_WIN32) || defined(__CYGWIN__)
value = 1;
#else
value = (geteuid() == buf.st_uid);
@@ -1783,7 +1850,7 @@ PathFilesystemCmd(
}
fsInfo = Tcl_FSFileSystemInfo(objv[1]);
if (fsInfo == NULL) {
- Tcl_SetResult(interp, "unrecognised path", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("unrecognised path", -1));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "FILESYSTEM",
Tcl_GetString(objv[1]), NULL);
return TCL_ERROR;
@@ -1820,7 +1887,7 @@ PathJoinCmd(
Tcl_WrongNumArgs(interp, 1, objv, "name ?name ...?");
return TCL_ERROR;
}
- Tcl_SetObjResult(interp, Tcl_FSJoinToPath(NULL, objc - 1, objv + 1));
+ Tcl_SetObjResult(interp, TclJoinPath(objc - 1, objv + 1));
return TCL_OK;
}
@@ -1848,20 +1915,16 @@ PathNativeNameCmd(
int objc,
Tcl_Obj *const objv[])
{
- const char *fileName;
Tcl_DString ds;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "name");
return TCL_ERROR;
}
- fileName = Tcl_TranslateFileName(interp, TclGetString(objv[1]), &ds);
- if (fileName == NULL) {
+ if (Tcl_TranslateFileName(interp, TclGetString(objv[1]), &ds) == NULL) {
return TCL_ERROR;
}
- Tcl_SetObjResult(interp, Tcl_NewStringObj(fileName,
- Tcl_DStringLength(&ds)));
- Tcl_DStringFree(&ds);
+ Tcl_SetObjResult(interp, TclDStringToObj(&ds));
return TCL_OK;
}
@@ -1935,8 +1998,9 @@ PathSplitCmd(
}
res = Tcl_FSSplitPath(objv[1], NULL);
if (res == NULL) {
- Tcl_AppendResult(interp, "could not read \"", TclGetString(objv[1]),
- "\": no such file or directory", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not read \"%s\": no such file or directory",
+ TclGetString(objv[1])));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PATHSPLIT", "NONESUCH",
NULL);
return TCL_ERROR;
@@ -2037,7 +2101,8 @@ FilesystemSeparatorCmd(
Tcl_Obj *separatorObj = Tcl_FSPathSeparator(objv[1]);
if (separatorObj == NULL) {
- Tcl_SetResult(interp, "unrecognised path", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "unrecognised path", -1));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "FILESYSTEM",
Tcl_GetString(objv[1]), NULL);
return TCL_ERROR;
@@ -2156,9 +2221,9 @@ GetStatBuf(
if (status < 0) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "could not read \"",
- TclGetString(pathPtr), "\": ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not read \"%s\": %s",
+ TclGetString(pathPtr), Tcl_PosixError(interp)));
}
return TCL_ERROR;
}
@@ -2505,7 +2570,7 @@ ForPostNextCallback(
/*
*----------------------------------------------------------------------
*
- * Tcl_ForeachObjCmd, TclNRForeachCmd --
+ * Tcl_ForeachObjCmd, TclNRForeachCmd, EachloopCmd --
*
* This object-based procedure is invoked to process the "foreach" Tcl
* command. See the user documentation for details on what it does.
@@ -2537,6 +2602,38 @@ TclNRForeachCmd(
int objc,
Tcl_Obj *const objv[])
{
+ return EachloopCmd(interp, TCL_EACH_KEEP_NONE, objc, objv);
+}
+
+int
+Tcl_LmapObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ return Tcl_NRCallObjProc(interp, TclNRLmapCmd, dummy, objc, objv);
+}
+
+int
+TclNRLmapCmd(
+ ClientData dummy,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ return EachloopCmd(interp, TCL_EACH_COLLECT, objc, objv);
+}
+
+static inline int
+EachloopCmd(
+ Tcl_Interp *interp, /* Our context for variables and script
+ * evaluation. */
+ int collect, /* Select collecting or accumulating mode
+ * (TCL_EACH_*) */
+ int objc, /* The arguments being passed in... */
+ Tcl_Obj *const objv[])
+{
int numLists = (objc-2) / 2;
register struct ForeachState *statePtr;
int i, j, result;
@@ -2580,6 +2677,12 @@ TclNRForeachCmd(
statePtr->bodyPtr = objv[objc - 1];
statePtr->bodyIdx = objc - 1;
+ if (collect == TCL_EACH_COLLECT) {
+ statePtr->resultList = Tcl_NewListObj(0, NULL);
+ } else {
+ statePtr->resultList = NULL;
+ }
+
/*
* Break up the value lists and variable lists into elements.
*/
@@ -2593,8 +2696,11 @@ TclNRForeachCmd(
TclListObjGetElements(NULL, statePtr->vCopyList[i],
&statePtr->varcList[i], &statePtr->varvList[i]);
if (statePtr->varcList[i] < 1) {
- Tcl_AppendResult(interp, "foreach varlist is empty", NULL);
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FOREACH",
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "%s varlist is empty",
+ (statePtr->resultList != NULL ? "lmap" : "foreach")));
+ Tcl_SetErrorCode(interp, "TCL", "OPERATION",
+ (statePtr->resultList != NULL ? "LMAP" : "FOREACH"),
"NEEDVARS", NULL);
result = TCL_ERROR;
goto done;
@@ -2664,14 +2770,21 @@ ForeachLoopStep(
switch (result) {
case TCL_CONTINUE:
result = TCL_OK;
+ break;
case TCL_OK:
+ if (statePtr->resultList != NULL) {
+ Tcl_ListObjAppendElement(interp, statePtr->resultList,
+ Tcl_GetObjResult(interp));
+ }
break;
case TCL_BREAK:
result = TCL_OK;
- goto done;
+ goto finish;
case TCL_ERROR:
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
- "\n (\"foreach\" body line %d)", Tcl_GetErrorLine(interp)));
+ "\n (\"%s\" body line %d)",
+ (statePtr->resultList != NULL ? "lmap" : "foreach"),
+ Tcl_GetErrorLine(interp)));
default:
goto done;
}
@@ -2696,7 +2809,14 @@ ForeachLoopStep(
* We're done. Tidy up our work space and finish off.
*/
- Tcl_ResetResult(interp);
+ finish:
+ if (statePtr->resultList == NULL) {
+ Tcl_ResetResult(interp);
+ } else {
+ Tcl_SetObjResult(interp, statePtr->resultList);
+ statePtr->resultList = NULL; /* Don't clean it up */
+ }
+
done:
ForeachCleanup(interp, statePtr);
return result;
@@ -2729,7 +2849,8 @@ ForeachAssignments(
if (varValuePtr == NULL) {
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
- "\n (setting foreach loop variable \"%s\")",
+ "\n (setting %s loop variable \"%s\")",
+ (statePtr->resultList != NULL ? "lmap" : "foreach"),
TclGetString(statePtr->varvList[i][v])));
return TCL_ERROR;
}
@@ -2758,6 +2879,9 @@ ForeachCleanup(
TclDecrRefCount(statePtr->aCopyList[i]);
}
}
+ if (statePtr->resultList != NULL) {
+ TclDecrRefCount(statePtr->resultList);
+ }
TclStackFree(interp, statePtr);
}
diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c
index 95532d3..41c1eb6 100644
--- a/generic/tclCmdIL.c
+++ b/generic/tclCmdIL.c
@@ -27,15 +27,15 @@
*/
typedef struct SortElement {
- union { /* The value that we sorting by. */
+ union { /* The value that we sorting by. */
const char *strValuePtr;
long intValue;
double doubleValue;
Tcl_Obj *objValuePtr;
} collationKey;
- union { /* Object being sorted, or its index. */
- Tcl_Obj *objPtr;
- int index;
+ union { /* Object being sorted, or its index. */
+ Tcl_Obj *objPtr;
+ int index;
} payload;
struct SortElement *nextPtr;/* Next element in the list, or NULL for end
* of list. */
@@ -161,30 +161,30 @@ static Tcl_Obj * SelectObjFromSublist(Tcl_Obj *firstPtr,
*/
static const EnsembleImplMap defaultInfoMap[] = {
- {"args", InfoArgsCmd, NULL, NULL, NULL, 0},
- {"body", InfoBodyCmd, NULL, NULL, NULL, 0},
- {"cmdcount", InfoCmdCountCmd, NULL, NULL, NULL, 0},
- {"commands", InfoCommandsCmd, NULL, NULL, NULL, 0},
- {"complete", InfoCompleteCmd, NULL, NULL, NULL, 0},
- {"coroutine", TclInfoCoroutineCmd, NULL, NULL, NULL, 0},
- {"default", InfoDefaultCmd, NULL, NULL, NULL, 0},
- {"errorstack", InfoErrorStackCmd, NULL, NULL, NULL, 0},
+ {"args", InfoArgsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"body", InfoBodyCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"cmdcount", InfoCmdCountCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
+ {"commands", InfoCommandsCmd, TclCompileInfoCommandsCmd, NULL, NULL, 0},
+ {"complete", InfoCompleteCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"coroutine", TclInfoCoroutineCmd, TclCompileInfoCoroutineCmd, NULL, NULL, 0},
+ {"default", InfoDefaultCmd, TclCompileBasic3ArgCmd, NULL, NULL, 0},
+ {"errorstack", InfoErrorStackCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"exists", TclInfoExistsCmd, TclCompileInfoExistsCmd, NULL, NULL, 0},
- {"frame", InfoFrameCmd, NULL, NULL, NULL, 0},
- {"functions", InfoFunctionsCmd, NULL, NULL, NULL, 0},
- {"globals", TclInfoGlobalsCmd, NULL, NULL, NULL, 0},
- {"hostname", InfoHostnameCmd, NULL, NULL, NULL, 0},
- {"level", InfoLevelCmd, NULL, NULL, NULL, 0},
- {"library", InfoLibraryCmd, NULL, NULL, NULL, 0},
- {"loaded", InfoLoadedCmd, NULL, NULL, NULL, 0},
- {"locals", TclInfoLocalsCmd, NULL, NULL, NULL, 0},
- {"nameofexecutable", InfoNameOfExecutableCmd, NULL, NULL, NULL, 0},
- {"patchlevel", InfoPatchLevelCmd, NULL, NULL, NULL, 0},
- {"procs", InfoProcsCmd, NULL, NULL, NULL, 0},
- {"script", InfoScriptCmd, NULL, NULL, NULL, 0},
- {"sharedlibextension", InfoSharedlibCmd, NULL, NULL, NULL, 0},
- {"tclversion", InfoTclVersionCmd, NULL, NULL, NULL, 0},
- {"vars", TclInfoVarsCmd, NULL, NULL, NULL, 0},
+ {"frame", InfoFrameCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+ {"functions", InfoFunctionsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+ {"globals", TclInfoGlobalsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+ {"hostname", InfoHostnameCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
+ {"level", InfoLevelCmd, TclCompileInfoLevelCmd, NULL, NULL, 0},
+ {"library", InfoLibraryCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
+ {"loaded", InfoLoadedCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+ {"locals", TclInfoLocalsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+ {"nameofexecutable", InfoNameOfExecutableCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
+ {"patchlevel", InfoPatchLevelCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
+ {"procs", InfoProcsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+ {"script", InfoScriptCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+ {"sharedlibextension", InfoSharedlibCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
+ {"tclversion", InfoTclVersionCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
+ {"vars", TclInfoVarsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
};
@@ -229,8 +229,9 @@ TclNRIfObjCmd(
Tcl_Obj *boolObj;
if (objc <= 1) {
- Tcl_AppendResult(interp, "wrong # args: no expression after \"",
- TclGetString(objv[0]), "\" argument", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "wrong # args: no expression after \"%s\" argument",
+ TclGetString(objv[0])));
Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
return TCL_ERROR;
}
@@ -319,8 +320,9 @@ IfConditionCallback(
*/
if (i >= objc) {
- Tcl_AppendResult(interp, "wrong # args: ",
- "no expression after \"", clause, "\" argument", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "wrong # args: no expression after \"%s\" argument",
+ clause));
Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
return TCL_ERROR;
}
@@ -345,8 +347,9 @@ IfConditionCallback(
}
}
if (i < objc - 1) {
- Tcl_AppendResult(interp, "wrong # args: ",
- "extra words after \"else\" clause in \"if\" command", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "wrong # args: extra words after \"else\" clause in \"if\" command",
+ -1));
Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
return TCL_ERROR;
}
@@ -361,9 +364,9 @@ IfConditionCallback(
return TclNREvalObjEx(interp, objv[i], 0, iPtr->cmdFramePtr, i);
missingScript:
- clause = TclGetString(objv[i-1]);
- Tcl_AppendResult(interp, "wrong # args: no script following \"", clause,
- "\" argument", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "wrong # args: no script following \"%s\" argument",
+ TclGetString(objv[i-1])));
Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
return TCL_ERROR;
}
@@ -491,7 +494,8 @@ InfoArgsCmd(
name = TclGetString(objv[1]);
procPtr = TclFindProc(iPtr, name);
if (procPtr == NULL) {
- Tcl_AppendResult(interp, "\"", name, "\" isn't a procedure", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" isn't a procedure", name));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", name, NULL);
return TCL_ERROR;
}
@@ -552,7 +556,8 @@ InfoBodyCmd(
name = TclGetString(objv[1]);
procPtr = TclFindProc(iPtr, name);
if (procPtr == NULL) {
- Tcl_AppendResult(interp, "\"", name, "\" isn't a procedure", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" isn't a procedure", name));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", name, NULL);
return TCL_ERROR;
}
@@ -981,7 +986,8 @@ InfoDefaultCmd(
procPtr = TclFindProc(iPtr, procName);
if (procPtr == NULL) {
- Tcl_AppendResult(interp, "\"", procName, "\" isn't a procedure",NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" isn't a procedure", procName));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", procName,
NULL);
return TCL_ERROR;
@@ -1012,8 +1018,9 @@ InfoDefaultCmd(
}
}
- Tcl_AppendResult(interp, "procedure \"", procName,
- "\" doesn't have an argument \"", argName, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "procedure \"%s\" doesn't have an argument \"%s\"",
+ procName, argName));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARGUMENT", argName, NULL);
return TCL_ERROR;
}
@@ -1055,10 +1062,10 @@ InfoErrorStackCmd(
target = interp;
if (objc == 2) {
- target = Tcl_GetSlave(interp, Tcl_GetString(objv[1]));
- if (target == NULL) {
- return TCL_ERROR;
- }
+ target = Tcl_GetSlave(interp, Tcl_GetString(objv[1]));
+ if (target == NULL) {
+ return TCL_ERROR;
+ }
}
iPtr = (Interp *) target;
@@ -1140,32 +1147,38 @@ InfoFrameCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
Interp *iPtr = (Interp *) interp;
- int level, topLevel;
- CmdFrame *framePtr;
+ int level, code = TCL_OK;
+ CmdFrame *framePtr, **cmdFramePtrPtr = &iPtr->cmdFramePtr;
+ CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
+ int topLevel = 0;
- topLevel = ((iPtr->cmdFramePtr == NULL)
- ? 0
- : iPtr->cmdFramePtr->level);
-
-
- if (iPtr->execEnvPtr->corPtr) {
- /*
- * A coroutine: must fix the level computations AND the cmdFrame chain,
- * which is interrupted at the base.
- */
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "?number?");
+ return TCL_ERROR;
+ }
- CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
- CmdFrame *runPtr = iPtr->cmdFramePtr;
- CmdFrame *lastPtr = NULL;
+ while (corPtr) {
+ while (*cmdFramePtrPtr) {
+ topLevel++;
+ cmdFramePtrPtr = &((*cmdFramePtrPtr)->nextPtr);
+ }
+ if (corPtr->caller.cmdFramePtr) {
+ *cmdFramePtrPtr = corPtr->caller.cmdFramePtr;
+ }
+ corPtr = corPtr->callerEEPtr->corPtr;
+ }
+ topLevel += (*cmdFramePtrPtr)->level;
- topLevel += corPtr->caller.cmdFramePtr->level;
- while (runPtr && (runPtr != corPtr->caller.cmdFramePtr)) {
- lastPtr = runPtr;
- runPtr = runPtr->nextPtr;
- }
- if (lastPtr && !runPtr) {
- lastPtr->nextPtr = corPtr->caller.cmdFramePtr;
- }
+ if (topLevel != iPtr->cmdFramePtr->level) {
+ framePtr = iPtr->cmdFramePtr;
+ while (framePtr) {
+ framePtr->level = topLevel--;
+ framePtr = framePtr->nextPtr;
+ }
+ if (topLevel) {
+ Tcl_Panic("Broken frame level calculation");
+ }
+ topLevel = iPtr->cmdFramePtr->level;
}
if (objc == 1) {
@@ -1174,10 +1187,7 @@ InfoFrameCmd(
*/
Tcl_SetObjResult(interp, Tcl_NewIntObj(topLevel));
- return TCL_OK;
- } else if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "?number?");
- return TCL_ERROR;
+ goto done;
}
/*
@@ -1185,16 +1195,18 @@ InfoFrameCmd(
*/
if (TclGetIntFromObj(interp, objv[1], &level) != TCL_OK) {
- return TCL_ERROR;
+ code = TCL_ERROR;
+ goto done;
}
if ((level > topLevel) || (level <= - topLevel)) {
levelError:
- Tcl_AppendResult(interp, "bad level \"", TclGetString(objv[1]), "\"",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad level \"%s\"", TclGetString(objv[1])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_FRAME",
TclGetString(objv[1]), NULL);
- return TCL_ERROR;
+ code = TCL_ERROR;
+ goto done;
}
/*
@@ -1214,7 +1226,31 @@ InfoFrameCmd(
}
Tcl_SetObjResult(interp, TclInfoFrame(interp, framePtr));
- return TCL_OK;
+
+ done:
+ cmdFramePtrPtr = &iPtr->cmdFramePtr;
+ corPtr = iPtr->execEnvPtr->corPtr;
+ while (corPtr) {
+ CmdFrame *endPtr = corPtr->caller.cmdFramePtr;
+
+ if (endPtr) {
+ if (*cmdFramePtrPtr == endPtr) {
+ *cmdFramePtrPtr = NULL;
+ } else {
+ CmdFrame *runPtr = *cmdFramePtrPtr;
+
+ while (runPtr->nextPtr != endPtr) {
+ runPtr->level -= endPtr->level;
+ runPtr = runPtr->nextPtr;
+ }
+ runPtr->level = 1;
+ runPtr->nextPtr = NULL;
+ }
+ cmdFramePtrPtr = &corPtr->caller.cmdFramePtr;
+ }
+ corPtr = corPtr->callerEEPtr->corPtr;
+ }
+ return code;
}
/*
@@ -1270,28 +1306,12 @@ TclInfoFrame(
*/
ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
- ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0]));
- ADD_PAIR("cmd", Tcl_NewStringObj(framePtr->cmd.str.cmd,
- framePtr->cmd.str.len));
- break;
-
- case TCL_LOCATION_EVAL_LIST:
- /*
- * List optimized evaluation. Type, line, cmd, the latter through
- * listPtr, possibly a frame.
- */
-
- ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
- ADD_PAIR("line", Tcl_NewIntObj(1));
-
- /*
- * We put a duplicate of the command list obj into the result to
- * ensure that the 'pure List'-property of the command itself is not
- * destroyed. Otherwise the query here would disable the list
- * optimization path in Tcl_EvalObjEx.
- */
-
- ADD_PAIR("cmd", Tcl_DuplicateObj(framePtr->cmd.listPtr));
+ if (framePtr->line) {
+ ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0]));
+ } else {
+ ADD_PAIR("line", Tcl_NewIntObj(1));
+ }
+ ADD_PAIR("cmd", TclGetSourceFromFrame(framePtr, 0, NULL));
break;
case TCL_LOCATION_PREBC:
@@ -1339,8 +1359,7 @@ TclInfoFrame(
Tcl_DecrRefCount(fPtr->data.eval.path);
}
- ADD_PAIR("cmd",
- Tcl_NewStringObj(fPtr->cmd.str.cmd, fPtr->cmd.str.len));
+ ADD_PAIR("cmd", TclGetSourceFromFrame(fPtr, 0, NULL));
TclStackFree(interp, fPtr);
break;
}
@@ -1359,8 +1378,7 @@ TclInfoFrame(
* the result list object.
*/
- ADD_PAIR("cmd", Tcl_NewStringObj(framePtr->cmd.str.cmd,
- framePtr->cmd.str.len));
+ ADD_PAIR("cmd", TclGetSourceFromFrame(framePtr, 0, NULL));
break;
case TCL_LOCATION_PROC:
@@ -1377,15 +1395,15 @@ TclInfoFrame(
Tcl_HashEntry *namePtr = procPtr->cmdPtr->hPtr;
if (namePtr) {
- Tcl_Obj *procNameObj;
+ Tcl_Obj *procNameObj;
/*
* This is a regular command.
*/
- TclNewObj(procNameObj);
- Tcl_GetCommandFullName(interp, (Tcl_Command) procPtr->cmdPtr,
- procNameObj);
+ TclNewObj(procNameObj);
+ Tcl_GetCommandFullName(interp, (Tcl_Command) procPtr->cmdPtr,
+ procNameObj);
ADD_PAIR("proc", procNameObj);
} else if (procPtr->cmdPtr->clientData) {
ExtraFrameInfo *efiPtr = procPtr->cmdPtr->clientData;
@@ -1460,19 +1478,42 @@ InfoFunctionsCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- const char *pattern;
+ Tcl_Obj *script;
+ int code;
- if (objc == 1) {
- pattern = NULL;
- } else if (objc == 2) {
- pattern = TclGetString(objv[1]);
- } else {
+ if (objc > 2) {
Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
return TCL_ERROR;
}
- Tcl_SetObjResult(interp, Tcl_ListMathFuncs(interp, pattern));
- return TCL_OK;
+ script = Tcl_NewStringObj(
+" ::apply [::list {{pattern *}} {\n"
+" ::set cmds {}\n"
+" ::foreach cmd [::info commands ::tcl::mathfunc::$pattern] {\n"
+" ::lappend cmds [::namespace tail $cmd]\n"
+" }\n"
+" ::foreach cmd [::info commands tcl::mathfunc::$pattern] {\n"
+" ::set cmd [::namespace tail $cmd]\n"
+" ::if {$cmd ni $cmds} {\n"
+" ::lappend cmds $cmd\n"
+" }\n"
+" }\n"
+" ::return $cmds\n"
+" } [::namespace current]] ", -1);
+
+ if (objc == 2) {
+ Tcl_Obj *arg = Tcl_NewListObj(1, &(objv[1]));
+
+ Tcl_AppendObjToObj(script, arg);
+ Tcl_DecrRefCount(arg);
+ }
+
+ Tcl_IncrRefCount(script);
+ code = Tcl_EvalObjEx(interp, script, 0);
+
+ Tcl_DecrRefCount(script);
+
+ return code;
}
/*
@@ -1514,7 +1555,9 @@ InfoHostnameCmd(
Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
return TCL_OK;
}
- Tcl_SetResult(interp, "unable to determine name of host", TCL_STATIC);
+
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "unable to determine name of host", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "HOSTNAME", "UNKNOWN", NULL);
return TCL_ERROR;
}
@@ -1585,8 +1628,8 @@ InfoLevelCmd(
return TCL_ERROR;
levelError:
- Tcl_AppendResult(interp, "bad level \"", TclGetString(objv[1]), "\"",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad level \"%s\"", TclGetString(objv[1])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_LEVEL",
TclGetString(objv[1]), NULL);
return TCL_ERROR;
@@ -1632,7 +1675,9 @@ InfoLibraryCmd(
Tcl_SetObjResult(interp, Tcl_NewStringObj(libDirName, -1));
return TCL_OK;
}
- Tcl_SetResult(interp, "no library has been specified for Tcl",TCL_STATIC);
+
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "no library has been specified for Tcl", -1));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", "tcl_library",NULL);
return TCL_ERROR;
}
@@ -2566,9 +2611,10 @@ Tcl_LrepeatObjCmd(
return TCL_ERROR;
}
if (elementCount < 0) {
- Tcl_SetObjResult(interp, Tcl_Format(NULL,
- "bad count \"%d\": must be integer >= 0", 1, objv+1));
- Tcl_SetErrorCode(interp, "TCL","OPERATION","LREPEAT","NEGARG", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad count \"%d\": must be integer >= 0", elementCount));
+ Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPEAT", "NEGARG",
+ NULL);
return TCL_ERROR;
}
@@ -2584,7 +2630,7 @@ Tcl_LrepeatObjCmd(
if (elementCount && objc > LIST_MAX/elementCount) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"max length of a Tcl list (%d elements) exceeded", LIST_MAX));
- Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
+ Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
return TCL_ERROR;
}
totalElems = objc * elementCount;
@@ -2699,9 +2745,10 @@ Tcl_LreplaceObjCmd(
*/
if ((first >= listLen) && (listLen > 0)) {
- Tcl_AppendResult(interp, "list doesn't contain element ",
- TclGetString(objv[2]), NULL);
- Tcl_SetErrorCode(interp, "TCL","OPERATION","LREPLACE","BADIDX", NULL);
+ 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 (last >= listLen) {
@@ -2944,7 +2991,7 @@ Tcl_LsearchObjCmd(
dataType = INTEGER;
break;
case LSEARCH_NOCASE: /* -nocase */
- strCmpFn = strcasecmp;
+ strCmpFn = TclUtfCasecmp;
noCase = 1;
break;
case LSEARCH_NOT: /* -not */
@@ -2972,8 +3019,9 @@ Tcl_LsearchObjCmd(
Tcl_DecrRefCount(startPtr);
}
if (i > objc-4) {
- Tcl_AppendResult(interp, "missing starting index", NULL);
- Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "missing starting index", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
result = TCL_ERROR;
goto done;
}
@@ -3003,10 +3051,10 @@ Tcl_LsearchObjCmd(
if (startPtr != NULL) {
Tcl_DecrRefCount(startPtr);
}
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"\"-index\" option must be followed by list index",
- NULL);
- Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+ -1));
+ Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
return TCL_ERROR;
}
@@ -3064,18 +3112,18 @@ Tcl_LsearchObjCmd(
if (startPtr != NULL) {
Tcl_DecrRefCount(startPtr);
}
- Tcl_AppendResult(interp,
- "-subindices cannot be used without -index option", NULL);
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
- "BAD_OPTION_MIX", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "-subindices cannot be used without -index option", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
+ "BAD_OPTION_MIX", NULL);
return TCL_ERROR;
}
if (bisect && (allMatches || negatedMatch)) {
- Tcl_AppendResult(interp,
- "-bisect is not compatible with -all or -not", NULL);
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
- "BAD_OPTION_MIX", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "-bisect is not compatible with -all or -not", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
+ "BAD_OPTION_MIX", NULL);
return TCL_ERROR;
}
@@ -3338,7 +3386,7 @@ Tcl_LsearchObjCmd(
*/
if (noCase) {
- match = (strcasecmp(bytes, patternBytes) == 0);
+ match = (TclUtfCasecmp(bytes, patternBytes) == 0);
} else {
match = (memcmp(bytes, patternBytes,
(size_t) length) == 0);
@@ -3507,7 +3555,7 @@ Tcl_LsetObjCmd(
if (objc < 3) {
Tcl_WrongNumArgs(interp, 1, objv,
- "listVar ?index? ?index ...? value");
+ "listVar ?index? ?index ...? value");
return TCL_ERROR;
}
@@ -3583,7 +3631,8 @@ Tcl_LsortObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument values. */
{
- int i, j, index, indices, length, nocase = 0, sortMode, indexc;
+ int i, j, index, indices, length, nocase = 0, indexc;
+ int sortMode = SORTMODE_ASCII;
int group, groupSize, groupOffset, idx, allocatedIndexVector = 0;
Tcl_Obj *resultPtr, *cmdPtr, **listObjPtrs, *listObj, *indexPtr;
SortElement *elementArray, *elementPtr;
@@ -3640,10 +3689,10 @@ Tcl_LsortObjCmd(
break;
case LSORT_COMMAND:
if (i == objc-2) {
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"\"-command\" option must be followed "
- "by comparison command", NULL);
- Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+ "by comparison command", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
sortInfo.resultCode = TCL_ERROR;
goto done2;
}
@@ -3661,29 +3710,30 @@ Tcl_LsortObjCmd(
sortInfo.isIncreasing = 1;
break;
case LSORT_INDEX: {
- int indexc, dummy;
+ int indexc, dummy;
Tcl_Obj **indexv;
if (i == objc-2) {
- Tcl_AppendResult(interp, "\"-index\" option must be "
- "followed by list index", NULL);
- Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
- sortInfo.resultCode = TCL_ERROR;
- goto done2;
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "\"-index\" option must be followed by list index",
+ -1));
+ Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+ sortInfo.resultCode = TCL_ERROR;
+ goto done2;
}
if (TclListObjGetElements(interp, objv[i+1], &indexc,
&indexv) != TCL_OK) {
- sortInfo.resultCode = TCL_ERROR;
- goto done2;
+ sortInfo.resultCode = TCL_ERROR;
+ goto done2;
}
- /*
- * Check each of the indices for syntactic correctness. Note that
- * we do not store the converted values here because we do not
- * know if this is the only -index option yet and so we can't
- * allocate any space; that happens after the scan through all the
- * options is done.
- */
+ /*
+ * Check each of the indices for syntactic correctness. Note that
+ * we do not store the converted values here because we do not
+ * know if this is the only -index option yet and so we can't
+ * allocate any space; that happens after the scan through all the
+ * options is done.
+ */
for (j=0 ; j<indexc ; j++) {
if (TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
@@ -3695,7 +3745,7 @@ Tcl_LsortObjCmd(
}
}
indexPtr = objv[i+1];
- i++;
+ i++;
break;
}
case LSORT_INTEGER:
@@ -3715,9 +3765,10 @@ Tcl_LsortObjCmd(
break;
case LSORT_STRIDE:
if (i == objc-2) {
- Tcl_AppendResult(interp, "\"-stride\" option must be ",
- "followed by stride length", NULL);
- Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "\"-stride\" option must be "
+ "followed by stride length", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
sortInfo.resultCode = TCL_ERROR;
goto done2;
}
@@ -3726,10 +3777,10 @@ Tcl_LsortObjCmd(
goto done2;
}
if (groupSize < 2) {
- Tcl_AppendResult(interp, "stride length must be at least 2",
- NULL);
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
- "BADSTRIDE", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "stride length must be at least 2", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
+ "BADSTRIDE", NULL);
sortInfo.resultCode = TCL_ERROR;
goto done2;
}
@@ -3749,26 +3800,26 @@ Tcl_LsortObjCmd(
*/
if (indexPtr) {
- Tcl_Obj **indexv;
-
- TclListObjGetElements(interp, indexPtr, &sortInfo.indexc, &indexv);
- switch (sortInfo.indexc) {
- case 0:
- sortInfo.indexv = NULL;
- break;
- case 1:
- sortInfo.indexv = &sortInfo.singleIndex;
- break;
- default:
- sortInfo.indexv =
+ Tcl_Obj **indexv;
+
+ TclListObjGetElements(interp, indexPtr, &sortInfo.indexc, &indexv);
+ switch (sortInfo.indexc) {
+ case 0:
+ sortInfo.indexv = NULL;
+ break;
+ case 1:
+ sortInfo.indexv = &sortInfo.singleIndex;
+ break;
+ default:
+ sortInfo.indexv =
TclStackAlloc(interp, sizeof(int) * sortInfo.indexc);
- allocatedIndexVector = 1; /* Cannot use indexc field, as it
- * might be decreased by 1 later. */
- }
- for (j=0 ; j<sortInfo.indexc ; j++) {
- TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
+ allocatedIndexVector = 1; /* Cannot use indexc field, as it
+ * might be decreased by 1 later. */
+ }
+ for (j=0 ; j<sortInfo.indexc ; j++) {
+ TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
&sortInfo.indexv[j]);
- }
+ }
}
listObj = objv[objc-1];
@@ -3823,11 +3874,11 @@ Tcl_LsortObjCmd(
if (group) {
if (length % groupSize) {
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"list size must be a multiple of the stride length",
+ -1));
+ Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT", "BADSTRIDE",
NULL);
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT", "BADSTRIDE",
- NULL);
sortInfo.resultCode = TCL_ERROR;
goto done;
}
@@ -3843,11 +3894,11 @@ Tcl_LsortObjCmd(
groupOffset = (groupOffset - SORTIDX_END) + groupSize - 1;
}
if (groupOffset < 0 || groupOffset >= groupSize) {
- Tcl_AppendResult(interp, "when used with \"-stride\", the "
- "leading \"-index\" value must be within the group",
- NULL);
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
- "BADINDEX", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "when used with \"-stride\", the leading \"-index\""
+ " value must be within the group", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
+ "BADINDEX", NULL);
sortInfo.resultCode = TCL_ERROR;
goto done;
}
@@ -3927,7 +3978,7 @@ Tcl_LsortObjCmd(
goto done1;
}
elementArray[i].collationKey.intValue = a;
- } else if (sortInfo.sortMode == SORTMODE_REAL) {
+ } else if (sortMode == SORTMODE_REAL) {
double a;
if (Tcl_GetDoubleFromObj(sortInfo.interp, indexPtr,
@@ -4024,7 +4075,7 @@ Tcl_LsortObjCmd(
TclStackFree(interp, elementArray);
done:
- if (sortInfo.sortMode == SORTMODE_COMMAND) {
+ if (sortMode == SORTMODE_COMMAND) {
TclDecrRefCount(sortInfo.compareCmdPtr);
TclDecrRefCount(listObj);
sortInfo.compareCmdPtr = NULL;
@@ -4169,7 +4220,7 @@ SortCompare(
order = strcmp(elemPtr1->collationKey.strValuePtr,
elemPtr2->collationKey.strValuePtr);
} else if (infoPtr->sortMode == SORTMODE_ASCII_NC) {
- order = strcasecmp(elemPtr1->collationKey.strValuePtr,
+ order = TclUtfCasecmp(elemPtr1->collationKey.strValuePtr,
elemPtr2->collationKey.strValuePtr);
} else if (infoPtr->sortMode == SORTMODE_DICTIONARY) {
order = DictionaryCompare(elemPtr1->collationKey.strValuePtr,
@@ -4231,11 +4282,10 @@ SortCompare(
if (TclGetIntFromObj(infoPtr->interp,
Tcl_GetObjResult(infoPtr->interp), &order) != TCL_OK) {
- Tcl_ResetResult(infoPtr->interp);
- Tcl_AppendResult(infoPtr->interp,
- "-compare command returned non-integer result", NULL);
- Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT",
- "COMPARISONFAILED", NULL);
+ Tcl_SetObjResult(infoPtr->interp, Tcl_NewStringObj(
+ "-compare command returned non-integer result", -1));
+ Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT",
+ "COMPARISONFAILED", NULL);
infoPtr->resultCode = TCL_ERROR;
return 0;
}
@@ -4446,11 +4496,11 @@ SelectObjFromSublist(
return NULL;
}
if (currentObj == NULL) {
- Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf(
- "element %d missing from sublist \"%s\"",
- index, TclGetString(objPtr)));
- Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT",
- "INDEXFAILED", NULL);
+ Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf(
+ "element %d missing from sublist \"%s\"",
+ index, TclGetString(objPtr)));
+ Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT",
+ "INDEXFAILED", NULL);
infoPtr->resultCode = TCL_ERROR;
return NULL;
}
@@ -4465,6 +4515,5 @@ SelectObjFromSublist(
* c-basic-offset: 4
* fill-column: 78
* tab-width: 8
- * indent-tabs-mode: nil
* End:
*/
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index e7c7152..00c9f2f 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -18,6 +18,7 @@
#include "tclInt.h"
#include "tclRegexp.h"
+#include "tclStringTrim.h"
static inline Tcl_Obj * During(Tcl_Interp *interp, int resultCode,
Tcl_Obj *oldOptions, Tcl_Obj *errorInfo);
@@ -34,12 +35,36 @@ static int UniCharIsHexDigit(int character);
/*
* Default set of characters to trim in [string trim] and friends. This is a
- * UTF-8 literal string containing space, tab, newline, carriage return,
- * ethiopic wordspace (U+1361), ogham space mark (U+1680), and ideographic
- * space (U+3000). [TIP #318]
+ * UTF-8 literal string containing all Unicode space characters [TIP #413]
*/
-#define DEFAULT_TRIM_SET " \t\n\r\xe1\x8d\xa1\xe1\x9a\x80\xe3\x80\x80"
+const char tclDefaultTrimSet[] =
+ "\x09\x0a\x0b\x0c\x0d " /* ASCII */
+ "\xc0\x80" /* nul (U+0000) */
+ "\xc2\x85" /* next line (U+0085) */
+ "\xc2\xa0" /* non-breaking space (U+00a0) */
+ "\xe1\x9a\x80" /* ogham space mark (U+1680) */
+ "\xe1\xa0\x8e" /* mongolian vowel separator (U+180e) */
+ "\xe2\x80\x80" /* en quad (U+2000) */
+ "\xe2\x80\x81" /* em quad (U+2001) */
+ "\xe2\x80\x82" /* en space (U+2002) */
+ "\xe2\x80\x83" /* em space (U+2003) */
+ "\xe2\x80\x84" /* three-per-em space (U+2004) */
+ "\xe2\x80\x85" /* four-per-em space (U+2005) */
+ "\xe2\x80\x86" /* six-per-em space (U+2006) */
+ "\xe2\x80\x87" /* figure space (U+2007) */
+ "\xe2\x80\x88" /* punctuation space (U+2008) */
+ "\xe2\x80\x89" /* thin space (U+2009) */
+ "\xe2\x80\x8a" /* hair space (U+200a) */
+ "\xe2\x80\x8b" /* zero width space (U+200b) */
+ "\xe2\x80\xa8" /* line separator (U+2028) */
+ "\xe2\x80\xa9" /* paragraph separator (U+2029) */
+ "\xe2\x80\xaf" /* narrow no-break space (U+202f) */
+ "\xe2\x81\x9f" /* medium mathematical space (U+205f) */
+ "\xe2\x81\xa0" /* word joiner (U+2060) */
+ "\xe3\x80\x80" /* ideographic space (U+3000) */
+ "\xef\xbb\xbf" /* zero width no-break space (U+feff) */
+;
/*
*----------------------------------------------------------------------
@@ -204,8 +229,8 @@ Tcl_RegexpObjCmd(
*/
if (doinline && ((objc - 2) != 0)) {
- Tcl_AppendResult(interp, "regexp match variables not allowed"
- " when using -inline", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "regexp match variables not allowed when using -inline", -1));
goto optionError;
}
@@ -282,8 +307,11 @@ Tcl_RegexpObjCmd(
* start of the string unless the previous character is a newline.
*/
- if ((offset == 0) || ((offset > 0) &&
- (Tcl_GetUniChar(objPtr, offset-1) == (Tcl_UniChar) '\n'))) {
+ if (offset == 0) {
+ eflags = 0;
+ } else if (offset > stringLength) {
+ eflags = TCL_REG_NOTBOL;
+ } else if (Tcl_GetUniChar(objPtr, offset-1) == (Tcl_UniChar)'\n') {
eflags = 0;
} else {
eflags = TCL_REG_NOTBOL;
@@ -1433,18 +1461,19 @@ StringIsCmd(
static const char *const isClasses[] = {
"alnum", "alpha", "ascii", "control",
- "boolean", "digit", "double", "false",
- "graph", "integer", "list", "lower",
- "print", "punct", "space", "true",
- "upper", "wideinteger", "wordchar", "xdigit",
- NULL
+ "boolean", "digit", "double", "entier",
+ "false", "graph", "integer", "list",
+ "lower", "print", "punct", "space",
+ "true", "upper", "wideinteger", "wordchar",
+ "xdigit", NULL
};
enum isClasses {
- STR_IS_ALNUM, STR_IS_ALPHA, STR_IS_ASCII, STR_IS_CONTROL,
- STR_IS_BOOL, STR_IS_DIGIT, STR_IS_DOUBLE, STR_IS_FALSE,
- STR_IS_GRAPH, STR_IS_INT, STR_IS_LIST, STR_IS_LOWER,
- STR_IS_PRINT, STR_IS_PUNCT, STR_IS_SPACE, STR_IS_TRUE,
- STR_IS_UPPER, STR_IS_WIDE, STR_IS_WORD, STR_IS_XDIGIT
+ STR_IS_ALNUM, STR_IS_ALPHA, STR_IS_ASCII, STR_IS_CONTROL,
+ STR_IS_BOOL, STR_IS_DIGIT, STR_IS_DOUBLE, STR_IS_ENTIER,
+ STR_IS_FALSE, STR_IS_GRAPH, STR_IS_INT, STR_IS_LIST,
+ STR_IS_LOWER, STR_IS_PRINT, STR_IS_PUNCT, STR_IS_SPACE,
+ STR_IS_TRUE, STR_IS_UPPER, STR_IS_WIDE, STR_IS_WORD,
+ STR_IS_XDIGIT
};
static const char *const isOptions[] = {
"-strict", "-failindex", NULL
@@ -1513,7 +1542,8 @@ StringIsCmd(
case STR_IS_BOOL:
case STR_IS_TRUE:
case STR_IS_FALSE:
- if (TCL_OK != Tcl_ConvertToType(NULL, objPtr, &tclBooleanType)) {
+ if ((objPtr->typePtr != &tclBooleanType)
+ && (TCL_OK != TclSetBooleanFromAny(NULL, objPtr))) {
if (strict) {
result = 0;
} else {
@@ -1537,7 +1567,7 @@ StringIsCmd(
/* TODO */
if ((objPtr->typePtr == &tclDoubleType) ||
(objPtr->typePtr == &tclIntType) ||
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
(objPtr->typePtr == &tclWideIntType) ||
#endif
(objPtr->typePtr == &tclBignumType)) {
@@ -1572,6 +1602,51 @@ StringIsCmd(
break;
}
goto failedIntParse;
+ case STR_IS_ENTIER:
+ if ((objPtr->typePtr == &tclIntType) ||
+#ifndef TCL_WIDE_INT_IS_LONG
+ (objPtr->typePtr == &tclWideIntType) ||
+#endif
+ (objPtr->typePtr == &tclBignumType)) {
+ break;
+ }
+ string1 = TclGetStringFromObj(objPtr, &length1);
+ if (length1 == 0) {
+ if (strict) {
+ result = 0;
+ }
+ goto str_is_done;
+ }
+ end = string1 + length1;
+ if (TclParseNumber(NULL, objPtr, NULL, NULL, -1,
+ (const char **) &stop, TCL_PARSE_INTEGER_ONLY) == TCL_OK) {
+ if (stop == end) {
+ /*
+ * Entire string parses as an integer.
+ */
+
+ break;
+ } else {
+ /*
+ * Some prefix parsed as an integer, but not the whole string,
+ * so return failure index as the point where parsing stopped.
+ * Clear out the internal rep, since keeping it would leave
+ * *objPtr in an inconsistent state.
+ */
+
+ result = 0;
+ failat = stop - string1;
+ TclFreeIntRep(objPtr);
+ }
+ } else {
+ /*
+ * No prefix is a valid integer. Fail at beginning.
+ */
+
+ result = 0;
+ failat = 0;
+ }
+ break;
case STR_IS_WIDE:
if (TCL_OK == Tcl_GetWideIntFromObj(NULL, objPtr, &w)) {
break;
@@ -1790,8 +1865,8 @@ StringMapCmd(
strncmp(string, "-nocase", (size_t) length2) == 0) {
nocase = 1;
} else {
- Tcl_AppendResult(interp, "bad option \"", string,
- "\": must be -nocase", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad option \"%s\": must be -nocase", string));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
string, NULL);
return TCL_ERROR;
@@ -2057,8 +2132,8 @@ StringMatchCmd(
strncmp(string, "-nocase", (size_t) length) == 0) {
nocase = TCL_MATCH_NOCASE;
} else {
- Tcl_AppendResult(interp, "bad option \"", string,
- "\": must be -nocase", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad option \"%s\": must be -nocase", string));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
string, NULL);
return TCL_ERROR;
@@ -2518,8 +2593,9 @@ StringEqualCmd(
return TCL_ERROR;
}
} else {
- Tcl_AppendResult(interp, "bad option \"", string2,
- "\": must be -nocase or -length", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad option \"%s\": must be -nocase or -length",
+ string2));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
string2, NULL);
return TCL_ERROR;
@@ -2667,8 +2743,9 @@ StringCmpCmd(
return TCL_ERROR;
}
} else {
- Tcl_AppendResult(interp, "bad option \"", string2,
- "\": must be -nocase or -length", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad option \"%s\": must be -nocase or -length",
+ string2));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
string2, NULL);
return TCL_ERROR;
@@ -3114,8 +3191,8 @@ StringTrimCmd(
if (objc == 3) {
string2 = TclGetStringFromObj(objv[2], &length2);
} else if (objc == 2) {
- string2 = DEFAULT_TRIM_SET;
- length2 = strlen(DEFAULT_TRIM_SET);
+ string2 = tclDefaultTrimSet;
+ length2 = strlen(tclDefaultTrimSet);
} else {
Tcl_WrongNumArgs(interp, 1, objv, "string ?chars?");
return TCL_ERROR;
@@ -3162,8 +3239,8 @@ StringTrimLCmd(
if (objc == 3) {
string2 = TclGetStringFromObj(objv[2], &length2);
} else if (objc == 2) {
- string2 = DEFAULT_TRIM_SET;
- length2 = strlen(DEFAULT_TRIM_SET);
+ string2 = tclDefaultTrimSet;
+ length2 = strlen(tclDefaultTrimSet);
} else {
Tcl_WrongNumArgs(interp, 1, objv, "string ?chars?");
return TCL_ERROR;
@@ -3208,8 +3285,8 @@ StringTrimRCmd(
if (objc == 3) {
string2 = TclGetStringFromObj(objv[2], &length2);
} else if (objc == 2) {
- string2 = DEFAULT_TRIM_SET;
- length2 = strlen(DEFAULT_TRIM_SET);
+ string2 = tclDefaultTrimSet;
+ length2 = strlen(tclDefaultTrimSet);
} else {
Tcl_WrongNumArgs(interp, 1, objv, "string ?chars?");
return TCL_ERROR;
@@ -3250,28 +3327,28 @@ TclInitStringCmd(
Tcl_Interp *interp) /* Current interpreter. */
{
static const EnsembleImplMap stringImplMap[] = {
- {"bytelength", StringBytesCmd, NULL, NULL, NULL, 0},
+ {"bytelength", StringBytesCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"compare", StringCmpCmd, TclCompileStringCmpCmd, NULL, NULL, 0},
{"equal", StringEqualCmd, TclCompileStringEqualCmd, NULL, NULL, 0},
- {"first", StringFirstCmd, NULL, NULL, NULL, 0},
+ {"first", StringFirstCmd, TclCompileStringFirstCmd, NULL, NULL, 0},
{"index", StringIndexCmd, TclCompileStringIndexCmd, NULL, NULL, 0},
- {"is", StringIsCmd, NULL, NULL, NULL, 0},
- {"last", StringLastCmd, NULL, NULL, NULL, 0},
+ {"is", StringIsCmd, TclCompileStringIsCmd, NULL, NULL, 0},
+ {"last", StringLastCmd, TclCompileStringLastCmd, NULL, NULL, 0},
{"length", StringLenCmd, TclCompileStringLenCmd, NULL, NULL, 0},
- {"map", StringMapCmd, NULL, NULL, NULL, 0},
+ {"map", StringMapCmd, TclCompileStringMapCmd, NULL, NULL, 0},
{"match", StringMatchCmd, TclCompileStringMatchCmd, NULL, NULL, 0},
- {"range", StringRangeCmd, NULL, NULL, NULL, 0},
- {"repeat", StringReptCmd, NULL, NULL, NULL, 0},
- {"replace", StringRplcCmd, NULL, NULL, NULL, 0},
- {"reverse", StringRevCmd, NULL, NULL, NULL, 0},
- {"tolower", StringLowerCmd, NULL, NULL, NULL, 0},
- {"toupper", StringUpperCmd, NULL, NULL, NULL, 0},
- {"totitle", StringTitleCmd, NULL, NULL, NULL, 0},
- {"trim", StringTrimCmd, NULL, NULL, NULL, 0},
- {"trimleft", StringTrimLCmd, NULL, NULL, NULL, 0},
- {"trimright", StringTrimRCmd, NULL, NULL, NULL, 0},
- {"wordend", StringEndCmd, NULL, NULL, NULL, 0},
- {"wordstart", StringStartCmd, NULL, NULL, NULL, 0},
+ {"range", StringRangeCmd, TclCompileStringRangeCmd, NULL, NULL, 0},
+ {"repeat", StringReptCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"replace", StringRplcCmd, TclCompileStringReplaceCmd, NULL, NULL, 0},
+ {"reverse", StringRevCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"tolower", StringLowerCmd, TclCompileStringToLowerCmd, NULL, NULL, 0},
+ {"toupper", StringUpperCmd, TclCompileStringToUpperCmd, NULL, NULL, 0},
+ {"totitle", StringTitleCmd, TclCompileStringToTitleCmd, NULL, NULL, 0},
+ {"trim", StringTrimCmd, TclCompileStringTrimCmd, NULL, NULL, 0},
+ {"trimleft", StringTrimLCmd, TclCompileStringTrimLCmd, NULL, NULL, 0},
+ {"trimright", StringTrimRCmd, TclCompileStringTrimRCmd, NULL, NULL, 0},
+ {"wordend", StringEndCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"wordstart", StringStartCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
};
@@ -3452,7 +3529,7 @@ TclNRSwitchObjCmd(
i++;
goto finishedOptions;
case OPT_NOCASE:
- strCmpFn = strcasecmp;
+ strCmpFn = TclUtfCasecmp;
noCase = 1;
break;
@@ -3466,9 +3543,9 @@ TclNRSwitchObjCmd(
* Mode already set via -exact, -glob, or -regexp.
*/
- Tcl_AppendResult(interp, "bad option \"",
- TclGetString(objv[i]), "\": ", options[mode],
- " option already found", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad option \"%s\": %s option already found",
+ TclGetString(objv[i]), options[mode]));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
"DOUBLEOPT", NULL);
return TCL_ERROR;
@@ -3485,8 +3562,9 @@ TclNRSwitchObjCmd(
case OPT_INDEXV:
i++;
if (i >= objc-2) {
- Tcl_AppendResult(interp, "missing variable name argument to ",
- "-indexvar", " option", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "missing variable name argument to %s option",
+ "-indexvar"));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
"NOVAR", NULL);
return TCL_ERROR;
@@ -3497,8 +3575,9 @@ TclNRSwitchObjCmd(
case OPT_MATCHV:
i++;
if (i >= objc-2) {
- Tcl_AppendResult(interp, "missing variable name argument to ",
- "-matchvar", " option", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "missing variable name argument to %s option",
+ "-matchvar"));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
"NOVAR", NULL);
return TCL_ERROR;
@@ -3516,15 +3595,15 @@ TclNRSwitchObjCmd(
return TCL_ERROR;
}
if (indexVarObj != NULL && mode != OPT_REGEXP) {
- Tcl_AppendResult(interp,
- "-indexvar option requires -regexp option", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "%s option requires -regexp option", "-indexvar"));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
"MODERESTRICTION", NULL);
return TCL_ERROR;
}
if (matchVarObj != NULL && mode != OPT_REGEXP) {
- Tcl_AppendResult(interp,
- "-matchvar option requires -regexp option", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "%s option requires -regexp option", "-matchvar"));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
"MODERESTRICTION", NULL);
return TCL_ERROR;
@@ -3573,7 +3652,8 @@ TclNRSwitchObjCmd(
if (objc % 2) {
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "extra switch pattern with no body", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "extra switch pattern with no body", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "BADARM",
NULL);
@@ -3588,10 +3668,10 @@ TclNRSwitchObjCmd(
if (splitObjs) {
for (i=0 ; i<objc ; i+=2) {
if (TclGetString(objv[i])[0] == '#') {
- Tcl_AppendResult(interp, ", this may be due to a "
- "comment incorrectly placed outside of a "
- "switch body - see the \"switch\" "
- "documentation", NULL);
+ Tcl_AppendToObj(Tcl_GetObjResult(interp),
+ ", this may be due to a comment incorrectly"
+ " placed outside of a switch body - see the"
+ " \"switch\" documentation", -1);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
"BADARM", "COMMENT?", NULL);
break;
@@ -3608,9 +3688,9 @@ TclNRSwitchObjCmd(
*/
if (strcmp(TclGetString(objv[objc-1]), "-") == 0) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "no body specified for pattern \"",
- TclGetString(objv[objc-2]), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "no body specified for pattern \"%s\"",
+ TclGetString(objv[objc-2])));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "BADARM",
"FALLTHROUGH", NULL);
return TCL_ERROR;
@@ -3709,8 +3789,12 @@ TclNRSwitchObjCmd(
if (indexVarObj != NULL) {
Tcl_Obj *rangeObjAry[2];
- rangeObjAry[0] = Tcl_NewLongObj(info.matches[j].start);
- rangeObjAry[1] = Tcl_NewLongObj(info.matches[j].end);
+ if (info.matches[j].end > 0) {
+ rangeObjAry[0] = Tcl_NewLongObj(info.matches[j].start);
+ rangeObjAry[1] = Tcl_NewLongObj(info.matches[j].end-1);
+ } else {
+ rangeObjAry[0] = rangeObjAry[1] = Tcl_NewIntObj(-1);
+ }
/*
* Never fails; the object is always clean at this point.
@@ -3932,7 +4016,8 @@ Tcl_ThrowObjCmd(
if (Tcl_ListObjLength(interp, objv[1], &len) != TCL_OK) {
return TCL_ERROR;
} else if (len < 1) {
- Tcl_AppendResult(interp, "type must be non-empty list", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "type must be non-empty list", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "THROW", "BADEXCEPTION",
NULL);
return TCL_ERROR;
@@ -4116,15 +4201,16 @@ TclNRTryObjCmd(
switch ((enum Handlers) type) {
case TryFinally: /* finally script */
if (i < objc-2) {
- Tcl_AppendResult(interp, "finally clause must be last", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "finally clause must be last", -1));
Tcl_DecrRefCount(handlersObj);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "FINALLY",
"NONTERMINAL", NULL);
return TCL_ERROR;
} else if (i == objc-1) {
- Tcl_AppendResult(interp, "wrong # args to finally clause: ",
- "must be \"", TclGetString(objv[0]),
- " ... finally script\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "wrong # args to finally clause: must be"
+ " \"... finally script\"", -1));
Tcl_DecrRefCount(handlersObj);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "FINALLY",
"ARGUMENT", NULL);
@@ -4135,15 +4221,16 @@ TclNRTryObjCmd(
case TryOn: /* on code variableList script */
if (i > objc-4) {
- Tcl_AppendResult(interp, "wrong # args to on clause: ",
- "must be \"", TclGetString(objv[0]),
- " ... on code variableList script\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "wrong # args to on clause: must be \"... on code"
+ " variableList script\"", -1));
Tcl_DecrRefCount(handlersObj);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "ON",
"ARGUMENT", NULL);
return TCL_ERROR;
}
- if (TCL_ERROR == TclGetCompletionCodeFromObj(interp, objv[i+1], &code)) {
+ if (TclGetCompletionCodeFromObj(interp, objv[i+1],
+ &code) != TCL_OK) {
Tcl_DecrRefCount(handlersObj);
return TCL_ERROR;
}
@@ -4152,9 +4239,10 @@ TclNRTryObjCmd(
case TryTrap: /* trap pattern variableList script */
if (i > objc-4) {
- Tcl_AppendResult(interp, "wrong # args to trap clause: ",
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "wrong # args to trap clause: "
"must be \"... trap pattern variableList script\"",
- NULL);
+ -1));
Tcl_DecrRefCount(handlersObj);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "TRAP",
"ARGUMENT", NULL);
@@ -4195,9 +4283,8 @@ TclNRTryObjCmd(
}
}
if (bodyShared) {
- Tcl_AppendResult(interp,
- "last non-finally clause must not have a body of \"-\"",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "last non-finally clause must not have a body of \"-\"", -1));
Tcl_DecrRefCount(handlersObj);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "BADFALLTHROUGH",
NULL);
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index 66c03ab..d1d7a80 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.c
@@ -7,7 +7,7 @@
* Copyright (c) 1997-1998 Sun Microsystems, Inc.
* Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
* Copyright (c) 2002 ActiveState Corporation.
- * Copyright (c) 2004-2006 by Donal K. Fellows.
+ * Copyright (c) 2004-2013 by Donal K. Fellows.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -15,6 +15,7 @@
#include "tclInt.h"
#include "tclCompile.h"
+#include <assert.h>
/*
* Prototypes for procedures defined later in this file:
@@ -30,63 +31,15 @@ static void FreeForeachInfo(ClientData clientData);
static void PrintForeachInfo(ClientData clientData,
Tcl_Obj *appendObj, ByteCode *codePtr,
unsigned int pcOffset);
-static void CompileReturnInternal(CompileEnv *envPtr,
- unsigned char op, int code, int level,
- Tcl_Obj *returnOpts);
-static int IndexTailVarIfKnown(Tcl_Interp *interp,
- Tcl_Token *varTokenPtr, CompileEnv *envPtr);
-static int PushVarName(Tcl_Interp *interp,
- Tcl_Token *varTokenPtr, CompileEnv *envPtr,
- int flags, int *localIndexPtr,
- int *simpleVarNamePtr, int *isScalarPtr,
- int line, int *clNext);
-
-/*
- * Macro that encapsulates an efficiency trick that avoids a function call for
- * the simplest of compiles. The ANSI C "prototype" for this macro is:
- *
- * static void CompileWord(CompileEnv *envPtr, Tcl_Token *tokenPtr,
- * Tcl_Interp *interp, int word);
- */
-
-#define CompileWord(envPtr, tokenPtr, interp, word) \
- if ((tokenPtr)->type == TCL_TOKEN_SIMPLE_WORD) { \
- TclEmitPush(TclRegisterNewLiteral((envPtr), (tokenPtr)[1].start, \
- (tokenPtr)[1].size), (envPtr)); \
- } else { \
- envPtr->line = mapPtr->loc[eclIndex].line[word]; \
- envPtr->clNext = mapPtr->loc[eclIndex].next[word]; \
- TclCompileTokens((interp), (tokenPtr)+1, (tokenPtr)->numComponents, \
- (envPtr)); \
- }
-
-/*
- * TIP #280: Remember the per-word line information of the current command. An
- * index is used instead of a pointer as recursive compilation may reallocate,
- * i.e. move, the array. This is also the reason to save the nuloc now, it may
- * change during the course of the function.
- *
- * Macro to encapsulate the variable definition and setup.
- */
-
-#define DefineLineInformation \
- ExtCmdLoc *mapPtr = envPtr->extCmdMapPtr; \
- int eclIndex = mapPtr->nuloc - 1
-
-#define SetLineInformation(word) \
- envPtr->line = mapPtr->loc[eclIndex].line[(word)]; \
- envPtr->clNext = mapPtr->loc[eclIndex].next[(word)]
-
-#define PushVarNameWord(i,v,e,f,l,s,sc,word) \
- PushVarName(i,v,e,f,l,s,sc, \
- mapPtr->loc[eclIndex].line[(word)], \
- mapPtr->loc[eclIndex].next[(word)])
-
-/*
- * Flags bits used by PushVarName.
- */
-
-#define TCL_NO_LARGE_INDEX 1 /* Do not return localIndex value > 255 */
+static void PrintNewForeachInfo(ClientData clientData,
+ Tcl_Obj *appendObj, ByteCode *codePtr,
+ unsigned int pcOffset);
+static int CompileEachloopCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ CompileEnv *envPtr, int collect);
+static int CompileDictEachCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr, int collect);
/*
* The structures below define the AuxData types defined in this file.
@@ -99,6 +52,13 @@ const AuxDataType tclForeachInfoType = {
PrintForeachInfo /* printProc */
};
+const AuxDataType tclNewForeachInfoType = {
+ "NewForeachInfo", /* name */
+ DupForeachInfo, /* dupProc */
+ FreeForeachInfo, /* freeProc */
+ PrintNewForeachInfo /* printProc */
+};
+
const AuxDataType tclDictUpdateInfoType = {
"DictUpdateInfo", /* name */
DupDictUpdateInfo, /* dupProc */
@@ -134,9 +94,10 @@ TclCompileAppendCmd(
CompileEnv *envPtr) /* Holds resulting instructions. */
{
Tcl_Token *varTokenPtr, *valueTokenPtr;
- int simpleVarName, isScalar, localIndex, numWords;
+ int isScalar, localIndex, numWords, i;
DefineLineInformation; /* TIP #280 */
+ /* TODO: Consider support for compiling expanded args. */
numWords = parsePtr->numWords;
if (numWords == 1) {
return TCL_ERROR;
@@ -148,10 +109,11 @@ TclCompileAppendCmd(
return TclCompileSetCmd(interp, parsePtr, cmdPtr, envPtr);
} else if (numWords > 3) {
/*
- * APPEND instructions currently only handle one value.
+ * APPEND instructions currently only handle one value, but we can
+ * handle some multi-value cases by stringing them together.
*/
- return TCL_ERROR;
+ goto appendMultiple;
}
/*
@@ -165,7 +127,7 @@ TclCompileAppendCmd(
varTokenPtr = TokenAfter(parsePtr->tokenPtr);
PushVarNameWord(interp, varTokenPtr, envPtr, 0,
- &localIndex, &simpleVarName, &isScalar, 1);
+ &localIndex, &isScalar, 1);
/*
* We are doing an assignment, otherwise TclCompileSetCmd was called, so
@@ -173,37 +135,311 @@ TclCompileAppendCmd(
* each argument.
*/
- if (numWords > 2) {
valueTokenPtr = TokenAfter(varTokenPtr);
CompileWord(envPtr, valueTokenPtr, interp, 2);
- }
/*
* Emit instructions to set/get the variable.
*/
- if (simpleVarName) {
if (isScalar) {
if (localIndex < 0) {
TclEmitOpcode(INST_APPEND_STK, envPtr);
- } else if (localIndex <= 255) {
- TclEmitInstInt1(INST_APPEND_SCALAR1, localIndex, envPtr);
} else {
- TclEmitInstInt4(INST_APPEND_SCALAR4, localIndex, envPtr);
+ Emit14Inst(INST_APPEND_SCALAR, localIndex, envPtr);
}
} else {
if (localIndex < 0) {
TclEmitOpcode(INST_APPEND_ARRAY_STK, envPtr);
- } else if (localIndex <= 255) {
- TclEmitInstInt1(INST_APPEND_ARRAY1, localIndex, envPtr);
} else {
- TclEmitInstInt4(INST_APPEND_ARRAY4, localIndex, envPtr);
+ Emit14Inst(INST_APPEND_ARRAY, localIndex, envPtr);
}
}
+
+ return TCL_OK;
+
+ appendMultiple:
+ /*
+ * Can only handle the case where we are appending to a local scalar when
+ * there are multiple values to append. Fortunately, this is common.
+ */
+
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_ELEMENT,
+ &localIndex, &isScalar, 1);
+ if (!isScalar || localIndex < 0) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Definitely appending to a local scalar; generate the words and append
+ * them.
+ */
+
+ valueTokenPtr = TokenAfter(varTokenPtr);
+ for (i = 2 ; i < numWords ; i++) {
+ CompileWord(envPtr, valueTokenPtr, interp, i);
+ valueTokenPtr = TokenAfter(valueTokenPtr);
+ }
+ TclEmitInstInt4( INST_REVERSE, numWords-2, envPtr);
+ for (i = 2 ; i < numWords ;) {
+ Emit14Inst( INST_APPEND_SCALAR, localIndex, envPtr);
+ if (++i < numWords) {
+ TclEmitOpcode(INST_POP, envPtr);
+ }
+ }
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileArray*Cmd --
+ *
+ * Functions called to compile "array" sucommands.
+ *
+ * Results:
+ * All return TCL_OK for a successful compile, and TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "array" subcommand at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileArrayExistsCmd(
+ Tcl_Interp *interp, /* Used for looking up stuff. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr;
+ int isScalar, localIndex;
+
+ if (parsePtr->numWords != 2) {
+ return TCL_ERROR;
+ }
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ PushVarNameWord(interp, tokenPtr, envPtr, TCL_NO_ELEMENT,
+ &localIndex, &isScalar, 1);
+ if (!isScalar) {
+ return TCL_ERROR;
+ }
+
+ if (localIndex >= 0) {
+ TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex, envPtr);
} else {
- TclEmitOpcode(INST_APPEND_STK, envPtr);
+ TclEmitOpcode( INST_ARRAY_EXISTS_STK, envPtr);
+ }
+ return TCL_OK;
+}
+
+int
+TclCompileArraySetCmd(
+ Tcl_Interp *interp, /* Used for looking up stuff. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *varTokenPtr, *dataTokenPtr;
+ int isScalar, localIndex, code = TCL_OK;
+ int isDataLiteral, isDataValid, isDataEven, len;
+ int keyVar, valVar, infoIndex;
+ int fwd, offsetBack, offsetFwd;
+ Tcl_Obj *literalObj;
+ ForeachInfo *infoPtr;
+
+ if (parsePtr->numWords != 3) {
+ return TCL_ERROR;
+ }
+
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ dataTokenPtr = TokenAfter(varTokenPtr);
+ literalObj = Tcl_NewObj();
+ isDataLiteral = TclWordKnownAtCompileTime(dataTokenPtr, literalObj);
+ isDataValid = (isDataLiteral
+ && Tcl_ListObjLength(NULL, literalObj, &len) == TCL_OK);
+ isDataEven = (isDataValid && (len & 1) == 0);
+
+ /*
+ * Special case: literal odd-length argument is always an error.
+ */
+
+ if (isDataValid && !isDataEven) {
+ 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;
+ }
+
+ /*
+ * Except for the special "ensure array" case below, when we're not in
+ * a proc, we cannot do a better compile than generic.
+ */
+
+ if (envPtr->procPtr == NULL && !(isDataEven && len == 0)) {
+ code = TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ goto done;
+ }
+
+ PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_ELEMENT,
+ &localIndex, &isScalar, 1);
+ if (!isScalar) {
+ code = TCL_ERROR;
+ goto done;
+ }
+
+ /*
+ * Special case: literal empty value argument is just an "ensure array"
+ * operation.
+ */
+
+ if (isDataEven && len == 0) {
+ if (localIndex >= 0) {
+ TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex, envPtr);
+ TclEmitInstInt1(INST_JUMP_TRUE1, 7, envPtr);
+ TclEmitInstInt4(INST_ARRAY_MAKE_IMM, localIndex, envPtr);
+ } else {
+ TclEmitOpcode( INST_DUP, envPtr);
+ TclEmitOpcode( INST_ARRAY_EXISTS_STK, envPtr);
+ TclEmitInstInt1(INST_JUMP_TRUE1, 5, envPtr);
+ TclEmitOpcode( INST_ARRAY_MAKE_STK, envPtr);
+ TclEmitInstInt1(INST_JUMP1, 3, envPtr);
+ /* Each branch decrements stack depth, but we only take one. */
+ TclAdjustStackDepth(1, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ }
+ PushStringLiteral(envPtr, "");
+ goto done;
+ }
+
+ if (localIndex < 0) {
+ /*
+ * a non-local variable: upvar from a local one! This consumes the
+ * variable name that was left at stacktop.
+ */
+
+ localIndex = AnonymousLocal(envPtr);
+ PushStringLiteral(envPtr, "0");
+ TclEmitInstInt4(INST_REVERSE, 2, envPtr);
+ TclEmitInstInt4(INST_UPVAR, localIndex, envPtr);
+ TclEmitOpcode(INST_POP, envPtr);
+ }
+
+ /*
+ * Prepare for the internal foreach.
+ */
+
+ keyVar = AnonymousLocal(envPtr);
+ valVar = AnonymousLocal(envPtr);
+
+ infoPtr = ckalloc(sizeof(ForeachInfo));
+ infoPtr->numLists = 1;
+ infoPtr->varLists[0] = ckalloc(sizeof(ForeachVarList) + sizeof(int));
+ infoPtr->varLists[0]->numVars = 2;
+ infoPtr->varLists[0]->varIndexes[0] = keyVar;
+ infoPtr->varLists[0]->varIndexes[1] = valVar;
+ infoIndex = TclCreateAuxData(infoPtr, &tclForeachInfoType, envPtr);
+
+ /*
+ * Start issuing instructions to write to the array.
+ */
+
+ CompileWord(envPtr, dataTokenPtr, interp, 2);
+ if (!isDataLiteral || !isDataValid) {
+ /*
+ * Only need this safety check if we're handling a non-literal or list
+ * containing an invalid literal; with valid list literals, we've
+ * already checked (worth it because literals are a very common
+ * use-case with [array set]).
+ */
+
+ TclEmitOpcode( INST_DUP, envPtr);
+ TclEmitOpcode( INST_LIST_LENGTH, envPtr);
+ PushStringLiteral(envPtr, "1");
+ TclEmitOpcode( INST_BITAND, envPtr);
+ offsetFwd = CurrentOffset(envPtr);
+ TclEmitInstInt1(INST_JUMP_FALSE1, 0, envPtr);
+ 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);
+ TclAdjustStackDepth(-1, envPtr);
+ fwd = CurrentOffset(envPtr) - offsetFwd;
+ 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);
+ Emit14Inst( INST_LOAD_SCALAR, valVar, envPtr);
+ Emit14Inst( INST_STORE_ARRAY, localIndex, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ infoPtr->loopCtTemp = offsetBack - CurrentOffset(envPtr); /*misuse */
+ TclEmitOpcode( INST_FOREACH_STEP, envPtr);
+ TclEmitOpcode( INST_FOREACH_END, envPtr);
+ TclAdjustStackDepth(-3, envPtr);
+ PushStringLiteral(envPtr, "");
+
+ done:
+ Tcl_DecrRefCount(literalObj);
+ return code;
+}
+
+int
+TclCompileArrayUnsetCmd(
+ Tcl_Interp *interp, /* Used for looking up stuff. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ int isScalar, localIndex;
+
+ if (parsePtr->numWords != 2) {
+ return TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
}
+ PushVarNameWord(interp, tokenPtr, envPtr, TCL_NO_ELEMENT,
+ &localIndex, &isScalar, 1);
+ if (!isScalar) {
+ return TCL_ERROR;
+ }
+
+ if (localIndex >= 0) {
+ TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex, envPtr);
+ TclEmitInstInt1(INST_JUMP_FALSE1, 8, envPtr);
+ TclEmitInstInt1(INST_UNSET_SCALAR, 1, envPtr);
+ TclEmitInt4( localIndex, envPtr);
+ } else {
+ TclEmitOpcode( INST_DUP, envPtr);
+ TclEmitOpcode( INST_ARRAY_EXISTS_STK, envPtr);
+ TclEmitInstInt1(INST_JUMP_FALSE1, 6, envPtr);
+ TclEmitInstInt1(INST_UNSET_STK, 1, envPtr);
+ TclEmitInstInt1(INST_JUMP1, 3, envPtr);
+ /* Each branch decrements stack depth, but we only take one. */
+ TclAdjustStackDepth(1, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ }
+ PushStringLiteral(envPtr, "");
return TCL_OK;
}
@@ -234,15 +470,34 @@ TclCompileBreakCmd(
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
+ ExceptionRange *rangePtr;
+ ExceptionAux *auxPtr;
+
if (parsePtr->numWords != 1) {
return TCL_ERROR;
}
/*
- * Emit a break instruction.
+ * Find the innermost exception range that contains this command.
*/
- TclEmitOpcode(INST_BREAK, envPtr);
+ rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_BREAK, &auxPtr);
+ if (rangePtr && rangePtr->type == LOOP_EXCEPTION_RANGE) {
+ /*
+ * Found the target! No need for a nasty INST_BREAK here.
+ */
+
+ TclCleanupStackForBreakContinue(envPtr, auxPtr);
+ TclAddLoopBreakFixup(envPtr, auxPtr);
+ } else {
+ /*
+ * Emit a real break.
+ */
+
+ TclEmitOpcode(INST_BREAK, envPtr);
+ }
+ TclAdjustStackDepth(1, envPtr);
+
return TCL_OK;
}
@@ -275,12 +530,10 @@ TclCompileCatchCmd(
{
JumpFixup jumpFixup;
Tcl_Token *cmdTokenPtr, *resultNameTokenPtr, *optsNameTokenPtr;
- const char *name;
- int resultIndex, optsIndex, nameChars, range;
- int initStackDepth = envPtr->currStackDepth;
- int savedStackDepth;
+ int resultIndex, optsIndex, range, dropScript = 0;
DefineLineInformation; /* TIP #280 */
-
+ int depth = TclGetStackDepth(envPtr);
+
/*
* If syntax does not match what we expect for [catch], do not compile.
* Let runtime checks determine if syntax has changed.
@@ -309,17 +562,7 @@ TclCompileCatchCmd(
if (parsePtr->numWords >= 3) {
resultNameTokenPtr = TokenAfter(cmdTokenPtr);
/* DGP */
- if (resultNameTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_ERROR;
- }
-
- name = resultNameTokenPtr[1].start;
- nameChars = resultNameTokenPtr[1].size;
- if (!TclIsLocalScalar(name, nameChars)) {
- return TCL_ERROR;
- }
- resultIndex = TclFindCompiledLocal(resultNameTokenPtr[1].start,
- resultNameTokenPtr[1].size, /*create*/ 1, envPtr);
+ resultIndex = LocalScalarFromToken(resultNameTokenPtr, envPtr);
if (resultIndex < 0) {
return TCL_ERROR;
}
@@ -327,16 +570,7 @@ TclCompileCatchCmd(
/* DKF */
if (parsePtr->numWords == 4) {
optsNameTokenPtr = TokenAfter(resultNameTokenPtr);
- if (optsNameTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_ERROR;
- }
- name = optsNameTokenPtr[1].start;
- nameChars = optsNameTokenPtr[1].size;
- if (!TclIsLocalScalar(name, nameChars)) {
- return TCL_ERROR;
- }
- optsIndex = TclFindCompiledLocal(optsNameTokenPtr[1].start,
- optsNameTokenPtr[1].size, /*create*/ 1, envPtr);
+ optsIndex = LocalScalarFromToken(optsNameTokenPtr, envPtr);
if (optsIndex < 0) {
return TCL_ERROR;
}
@@ -344,148 +578,199 @@ TclCompileCatchCmd(
}
/*
- * We will compile the catch command. Declare the exception range
- * that it uses.
- */
-
- range = DeclareExceptionRange(envPtr, CATCH_EXCEPTION_RANGE);
-
- /*
+ * We will compile the catch command. Declare the exception range that it
+ * uses.
+ *
* If the body is a simple word, compile a BEGIN_CATCH instruction,
* followed by the instructions to eval the body.
* Otherwise, compile instructions to substitute the body text before
- * starting the catch, then BEGIN_CATCH, and then EVAL_STK to
- * evaluate the substituted body.
- * Care has to be taken to make sure that substitution happens outside
- * the catch range so that errors in the substitution are not caught.
+ * starting the catch, then BEGIN_CATCH, and then EVAL_STK to evaluate the
+ * substituted body.
+ * Care has to be taken to make sure that substitution happens outside the
+ * catch range so that errors in the substitution are not caught.
* [Bug 219184]
* The reason for duplicating the script is that EVAL_STK would otherwise
* begin by undeflowing the stack below the mark set by BEGIN_CATCH4.
*/
- SetLineInformation(1);
+ range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
if (cmdTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- savedStackDepth = envPtr->currStackDepth;
- TclEmitInstInt4(INST_BEGIN_CATCH4, range, envPtr);
+ TclEmitInstInt4( INST_BEGIN_CATCH4, range, envPtr);
ExceptionRangeStarts(envPtr, range);
- CompileBody(envPtr, cmdTokenPtr, interp);
+ BODY(cmdTokenPtr, 1);
} else {
+ SetLineInformation(1);
CompileTokens(envPtr, cmdTokenPtr, interp);
- savedStackDepth = envPtr->currStackDepth;
- TclEmitInstInt4(INST_BEGIN_CATCH4, range, envPtr);
+ TclEmitInstInt4( INST_BEGIN_CATCH4, range, envPtr);
ExceptionRangeStarts(envPtr, range);
- TclEmitOpcode(INST_DUP, envPtr);
- TclEmitOpcode(INST_EVAL_STK, envPtr);
+ TclEmitOpcode( INST_DUP, envPtr);
+ TclEmitInvoke(envPtr, INST_EVAL_STK);
+ /* drop the script */
+ dropScript = 1;
+ TclEmitInstInt4( INST_REVERSE, 2, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
}
- /* Stack at this point:
- * nonsimple: script <mark> result
- * simple: <mark> result
- */
+ ExceptionRangeEnds(envPtr, range);
+
/*
- * Emit the "no errors" epilogue: push "0" (TCL_OK) as the catch
- * result, and jump around the "error case" code.
+ * Emit the "no errors" epilogue: push "0" (TCL_OK) as the catch result,
+ * and jump around the "error case" code.
*/
- PushLiteral(envPtr, "0", 1);
+ TclCheckStackDepth(depth+1, envPtr);
+ PushStringLiteral(envPtr, "0");
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);
- /* Stack at this point: ?script? <mark> result TCL_OK */
/*
- * Emit the "error case" epilogue. Push the interpreter result
- * and the return code.
+ * Emit the "error case" epilogue. Push the interpreter result and the
+ * return code.
*/
- envPtr->currStackDepth = savedStackDepth;
ExceptionRangeTarget(envPtr, range, catchOffset);
- /* Stack at this point: ?script? */
- TclEmitOpcode(INST_PUSH_RESULT, envPtr);
- TclEmitOpcode(INST_PUSH_RETURN_CODE, envPtr);
+ TclSetStackDepth(depth + dropScript, envPtr);
+
+ if (dropScript) {
+ TclEmitOpcode( INST_POP, envPtr);
+ }
- /*
- * Update the target of the jump after the "no errors" code.
- */
- /* Stack at this point: ?script? result returnCode */
+ /* Stack at this point is empty */
+ TclEmitOpcode( INST_PUSH_RESULT, envPtr);
+ TclEmitOpcode( INST_PUSH_RETURN_CODE, envPtr);
+
+ /* Stack at this point on both branches: result returnCode */
+
if (TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127)) {
Tcl_Panic("TclCompileCatchCmd: bad jump distance %d",
(int)(CurrentOffset(envPtr) - jumpFixup.codeOffset));
}
- /* Push the return options if the caller wants them */
+ /*
+ * Push the return options if the caller wants them. This needs to happen
+ * before INST_END_CATCH
+ */
if (optsIndex != -1) {
- TclEmitOpcode(INST_PUSH_RETURN_OPTIONS, envPtr);
+ TclEmitOpcode( INST_PUSH_RETURN_OPTIONS, envPtr);
}
/*
* End the catch
*/
- ExceptionRangeEnds(envPtr, range);
- TclEmitOpcode(INST_END_CATCH, envPtr);
+ TclEmitOpcode( INST_END_CATCH, envPtr);
/*
- * At this point, the top of the stack is inconveniently ordered:
- * ?script? result returnCode ?returnOptions?
- * Reverse the stack to bring the result to the top.
+ * Save the result and return options if the caller wants them. This needs
+ * to happen after INST_END_CATCH (compile-3.6/7).
*/
if (optsIndex != -1) {
- TclEmitInstInt4(INST_REVERSE, 3, envPtr);
- } else {
- TclEmitInstInt4(INST_REVERSE, 2, envPtr);
+ Emit14Inst( INST_STORE_SCALAR, optsIndex, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
}
/*
- * Store the result if requested, and remove it from the stack
+ * At this point, the top of the stack is inconveniently ordered:
+ * result returnCode
+ * Reverse the stack to store the result.
*/
+ TclEmitInstInt4( INST_REVERSE, 2, envPtr);
if (resultIndex != -1) {
- if (resultIndex <= 255) {
- TclEmitInstInt1(INST_STORE_SCALAR1, resultIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_STORE_SCALAR4, resultIndex, envPtr);
- }
+ Emit14Inst( INST_STORE_SCALAR, resultIndex, envPtr);
+ }
+ TclEmitOpcode( INST_POP, envPtr);
+
+ TclCheckStackDepth(depth+1, envPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileConcatCmd --
+ *
+ * Procedure called to compile the "concat" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "concat" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileConcatCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Obj *objPtr, *listObj;
+ Tcl_Token *tokenPtr;
+ int i;
+
+ /* TODO: Consider compiling expansion case. */
+ if (parsePtr->numWords == 1) {
+ /*
+ * [concat] without arguments just pushes an empty object.
+ */
+
+ PushStringLiteral(envPtr, "");
+ return TCL_OK;
}
- TclEmitOpcode(INST_POP, envPtr);
/*
- * Stack is now ?script? ?returnOptions? returnCode.
- * If the options dict has been requested, it is buried on the stack
- * under the return code. Reverse the stack to bring it to the top,
- * store it and remove it from the stack.
+ * Test if all arguments are compile-time known. If they are, we can
+ * implement with a simple push.
*/
- if (optsIndex != -1) {
- TclEmitInstInt4(INST_REVERSE, 2, envPtr);
- if (optsIndex <= 255) {
- TclEmitInstInt1(INST_STORE_SCALAR1, optsIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_STORE_SCALAR4, optsIndex, envPtr);
+ listObj = Tcl_NewObj();
+ for (i = 1, tokenPtr = parsePtr->tokenPtr; i < parsePtr->numWords; i++) {
+ tokenPtr = TokenAfter(tokenPtr);
+ objPtr = Tcl_NewObj();
+ if (!TclWordKnownAtCompileTime(tokenPtr, objPtr)) {
+ Tcl_DecrRefCount(objPtr);
+ Tcl_DecrRefCount(listObj);
+ listObj = NULL;
+ break;
}
- TclEmitOpcode(INST_POP, envPtr);
+ (void) Tcl_ListObjAppendElement(NULL, listObj, objPtr);
}
+ if (listObj != NULL) {
+ Tcl_Obj **objs;
+ const char *bytes;
+ int len;
- /*
- * Stack is now ?script? result. Get rid of the subst'ed script
- * if it's hanging arond.
- */
-
- if (cmdTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- TclEmitInstInt4(INST_REVERSE, 2, envPtr);
- TclEmitOpcode(INST_POP, envPtr);
+ Tcl_ListObjGetElements(NULL, listObj, &len, &objs);
+ objPtr = Tcl_ConcatObj(len, objs);
+ Tcl_DecrRefCount(listObj);
+ bytes = Tcl_GetStringFromObj(objPtr, &len);
+ PushLiteral(envPtr, bytes, len);
+ Tcl_DecrRefCount(objPtr);
+ return TCL_OK;
}
- /*
- * Result of all this, on either branch, should have been to leave
- * one operand -- the return code -- on the stack.
+ /*
+ * General case: runtime concat.
*/
- if (envPtr->currStackDepth != initStackDepth + 1) {
- Tcl_Panic("in TclCompileCatchCmd, currStackDepth = %d should be %d",
- envPtr->currStackDepth, initStackDepth+1);
+ for (i = 1, tokenPtr = parsePtr->tokenPtr; i < parsePtr->numWords; i++) {
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, i);
}
+
+ TclEmitInstInt4( INST_CONCAT_STK, i-1, envPtr);
+
return TCL_OK;
}
@@ -516,6 +801,9 @@ TclCompileContinueCmd(
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
+ ExceptionRange *rangePtr;
+ ExceptionAux *auxPtr;
+
/*
* There should be no argument after the "continue".
*/
@@ -525,10 +813,27 @@ TclCompileContinueCmd(
}
/*
- * Emit a continue instruction.
+ * See if we can find a valid continueOffset (i.e., not -1) in the
+ * innermost containing exception range.
*/
- TclEmitOpcode(INST_CONTINUE, envPtr);
+ rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_CONTINUE, &auxPtr);
+ if (rangePtr && rangePtr->type == LOOP_EXCEPTION_RANGE) {
+ /*
+ * Found the target! No need for a nasty INST_CONTINUE here.
+ */
+
+ TclCleanupStackForBreakContinue(envPtr, auxPtr);
+ TclAddLoopContinueFixup(envPtr, auxPtr);
+ } else {
+ /*
+ * Emit a real continue.
+ */
+
+ TclEmitOpcode(INST_CONTINUE, envPtr);
+ }
+ TclAdjustStackDepth(1, envPtr);
+
return TCL_OK;
}
@@ -547,25 +852,6 @@ TclCompileContinueCmd(
* Instructions are added to envPtr to execute the "dict" subcommand at
* runtime.
*
- * Notes:
- * The following commands are in fairly common use and are possibly worth
- * bytecoding:
- * dict append
- * dict create [*]
- * dict exists [*]
- * dict for
- * dict get [*]
- * dict incr
- * dict keys [*]
- * dict lappend
- * dict set
- * dict unset
- *
- * In practice, those that are pure-value operators (marked with [*]) can
- * probably be left alone (except perhaps [dict get] which is very very
- * common) and [dict update] should be considered instead (really big
- * win!)
- *
*----------------------------------------------------------------------
*/
@@ -579,11 +865,9 @@ TclCompileDictSetCmd(
CompileEnv *envPtr) /* Holds resulting instructions. */
{
Tcl_Token *tokenPtr;
- int numWords, i;
+ int i, dictVarIndex;
DefineLineInformation; /* TIP #280 */
Tcl_Token *varTokenPtr;
- int dictVarIndex, nameChars;
- const char *name;
/*
* There must be at least one argument after the command.
@@ -600,15 +884,7 @@ TclCompileDictSetCmd(
*/
varTokenPtr = TokenAfter(parsePtr->tokenPtr);
- if (varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_ERROR;
- }
- name = varTokenPtr[1].start;
- nameChars = varTokenPtr[1].size;
- if (!TclIsLocalScalar(name, nameChars)) {
- return TCL_ERROR;
- }
- dictVarIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr);
+ dictVarIndex = LocalScalarFromToken(varTokenPtr, envPtr);
if (dictVarIndex < 0) {
return TCL_ERROR;
}
@@ -618,8 +894,7 @@ TclCompileDictSetCmd(
*/
tokenPtr = TokenAfter(varTokenPtr);
- numWords = parsePtr->numWords-1;
- for (i=1 ; i<numWords ; i++) {
+ for (i=2 ; i< parsePtr->numWords ; i++) {
CompileWord(envPtr, tokenPtr, interp, i);
tokenPtr = TokenAfter(tokenPtr);
}
@@ -628,8 +903,9 @@ TclCompileDictSetCmd(
* Now emit the instruction to do the dict manipulation.
*/
- TclEmitInstInt4( INST_DICT_SET, numWords-2, envPtr);
+ TclEmitInstInt4( INST_DICT_SET, parsePtr->numWords-3, envPtr);
TclEmitInt4( dictVarIndex, envPtr);
+ TclAdjustStackDepth(-1, envPtr);
return TCL_OK;
}
@@ -644,8 +920,7 @@ TclCompileDictIncrCmd(
{
DefineLineInformation; /* TIP #280 */
Tcl_Token *varTokenPtr, *keyTokenPtr;
- int dictVarIndex, nameChars, incrAmount;
- const char *name;
+ int dictVarIndex, incrAmount;
/*
* There must be at least two arguments after the command.
@@ -669,7 +944,7 @@ TclCompileDictIncrCmd(
incrTokenPtr = TokenAfter(keyTokenPtr);
if (incrTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_ERROR;
+ return TclCompileBasic2Or3ArgCmd(interp, parsePtr,cmdPtr, envPtr);
}
word = incrTokenPtr[1].start;
numBytes = incrTokenPtr[1].size;
@@ -679,7 +954,7 @@ TclCompileDictIncrCmd(
code = TclGetIntFromObj(NULL, intObj, &incrAmount);
TclDecrRefCount(intObj);
if (code != TCL_OK) {
- return TCL_ERROR;
+ return TclCompileBasic2Or3ArgCmd(interp, parsePtr,cmdPtr, envPtr);
}
} else {
incrAmount = 1;
@@ -691,24 +966,16 @@ TclCompileDictIncrCmd(
* discover what the index is.
*/
- if (varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_ERROR;
- }
- name = varTokenPtr[1].start;
- nameChars = varTokenPtr[1].size;
- if (!TclIsLocalScalar(name, nameChars)) {
- return TCL_ERROR;
- }
- dictVarIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr);
+ dictVarIndex = LocalScalarFromToken(varTokenPtr, envPtr);
if (dictVarIndex < 0) {
- return TCL_ERROR;
+ return TclCompileBasic2Or3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
}
/*
* Emit the key and the code to actually do the increment.
*/
- CompileWord(envPtr, keyTokenPtr, interp, 3);
+ CompileWord(envPtr, keyTokenPtr, interp, 2);
TclEmitInstInt4( INST_DICT_INCR_IMM, incrAmount, envPtr);
TclEmitInt4( dictVarIndex, envPtr);
return TCL_OK;
@@ -724,7 +991,7 @@ TclCompileDictGetCmd(
CompileEnv *envPtr) /* Holds resulting instructions. */
{
Tcl_Token *tokenPtr;
- int numWords, i;
+ int i;
DefineLineInformation; /* TIP #280 */
/*
@@ -732,21 +999,319 @@ TclCompileDictGetCmd(
* case is legal, but too special and magic for us to deal with here).
*/
+ /* TODO: Consider support for compiling expanded args. */
if (parsePtr->numWords < 3) {
return TCL_ERROR;
}
tokenPtr = TokenAfter(parsePtr->tokenPtr);
- numWords = parsePtr->numWords-1;
/*
* Only compile this because we need INST_DICT_GET anyway.
*/
- for (i=0 ; i<numWords ; i++) {
+ for (i=1 ; i<parsePtr->numWords ; i++) {
+ CompileWord(envPtr, tokenPtr, interp, i);
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+ TclEmitInstInt4(INST_DICT_GET, parsePtr->numWords-2, envPtr);
+ TclAdjustStackDepth(-1, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileDictExistsCmd(
+ Tcl_Interp *interp, /* Used for looking up stuff. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *tokenPtr;
+ int i;
+ DefineLineInformation; /* TIP #280 */
+
+ /*
+ * There must be at least two arguments after the command (the single-arg
+ * case is legal, but too special and magic for us to deal with here).
+ */
+
+ /* TODO: Consider support for compiling expanded args. */
+ if (parsePtr->numWords < 3) {
+ return TCL_ERROR;
+ }
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+ /*
+ * Now we do the code generation.
+ */
+
+ for (i=1 ; i<parsePtr->numWords ; i++) {
+ CompileWord(envPtr, tokenPtr, interp, i);
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+ TclEmitInstInt4(INST_DICT_EXISTS, parsePtr->numWords-2, envPtr);
+ TclAdjustStackDepth(-1, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileDictUnsetCmd(
+ Tcl_Interp *interp, /* Used for looking up stuff. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *tokenPtr;
+ DefineLineInformation; /* TIP #280 */
+ int i, dictVarIndex;
+
+ /*
+ * There must be at least one argument after the variable name for us to
+ * compile to bytecode.
+ */
+
+ /* TODO: Consider support for compiling expanded args. */
+ if (parsePtr->numWords < 3) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * The dictionary variable must be a local scalar that is knowable at
+ * compile time; anything else exceeds the complexity of the opcode. So
+ * discover what the index is.
+ */
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ dictVarIndex = LocalScalarFromToken(tokenPtr, envPtr);
+ if (dictVarIndex < 0) {
+ return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ }
+
+ /*
+ * Remaining words (the key path) can be handled normally.
+ */
+
+ for (i=2 ; i<parsePtr->numWords ; i++) {
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, i);
+ }
+
+ /*
+ * Now emit the instruction to do the dict manipulation.
+ */
+
+ TclEmitInstInt4( INST_DICT_UNSET, parsePtr->numWords-2, envPtr);
+ TclEmitInt4( dictVarIndex, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileDictCreateCmd(
+ Tcl_Interp *interp, /* Used for looking up stuff. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ int worker; /* Temp var for building the value in. */
+ Tcl_Token *tokenPtr;
+ Tcl_Obj *keyObj, *valueObj, *dictObj;
+ const char *bytes;
+ int i, len;
+
+ if ((parsePtr->numWords & 1) == 0) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * See if we can build the value at compile time...
+ */
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ dictObj = Tcl_NewObj();
+ Tcl_IncrRefCount(dictObj);
+ for (i=1 ; i<parsePtr->numWords ; i+=2) {
+ keyObj = Tcl_NewObj();
+ Tcl_IncrRefCount(keyObj);
+ if (!TclWordKnownAtCompileTime(tokenPtr, keyObj)) {
+ Tcl_DecrRefCount(keyObj);
+ Tcl_DecrRefCount(dictObj);
+ goto nonConstant;
+ }
+ tokenPtr = TokenAfter(tokenPtr);
+ valueObj = Tcl_NewObj();
+ Tcl_IncrRefCount(valueObj);
+ if (!TclWordKnownAtCompileTime(tokenPtr, valueObj)) {
+ Tcl_DecrRefCount(keyObj);
+ Tcl_DecrRefCount(valueObj);
+ Tcl_DecrRefCount(dictObj);
+ goto nonConstant;
+ }
+ tokenPtr = TokenAfter(tokenPtr);
+ Tcl_DictObjPut(NULL, dictObj, keyObj, valueObj);
+ Tcl_DecrRefCount(keyObj);
+ Tcl_DecrRefCount(valueObj);
+ }
+
+ /*
+ * We did! Excellent. The "verifyDict" is to do type forcing.
+ */
+
+ bytes = Tcl_GetStringFromObj(dictObj, &len);
+ PushLiteral(envPtr, bytes, len);
+ TclEmitOpcode( INST_DUP, envPtr);
+ TclEmitOpcode( INST_DICT_VERIFY, envPtr);
+ Tcl_DecrRefCount(dictObj);
+ return TCL_OK;
+
+ /*
+ * Otherwise, we've got to issue runtime code to do the building, which we
+ * do by [dict set]ting into an unnamed local variable. This requires that
+ * we are in a context with an LVT.
+ */
+
+ nonConstant:
+ worker = AnonymousLocal(envPtr);
+ if (worker < 0) {
+ return TclCompileBasicMin0ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ }
+
+ PushStringLiteral(envPtr, "");
+ Emit14Inst( INST_STORE_SCALAR, worker, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ for (i=1 ; i<parsePtr->numWords ; i+=2) {
CompileWord(envPtr, tokenPtr, interp, i);
tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, i+1);
+ tokenPtr = TokenAfter(tokenPtr);
+ TclEmitInstInt4( INST_DICT_SET, 1, envPtr);
+ TclEmitInt4( worker, envPtr);
+ TclAdjustStackDepth(-1, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ }
+ Emit14Inst( INST_LOAD_SCALAR, worker, envPtr);
+ TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( worker, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileDictMergeCmd(
+ Tcl_Interp *interp, /* Used for looking up stuff. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr;
+ int i, workerIndex, infoIndex, outLoop;
+
+ /*
+ * Deal with some special edge cases. Note that in the case with one
+ * argument, the only thing to do is to verify the dict-ness.
+ */
+
+ /* TODO: Consider support for compiling expanded args. (less likely) */
+ if (parsePtr->numWords < 2) {
+ PushStringLiteral(envPtr, "");
+ return TCL_OK;
+ } else if (parsePtr->numWords == 2) {
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ TclEmitOpcode( INST_DUP, envPtr);
+ TclEmitOpcode( INST_DICT_VERIFY, envPtr);
+ return TCL_OK;
}
- TclEmitInstInt4(INST_DICT_GET, numWords-1, envPtr);
+
+ /*
+ * There's real merging work to do.
+ *
+ * Allocate some working space. This means we'll only ever compile this
+ * command when there's an LVT present.
+ */
+
+ workerIndex = AnonymousLocal(envPtr);
+ if (workerIndex < 0) {
+ return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ }
+ infoIndex = AnonymousLocal(envPtr);
+
+ /*
+ * Get the first dictionary and verify that it is so.
+ */
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ TclEmitOpcode( INST_DUP, envPtr);
+ TclEmitOpcode( INST_DICT_VERIFY, envPtr);
+ Emit14Inst( INST_STORE_SCALAR, workerIndex, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+
+ /*
+ * For each of the remaining dictionaries...
+ */
+
+ outLoop = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+ TclEmitInstInt4( INST_BEGIN_CATCH4, outLoop, envPtr);
+ ExceptionRangeStarts(envPtr, outLoop);
+ for (i=2 ; i<parsePtr->numWords ; i++) {
+ /*
+ * Get the dictionary, and merge its pairs into the first dict (using
+ * a small loop).
+ */
+
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, i);
+ TclEmitInstInt4( INST_DICT_FIRST, infoIndex, envPtr);
+ TclEmitInstInt1( INST_JUMP_TRUE1, 24, envPtr);
+ TclEmitInstInt4( INST_REVERSE, 2, envPtr);
+ TclEmitInstInt4( INST_DICT_SET, 1, envPtr);
+ TclEmitInt4( workerIndex, envPtr);
+ TclAdjustStackDepth(-1, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ TclEmitInstInt4( INST_DICT_NEXT, infoIndex, envPtr);
+ TclEmitInstInt1( INST_JUMP_FALSE1, -20, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( infoIndex, envPtr);
+ }
+ ExceptionRangeEnds(envPtr, outLoop);
+ TclEmitOpcode( INST_END_CATCH, envPtr);
+
+ /*
+ * Clean up any state left over.
+ */
+
+ Emit14Inst( INST_LOAD_SCALAR, workerIndex, envPtr);
+ TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( workerIndex, envPtr);
+ TclEmitInstInt1( INST_JUMP1, 18, envPtr);
+
+ /*
+ * If an exception happens when starting to iterate over the second (and
+ * subsequent) dicts. This is strictly not necessary, but it is nice.
+ */
+
+ TclAdjustStackDepth(-1, envPtr);
+ ExceptionRangeTarget(envPtr, outLoop, catchOffset);
+ TclEmitOpcode( INST_PUSH_RETURN_OPTIONS, envPtr);
+ TclEmitOpcode( INST_PUSH_RESULT, envPtr);
+ TclEmitOpcode( INST_END_CATCH, envPtr);
+ TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( workerIndex, envPtr);
+ TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( infoIndex, envPtr);
+ TclEmitOpcode( INST_RETURN_STK, envPtr);
+
return TCL_OK;
}
@@ -759,23 +1324,51 @@ TclCompileDictForCmd(
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
+ return CompileDictEachCmd(interp, parsePtr, cmdPtr, envPtr,
+ TCL_EACH_KEEP_NONE);
+}
+
+int
+TclCompileDictMapCmd(
+ Tcl_Interp *interp, /* Used for looking up stuff. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ return CompileDictEachCmd(interp, parsePtr, cmdPtr, envPtr,
+ TCL_EACH_COLLECT);
+}
+
+int
+CompileDictEachCmd(
+ Tcl_Interp *interp, /* Used for looking up stuff. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr, /* Holds resulting instructions. */
+ int collect) /* Flag == TCL_EACH_COLLECT to collect and
+ * construct a new dictionary with the loop
+ * body result. */
+{
DefineLineInformation; /* TIP #280 */
Tcl_Token *varsTokenPtr, *dictTokenPtr, *bodyTokenPtr;
int keyVarIndex, valueVarIndex, nameChars, loopRange, catchRange;
int infoIndex, jumpDisplacement, bodyTargetOffset, emptyTargetOffset;
int numVars, endTargetOffset;
- int savedStackDepth = envPtr->currStackDepth;
- /* Needed because jumps confuse the stack
- * space calculator. */
+ int collectVar = -1; /* Index of temp var holding the result
+ * dict. */
const char **argv;
Tcl_DString buffer;
/*
- * There must be at least three argument after the command.
+ * There must be three arguments after the command.
*/
if (parsePtr->numWords != 4) {
- return TCL_ERROR;
+ return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
}
varsTokenPtr = TokenAfter(parsePtr->tokenPtr);
@@ -783,7 +1376,19 @@ TclCompileDictForCmd(
bodyTokenPtr = TokenAfter(dictTokenPtr);
if (varsTokenPtr->type != TCL_TOKEN_SIMPLE_WORD ||
bodyTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_ERROR;
+ return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ }
+
+ /*
+ * Create temporary variable to capture return values from loop body when
+ * we're collecting results.
+ */
+
+ if (collect == TCL_EACH_COLLECT) {
+ collectVar = AnonymousLocal(envPtr);
+ if (collectVar < 0) {
+ return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ }
}
/*
@@ -792,35 +1397,26 @@ TclCompileDictForCmd(
*/
Tcl_DStringInit(&buffer);
- Tcl_DStringAppend(&buffer, varsTokenPtr[1].start, varsTokenPtr[1].size);
+ TclDStringAppendToken(&buffer, &varsTokenPtr[1]);
if (Tcl_SplitList(NULL, Tcl_DStringValue(&buffer), &numVars,
&argv) != TCL_OK) {
Tcl_DStringFree(&buffer);
- return TCL_ERROR;
+ return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
}
Tcl_DStringFree(&buffer);
if (numVars != 2) {
ckfree(argv);
- return TCL_ERROR;
+ return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
}
nameChars = strlen(argv[0]);
- if (!TclIsLocalScalar(argv[0], nameChars)) {
- ckfree(argv);
- return TCL_ERROR;
- }
- keyVarIndex = TclFindCompiledLocal(argv[0], nameChars, 1, envPtr);
-
+ keyVarIndex = LocalScalar(argv[0], nameChars, envPtr);
nameChars = strlen(argv[1]);
- if (!TclIsLocalScalar(argv[1], nameChars)) {
- ckfree(argv);
- return TCL_ERROR;
- }
- valueVarIndex = TclFindCompiledLocal(argv[1], nameChars, 1, envPtr);
+ valueVarIndex = LocalScalar(argv[1], nameChars, envPtr);
ckfree(argv);
if ((keyVarIndex < 0) || (valueVarIndex < 0)) {
- return TCL_ERROR;
+ return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
}
/*
@@ -830,57 +1426,75 @@ TclCompileDictForCmd(
* (at which point it should also have been finished with).
*/
- infoIndex = TclFindCompiledLocal(NULL, 0, 1, envPtr);
+ infoIndex = AnonymousLocal(envPtr);
if (infoIndex < 0) {
- return TCL_ERROR;
+ return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
}
/*
* Preparation complete; issue instructions. Note that this code issues
* fixed-sized jumps. That simplifies things a lot!
*
- * First up, get the dictionary and start the iteration. No catching of
- * errors at this point.
+ * First up, initialize the accumulator dictionary if needed.
*/
- CompileWord(envPtr, dictTokenPtr, interp, 3);
- TclEmitInstInt4( INST_DICT_FIRST, infoIndex, envPtr);
- emptyTargetOffset = CurrentOffset(envPtr);
- TclEmitInstInt4( INST_JUMP_TRUE4, 0, envPtr);
+ if (collect == TCL_EACH_COLLECT) {
+ PushStringLiteral(envPtr, "");
+ Emit14Inst( INST_STORE_SCALAR, collectVar, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ }
+
+ /*
+ * Get the dictionary and start the iteration. No catching of errors at
+ * this point.
+ */
+
+ CompileWord(envPtr, dictTokenPtr, interp, 2);
/*
* Now we catch errors from here on so that we can finalize the search
* started by Tcl_DictObjFirst above.
*/
- catchRange = DeclareExceptionRange(envPtr, CATCH_EXCEPTION_RANGE);
- TclEmitInstInt4( INST_BEGIN_CATCH4, catchRange, envPtr);
+ catchRange = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+ TclEmitInstInt4( INST_BEGIN_CATCH4, catchRange, envPtr);
ExceptionRangeStarts(envPtr, catchRange);
+ TclEmitInstInt4( INST_DICT_FIRST, infoIndex, envPtr);
+ emptyTargetOffset = CurrentOffset(envPtr);
+ TclEmitInstInt4( INST_JUMP_TRUE4, 0, envPtr);
+
/*
* Inside the iteration, write the loop variables.
*/
bodyTargetOffset = CurrentOffset(envPtr);
- TclEmitInstInt4( INST_STORE_SCALAR4, keyVarIndex, envPtr);
- TclEmitOpcode( INST_POP, envPtr);
- TclEmitInstInt4( INST_STORE_SCALAR4, valueVarIndex, envPtr);
- TclEmitOpcode( INST_POP, envPtr);
+ Emit14Inst( INST_STORE_SCALAR, keyVarIndex, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ Emit14Inst( INST_STORE_SCALAR, valueVarIndex, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
/*
* Set up the loop exception targets.
*/
- loopRange = DeclareExceptionRange(envPtr, LOOP_EXCEPTION_RANGE);
+ loopRange = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
ExceptionRangeStarts(envPtr, loopRange);
/*
* Compile the loop body itself. It should be stack-neutral.
*/
- SetLineInformation(4);
- CompileBody(envPtr, bodyTokenPtr, interp);
- TclEmitOpcode( INST_POP, envPtr);
+ BODY(bodyTokenPtr, 3);
+ if (collect == TCL_EACH_COLLECT) {
+ Emit14Inst( INST_LOAD_SCALAR, keyVarIndex, envPtr);
+ TclEmitInstInt4(INST_OVER, 1, envPtr);
+ TclEmitInstInt4(INST_DICT_SET, 1, envPtr);
+ TclEmitInt4( collectVar, envPtr);
+ TclAdjustStackDepth(-1, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ }
+ TclEmitOpcode( INST_POP, envPtr);
/*
* Both exception target ranges (error and loop) end here.
@@ -896,39 +1510,29 @@ TclCompileDictForCmd(
*/
ExceptionRangeTarget(envPtr, loopRange, continueOffset);
- TclEmitInstInt4( INST_DICT_NEXT, infoIndex, envPtr);
+ TclEmitInstInt4( INST_DICT_NEXT, infoIndex, envPtr);
jumpDisplacement = bodyTargetOffset - CurrentOffset(envPtr);
- TclEmitInstInt4( INST_JUMP_FALSE4, jumpDisplacement, envPtr);
- TclEmitOpcode( INST_POP, envPtr);
- TclEmitOpcode( INST_POP, envPtr);
-
- /*
- * Now do the final cleanup for the no-error case (this is where we break
- * out of the loop to) by force-terminating the iteration (if not already
- * terminated), ditching the exception info and jumping to the last
- * instruction for this command. In theory, this could be done using the
- * "finally" clause (next generated) but this is faster.
- */
-
- ExceptionRangeTarget(envPtr, loopRange, breakOffset);
- TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
- TclEmitInt4( infoIndex, envPtr);
- TclEmitOpcode( INST_END_CATCH, envPtr);
+ TclEmitInstInt4( INST_JUMP_FALSE4, jumpDisplacement, envPtr);
endTargetOffset = CurrentOffset(envPtr);
- TclEmitInstInt4( INST_JUMP4, 0, envPtr);
+ TclEmitInstInt1( INST_JUMP1, 0, envPtr);
/*
* Error handler "finally" clause, which force-terminates the iteration
* and rethrows the error.
*/
+ TclAdjustStackDepth(-1, envPtr);
ExceptionRangeTarget(envPtr, catchRange, catchOffset);
- TclEmitOpcode( INST_PUSH_RETURN_OPTIONS, envPtr);
- TclEmitOpcode( INST_PUSH_RESULT, envPtr);
- TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
- TclEmitInt4( infoIndex, envPtr);
- TclEmitOpcode( INST_END_CATCH, envPtr);
- TclEmitOpcode( INST_RETURN_STK, envPtr);
+ TclEmitOpcode( INST_PUSH_RETURN_OPTIONS, envPtr);
+ TclEmitOpcode( INST_PUSH_RESULT, envPtr);
+ TclEmitOpcode( INST_END_CATCH, envPtr);
+ TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( infoIndex, envPtr);
+ if (collect == TCL_EACH_COLLECT) {
+ TclEmitInstInt1(INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( collectVar, envPtr);
+ }
+ TclEmitOpcode( INST_RETURN_STK, envPtr);
/*
* Otherwise we're done (the jump after the DICT_FIRST points here) and we
@@ -936,25 +1540,33 @@ TclCompileDictForCmd(
* easy!) Note that we skip the END_CATCH. [Bug 1382528]
*/
- envPtr->currStackDepth = savedStackDepth+2;
jumpDisplacement = CurrentOffset(envPtr) - emptyTargetOffset;
TclUpdateInstInt4AtPc(INST_JUMP_TRUE4, jumpDisplacement,
envPtr->codeStart + emptyTargetOffset);
- TclEmitOpcode( INST_POP, envPtr);
- TclEmitOpcode( INST_POP, envPtr);
- TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
- TclEmitInt4( infoIndex, envPtr);
+ jumpDisplacement = CurrentOffset(envPtr) - endTargetOffset;
+ TclUpdateInstInt1AtPc(INST_JUMP1, jumpDisplacement,
+ envPtr->codeStart + endTargetOffset);
+ TclEmitOpcode( INST_POP, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ ExceptionRangeTarget(envPtr, loopRange, breakOffset);
+ TclFinalizeLoopExceptionRange(envPtr, loopRange);
+ TclEmitOpcode( INST_END_CATCH, envPtr);
/*
* Final stage of the command (normal case) is that we push an empty
- * object. This is done last to promote peephole optimization when it's
- * dropped immediately.
+ * object (or push the accumulator as the result object). This is done
+ * last to promote peephole optimization when it's dropped immediately.
*/
- jumpDisplacement = CurrentOffset(envPtr) - endTargetOffset;
- TclUpdateInstInt4AtPc(INST_JUMP4, jumpDisplacement,
- envPtr->codeStart + endTargetOffset);
- PushLiteral(envPtr, "", 0);
+ TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( infoIndex, envPtr);
+ if (collect == TCL_EACH_COLLECT) {
+ Emit14Inst( INST_LOAD_SCALAR, collectVar, envPtr);
+ TclEmitInstInt1(INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( collectVar, envPtr);
+ } else {
+ PushStringLiteral(envPtr, "");
+ }
return TCL_OK;
}
@@ -968,10 +1580,8 @@ TclCompileDictUpdateCmd(
CompileEnv *envPtr) /* Holds resulting instructions. */
{
DefineLineInformation; /* TIP #280 */
- const char *name;
- int i, nameChars, dictIndex, numVars, range, infoIndex;
+ int i, dictIndex, numVars, range, infoIndex;
Tcl_Token **keyTokenPtrs, *dictVarTokenPtr, *bodyTokenPtr, *tokenPtr;
- int savedStackDepth = envPtr->currStackDepth;
DictUpdateInfo *duiPtr;
JumpFixup jumpFixup;
@@ -1000,17 +1610,9 @@ TclCompileDictUpdateCmd(
*/
dictVarTokenPtr = TokenAfter(parsePtr->tokenPtr);
- if (dictVarTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_ERROR;
- }
- name = dictVarTokenPtr[1].start;
- nameChars = dictVarTokenPtr[1].size;
- if (!TclIsLocalScalar(name, nameChars)) {
- return TCL_ERROR;
- }
- dictIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr);
+ dictIndex = LocalScalarFromToken(dictVarTokenPtr, envPtr);
if (dictIndex < 0) {
- return TCL_ERROR;
+ goto issueFallback;
}
/*
@@ -1021,8 +1623,7 @@ TclCompileDictUpdateCmd(
duiPtr = ckalloc(sizeof(DictUpdateInfo) + sizeof(int) * (numVars - 1));
duiPtr->length = numVars;
- keyTokenPtrs = TclStackAlloc(interp,
- sizeof(Tcl_Token *) * numVars);
+ keyTokenPtrs = TclStackAlloc(interp, sizeof(Tcl_Token *) * numVars);
tokenPtr = TokenAfter(dictVarTokenPtr);
for (i=0 ; i<numVars ; i++) {
@@ -1031,37 +1632,21 @@ TclCompileDictUpdateCmd(
*/
keyTokenPtrs[i] = tokenPtr;
-
- /*
- * Variables first need to be checked for sanity.
- */
-
tokenPtr = TokenAfter(tokenPtr);
- if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- goto failedUpdateInfoAssembly;
- }
- name = tokenPtr[1].start;
- nameChars = tokenPtr[1].size;
- if (!TclIsLocalScalar(name, nameChars)) {
- goto failedUpdateInfoAssembly;
- }
/*
- * Stash the index in the auxiliary data.
+ * Stash the index in the auxiliary data (if it is indeed a local
+ * scalar that is resolvable at compile-time).
*/
- duiPtr->varIndices[i] =
- TclFindCompiledLocal(name, nameChars, 1, envPtr);
+ duiPtr->varIndices[i] = LocalScalarFromToken(tokenPtr, envPtr);
if (duiPtr->varIndices[i] < 0) {
goto failedUpdateInfoAssembly;
}
tokenPtr = TokenAfter(tokenPtr);
}
if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- failedUpdateInfoAssembly:
- ckfree(duiPtr);
- TclStackFree(interp, keyTokenPtrs);
- return TCL_ERROR;
+ goto failedUpdateInfoAssembly;
}
bodyTokenPtr = tokenPtr;
@@ -1073,19 +1658,17 @@ TclCompileDictUpdateCmd(
infoIndex = TclCreateAuxData(duiPtr, &tclDictUpdateInfoType, envPtr);
for (i=0 ; i<numVars ; i++) {
- CompileWord(envPtr, keyTokenPtrs[i], interp, i);
+ CompileWord(envPtr, keyTokenPtrs[i], interp, 2*i+2);
}
- TclEmitInstInt4( INST_LIST, numVars, envPtr);
- TclEmitInstInt4( INST_DICT_UPDATE_START, dictIndex, envPtr);
- TclEmitInt4( infoIndex, envPtr);
+ TclEmitInstInt4( INST_LIST, numVars, envPtr);
+ TclEmitInstInt4( INST_DICT_UPDATE_START, dictIndex, envPtr);
+ TclEmitInt4( infoIndex, envPtr);
- range = DeclareExceptionRange(envPtr, CATCH_EXCEPTION_RANGE);
- TclEmitInstInt4( INST_BEGIN_CATCH4, range, envPtr);
+ range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+ TclEmitInstInt4( INST_BEGIN_CATCH4, range, envPtr);
ExceptionRangeStarts(envPtr, range);
- envPtr->currStackDepth++;
- CompileBody(envPtr, bodyTokenPtr, interp);
- envPtr->currStackDepth = savedStackDepth;
+ BODY(bodyTokenPtr, parsePtr->numWords - 1);
ExceptionRangeEnds(envPtr, range);
/*
@@ -1093,10 +1676,10 @@ TclCompileDictUpdateCmd(
* the body evaluation: swap them and finish the update code.
*/
- TclEmitOpcode( INST_END_CATCH, envPtr);
- TclEmitInstInt4( INST_REVERSE, 2, envPtr);
- TclEmitInstInt4( INST_DICT_UPDATE_END, dictIndex, envPtr);
- TclEmitInt4( infoIndex, envPtr);
+ TclEmitOpcode( INST_END_CATCH, envPtr);
+ TclEmitInstInt4( INST_REVERSE, 2, envPtr);
+ TclEmitInstInt4( INST_DICT_UPDATE_END, dictIndex, envPtr);
+ TclEmitInt4( infoIndex, envPtr);
/*
* Jump around the exceptional termination code.
@@ -1111,14 +1694,14 @@ TclCompileDictUpdateCmd(
*/
ExceptionRangeTarget(envPtr, range, catchOffset);
- TclEmitOpcode( INST_PUSH_RESULT, envPtr);
- TclEmitOpcode( INST_PUSH_RETURN_OPTIONS, envPtr);
- TclEmitOpcode( INST_END_CATCH, envPtr);
- TclEmitInstInt4( INST_REVERSE, 3, envPtr);
+ TclEmitOpcode( INST_PUSH_RESULT, envPtr);
+ TclEmitOpcode( INST_PUSH_RETURN_OPTIONS, envPtr);
+ TclEmitOpcode( INST_END_CATCH, envPtr);
+ TclEmitInstInt4( INST_REVERSE, 3, envPtr);
- TclEmitInstInt4( INST_DICT_UPDATE_END, dictIndex, envPtr);
- TclEmitInt4( infoIndex, envPtr);
- TclEmitOpcode( INST_RETURN_STK, envPtr);
+ TclEmitInstInt4( INST_DICT_UPDATE_END, dictIndex, envPtr);
+ TclEmitInt4( infoIndex, envPtr);
+ TclEmitInvoke(envPtr,INST_RETURN_STK);
if (TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127)) {
Tcl_Panic("TclCompileDictCmd(update): bad jump distance %d",
@@ -1126,6 +1709,16 @@ TclCompileDictUpdateCmd(
}
TclStackFree(interp, keyTokenPtrs);
return TCL_OK;
+
+ /*
+ * Clean up after a failure to create the DictUpdateInfo structure.
+ */
+
+ failedUpdateInfoAssembly:
+ ckfree(duiPtr);
+ TclStackFree(interp, keyTokenPtrs);
+ issueFallback:
+ return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
}
int
@@ -1147,6 +1740,7 @@ TclCompileDictAppendCmd(
* speed quite so much. ;-)
*/
+ /* TODO: Consider support for compiling expanded args. */
if (parsePtr->numWords<4 || parsePtr->numWords>100) {
return TCL_ERROR;
}
@@ -1156,19 +1750,9 @@ TclCompileDictAppendCmd(
*/
tokenPtr = TokenAfter(parsePtr->tokenPtr);
- if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_ERROR;
- } else {
- register const char *name = tokenPtr[1].start;
- register int nameChars = tokenPtr[1].size;
-
- if (!TclIsLocalScalar(name, nameChars)) {
- return TCL_ERROR;
- }
- dictVarIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr);
- if (dictVarIndex < 0) {
- return TCL_ERROR;
- }
+ dictVarIndex = LocalScalarFromToken(tokenPtr, envPtr);
+ if (dictVarIndex < 0) {
+ return TclCompileBasicMin2ArgCmd(interp, parsePtr,cmdPtr, envPtr);
}
/*
@@ -1181,7 +1765,7 @@ TclCompileDictAppendCmd(
tokenPtr = TokenAfter(tokenPtr);
}
if (parsePtr->numWords > 4) {
- TclEmitInstInt1(INST_CONCAT1, parsePtr->numWords-3, envPtr);
+ TclEmitInstInt1(INST_STR_CONCAT1, parsePtr->numWords-3, envPtr);
}
/*
@@ -1203,35 +1787,288 @@ TclCompileDictLappendCmd(
{
DefineLineInformation; /* TIP #280 */
Tcl_Token *varTokenPtr, *keyTokenPtr, *valueTokenPtr;
- int dictVarIndex, nameChars;
- const char *name;
+ int dictVarIndex;
/*
* There must be three arguments after the command.
*/
+ /* TODO: Consider support for compiling expanded args. */
+ /* Probably not. Why is INST_DICT_LAPPEND limited to one value? */
if (parsePtr->numWords != 4) {
return TCL_ERROR;
}
+ /*
+ * Parse the arguments.
+ */
+
varTokenPtr = TokenAfter(parsePtr->tokenPtr);
keyTokenPtr = TokenAfter(varTokenPtr);
valueTokenPtr = TokenAfter(keyTokenPtr);
- if (varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_ERROR;
+ dictVarIndex = LocalScalarFromToken(varTokenPtr, envPtr);
+ if (dictVarIndex < 0) {
+ return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
}
- name = varTokenPtr[1].start;
- nameChars = varTokenPtr[1].size;
- if (!TclIsLocalScalar(name, nameChars)) {
+
+ /*
+ * Issue the implementation.
+ */
+
+ CompileWord(envPtr, keyTokenPtr, interp, 2);
+ CompileWord(envPtr, valueTokenPtr, interp, 3);
+ TclEmitInstInt4( INST_DICT_LAPPEND, dictVarIndex, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileDictWithCmd(
+ Tcl_Interp *interp, /* Used for looking up stuff. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ int i, range, varNameTmp = -1, pathTmp = -1, keysTmp, gotPath;
+ int dictVar, bodyIsEmpty = 1;
+ Tcl_Token *varTokenPtr, *tokenPtr;
+ JumpFixup jumpFixup;
+ const char *ptr, *end;
+
+ /*
+ * There must be at least one argument after the command.
+ */
+
+ /* TODO: Consider support for compiling expanded args. */
+ if (parsePtr->numWords < 3) {
return TCL_ERROR;
}
- dictVarIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr);
- if (dictVarIndex < 0) {
- return TCL_ERROR;
+
+ /*
+ * Parse the command (trivially). Expect the following:
+ * dict with <any (varName)> ?<any> ...? <literal>
+ */
+
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ tokenPtr = TokenAfter(varTokenPtr);
+ for (i=3 ; i<parsePtr->numWords ; i++) {
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ }
+
+ /*
+ * Test if the last word is an empty script; if so, we can compile it in
+ * all cases, but if it is non-empty we need local variable table entries
+ * to hold the temporary variables (used to keep stack usage simple).
+ */
+
+ for (ptr=tokenPtr[1].start,end=ptr+tokenPtr[1].size ; ptr!=end ; ptr++) {
+ if (*ptr!=' ' && *ptr!='\t' && *ptr!='\n' && *ptr!='\r') {
+ if (envPtr->procPtr == NULL) {
+ return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr,
+ envPtr);
+ }
+ bodyIsEmpty = 0;
+ break;
+ }
+ }
+
+ /*
+ * Determine if we're manipulating a dict in a simple local variable.
+ */
+
+ gotPath = (parsePtr->numWords > 3);
+ dictVar = LocalScalarFromToken(varTokenPtr, envPtr);
+
+ /*
+ * Special case: an empty body means we definitely have no need to issue
+ * try-finally style code or to allocate local variable table entries for
+ * storing temporaries. Still need to do both INST_DICT_EXPAND and
+ * INST_DICT_RECOMBINE_* though, because we can't determine if we're free
+ * of traces.
+ */
+
+ if (bodyIsEmpty) {
+ if (dictVar >= 0) {
+ if (gotPath) {
+ /*
+ * Case: Path into dict in LVT with empty body.
+ */
+
+ tokenPtr = TokenAfter(varTokenPtr);
+ for (i=2 ; i<parsePtr->numWords-1 ; i++) {
+ CompileWord(envPtr, tokenPtr, interp, i);
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+ TclEmitInstInt4(INST_LIST, parsePtr->numWords-3,envPtr);
+ Emit14Inst( INST_LOAD_SCALAR, dictVar, envPtr);
+ TclEmitInstInt4(INST_OVER, 1, envPtr);
+ TclEmitOpcode( INST_DICT_EXPAND, envPtr);
+ TclEmitInstInt4(INST_DICT_RECOMBINE_IMM, dictVar, envPtr);
+ } else {
+ /*
+ * Case: Direct dict in LVT with empty body.
+ */
+
+ PushStringLiteral(envPtr, "");
+ Emit14Inst( INST_LOAD_SCALAR, dictVar, envPtr);
+ PushStringLiteral(envPtr, "");
+ TclEmitOpcode( INST_DICT_EXPAND, envPtr);
+ TclEmitInstInt4(INST_DICT_RECOMBINE_IMM, dictVar, envPtr);
+ }
+ } else {
+ if (gotPath) {
+ /*
+ * Case: Path into dict in non-simple var with empty body.
+ */
+
+ tokenPtr = varTokenPtr;
+ for (i=1 ; i<parsePtr->numWords-1 ; i++) {
+ CompileWord(envPtr, tokenPtr, interp, i);
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+ TclEmitInstInt4(INST_LIST, parsePtr->numWords-3,envPtr);
+ TclEmitInstInt4(INST_OVER, 1, envPtr);
+ TclEmitOpcode( INST_LOAD_STK, envPtr);
+ TclEmitInstInt4(INST_OVER, 1, envPtr);
+ TclEmitOpcode( INST_DICT_EXPAND, envPtr);
+ TclEmitOpcode( INST_DICT_RECOMBINE_STK, envPtr);
+ } else {
+ /*
+ * Case: Direct dict in non-simple var with empty body.
+ */
+
+ CompileWord(envPtr, varTokenPtr, interp, 1);
+ TclEmitOpcode( INST_DUP, envPtr);
+ TclEmitOpcode( INST_LOAD_STK, envPtr);
+ PushStringLiteral(envPtr, "");
+ TclEmitOpcode( INST_DICT_EXPAND, envPtr);
+ PushStringLiteral(envPtr, "");
+ TclEmitInstInt4(INST_REVERSE, 2, envPtr);
+ TclEmitOpcode( INST_DICT_RECOMBINE_STK, envPtr);
+ }
+ }
+ PushStringLiteral(envPtr, "");
+ return TCL_OK;
+ }
+
+ /*
+ * OK, we have a non-trivial body. This means that the focus is on
+ * generating a try-finally structure where the INST_DICT_RECOMBINE_* goes
+ * in the 'finally' clause.
+ *
+ * Start by allocating local (unnamed, untraced) working variables.
+ */
+
+ if (dictVar == -1) {
+ varNameTmp = AnonymousLocal(envPtr);
+ }
+ if (gotPath) {
+ pathTmp = AnonymousLocal(envPtr);
+ }
+ keysTmp = AnonymousLocal(envPtr);
+
+ /*
+ * Issue instructions. First, the part to expand the dictionary.
+ */
+
+ if (dictVar == -1) {
+ CompileWord(envPtr, varTokenPtr, interp, 1);
+ Emit14Inst( INST_STORE_SCALAR, varNameTmp, envPtr);
+ }
+ tokenPtr = TokenAfter(varTokenPtr);
+ if (gotPath) {
+ for (i=2 ; i<parsePtr->numWords-1 ; i++) {
+ CompileWord(envPtr, tokenPtr, interp, i);
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+ TclEmitInstInt4( INST_LIST, parsePtr->numWords-3,envPtr);
+ Emit14Inst( INST_STORE_SCALAR, pathTmp, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ }
+ if (dictVar == -1) {
+ TclEmitOpcode( INST_LOAD_STK, envPtr);
+ } else {
+ Emit14Inst( INST_LOAD_SCALAR, dictVar, envPtr);
+ }
+ if (gotPath) {
+ Emit14Inst( INST_LOAD_SCALAR, pathTmp, envPtr);
+ } else {
+ PushStringLiteral(envPtr, "");
+ }
+ TclEmitOpcode( INST_DICT_EXPAND, envPtr);
+ Emit14Inst( INST_STORE_SCALAR, keysTmp, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+
+ /*
+ * Now the body of the [dict with].
+ */
+
+ range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+ TclEmitInstInt4( INST_BEGIN_CATCH4, range, envPtr);
+
+ ExceptionRangeStarts(envPtr, range);
+ BODY(tokenPtr, parsePtr->numWords - 1);
+ ExceptionRangeEnds(envPtr, range);
+
+ /*
+ * Now fold the results back into the dictionary in the OK case.
+ */
+
+ TclEmitOpcode( INST_END_CATCH, envPtr);
+ if (dictVar == -1) {
+ Emit14Inst( INST_LOAD_SCALAR, varNameTmp, envPtr);
+ }
+ if (gotPath) {
+ Emit14Inst( INST_LOAD_SCALAR, pathTmp, envPtr);
+ } else {
+ PushStringLiteral(envPtr, "");
+ }
+ Emit14Inst( INST_LOAD_SCALAR, keysTmp, envPtr);
+ if (dictVar == -1) {
+ TclEmitOpcode( INST_DICT_RECOMBINE_STK, envPtr);
+ } else {
+ TclEmitInstInt4( INST_DICT_RECOMBINE_IMM, dictVar, envPtr);
+ }
+ TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);
+
+ /*
+ * Now fold the results back into the dictionary in the exception case.
+ */
+
+ TclAdjustStackDepth(-1, envPtr);
+ ExceptionRangeTarget(envPtr, range, catchOffset);
+ TclEmitOpcode( INST_PUSH_RETURN_OPTIONS, envPtr);
+ TclEmitOpcode( INST_PUSH_RESULT, envPtr);
+ TclEmitOpcode( INST_END_CATCH, envPtr);
+ if (dictVar == -1) {
+ Emit14Inst( INST_LOAD_SCALAR, varNameTmp, envPtr);
+ }
+ if (parsePtr->numWords > 3) {
+ Emit14Inst( INST_LOAD_SCALAR, pathTmp, envPtr);
+ } else {
+ PushStringLiteral(envPtr, "");
+ }
+ Emit14Inst( INST_LOAD_SCALAR, keysTmp, envPtr);
+ if (dictVar == -1) {
+ TclEmitOpcode( INST_DICT_RECOMBINE_STK, envPtr);
+ } else {
+ TclEmitInstInt4( INST_DICT_RECOMBINE_IMM, dictVar, envPtr);
+ }
+ TclEmitInvoke(envPtr, INST_RETURN_STK);
+
+ /*
+ * Prepare for the start of the next command.
+ */
+
+ if (TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127)) {
+ Tcl_Panic("TclCompileDictCmd(update): bad jump distance %d",
+ (int) (CurrentOffset(envPtr) - jumpFixup.codeOffset));
}
- CompileWord(envPtr, keyTokenPtr, interp, 3);
- CompileWord(envPtr, valueTokenPtr, interp, 4);
- TclEmitInstInt4( INST_DICT_LAPPEND, dictVarIndex, envPtr);
return TCL_OK;
}
@@ -1324,19 +2161,48 @@ TclCompileErrorCmd(
{
/*
* General syntax: [error message ?errorInfo? ?errorCode?]
- * However, we only deal with the case where there is just a message.
*/
- Tcl_Token *messageTokenPtr;
+
+ Tcl_Token *tokenPtr;
DefineLineInformation; /* TIP #280 */
- if (parsePtr->numWords != 2) {
+ if (parsePtr->numWords < 2 || parsePtr->numWords > 4) {
return TCL_ERROR;
}
- messageTokenPtr = TokenAfter(parsePtr->tokenPtr);
- PushLiteral(envPtr, "-code error -level 0", 20);
- CompileWord(envPtr, messageTokenPtr, interp, 1);
- TclEmitOpcode(INST_RETURN_STK, envPtr);
+ /*
+ * Handle the message.
+ */
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+
+ /*
+ * Construct the options. Note that -code and -level are not here.
+ */
+
+ if (parsePtr->numWords == 2) {
+ PushStringLiteral(envPtr, "");
+ } else {
+ PushStringLiteral(envPtr, "-errorinfo");
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 2);
+ if (parsePtr->numWords == 3) {
+ TclEmitInstInt4( INST_LIST, 2, envPtr);
+ } else {
+ PushStringLiteral(envPtr, "-errorcode");
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 3);
+ TclEmitInstInt4( INST_LIST, 4, envPtr);
+ }
+ }
+
+ /*
+ * Issue the error via 'returnImm error 0'.
+ */
+
+ TclEmitInstInt4( INST_RETURN_IMM, TCL_ERROR, envPtr);
+ TclEmitInt4( 0, envPtr);
return TCL_OK;
}
@@ -1414,9 +2280,8 @@ TclCompileForCmd(
{
Tcl_Token *startTokenPtr, *testTokenPtr, *nextTokenPtr, *bodyTokenPtr;
JumpFixup jumpEvalCondFixup;
- int testCodeOffset, bodyCodeOffset, nextCodeOffset, jumpDist;
+ int bodyCodeOffset, nextCodeOffset, jumpDist;
int bodyRange, nextRange;
- int savedStackDepth = envPtr->currStackDepth;
DefineLineInformation; /* TIP #280 */
if (parsePtr->numWords != 5) {
@@ -1448,20 +2313,10 @@ TclCompileForCmd(
}
/*
- * Create ExceptionRange records for the body and the "next" command. The
- * "next" command's ExceptionRange supports break but not continue (and
- * has a -1 continueOffset).
- */
-
- bodyRange = DeclareExceptionRange(envPtr, LOOP_EXCEPTION_RANGE);
- nextRange = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
-
- /*
* Inline compile the initial command.
*/
- SetLineInformation(1);
- CompileBody(envPtr, startTokenPtr, interp);
+ BODY(startTokenPtr, 1);
TclEmitOpcode(INST_POP, envPtr);
/*
@@ -1482,44 +2337,38 @@ TclCompileForCmd(
* Compile the loop body.
*/
+ bodyRange = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
bodyCodeOffset = ExceptionRangeStarts(envPtr, bodyRange);
- SetLineInformation(4);
- CompileBody(envPtr, bodyTokenPtr, interp);
+ BODY(bodyTokenPtr, 4);
ExceptionRangeEnds(envPtr, bodyRange);
- envPtr->currStackDepth = savedStackDepth + 1;
TclEmitOpcode(INST_POP, envPtr);
/*
- * Compile the "next" subcommand.
+ * Compile the "next" subcommand. Note that this exception range will not
+ * have a continueOffset (other than -1) connected to it; it won't trap
+ * TCL_CONTINUE but rather just TCL_BREAK.
*/
- envPtr->currStackDepth = savedStackDepth;
+ nextRange = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
+ envPtr->exceptAuxArrayPtr[nextRange].supportsContinue = 0;
nextCodeOffset = ExceptionRangeStarts(envPtr, nextRange);
- SetLineInformation(3);
- CompileBody(envPtr, nextTokenPtr, interp);
+ BODY(nextTokenPtr, 3);
ExceptionRangeEnds(envPtr, nextRange);
- envPtr->currStackDepth = savedStackDepth + 1;
TclEmitOpcode(INST_POP, envPtr);
- envPtr->currStackDepth = savedStackDepth;
/*
* Compile the test expression then emit the conditional jump that
* terminates the for.
*/
- testCodeOffset = CurrentOffset(envPtr);
-
- jumpDist = testCodeOffset - jumpEvalCondFixup.codeOffset;
- if (TclFixupForwardJump(envPtr, &jumpEvalCondFixup, jumpDist, 127)) {
+ if (TclFixupForwardJumpToHere(envPtr, &jumpEvalCondFixup, 127)) {
bodyCodeOffset += 3;
nextCodeOffset += 3;
- testCodeOffset += 3;
}
SetLineInformation(2);
- envPtr->currStackDepth = savedStackDepth;
TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
- envPtr->currStackDepth = savedStackDepth + 1;
+ TclClearNumConversion(envPtr);
jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
if (jumpDist > 127) {
@@ -1540,13 +2389,14 @@ TclCompileForCmd(
ExceptionRangeTarget(envPtr, bodyRange, breakOffset);
ExceptionRangeTarget(envPtr, nextRange, breakOffset);
+ TclFinalizeLoopExceptionRange(envPtr, bodyRange);
+ TclFinalizeLoopExceptionRange(envPtr, nextRange);
/*
* The for command's result is an empty string.
*/
- envPtr->currStackDepth = savedStackDepth;
- PushLiteral(envPtr, "", 0);
+ PushStringLiteral(envPtr, "");
return TCL_OK;
}
@@ -1578,20 +2428,78 @@ TclCompileForeachCmd(
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
+ return CompileEachloopCmd(interp, parsePtr, cmdPtr, envPtr,
+ TCL_EACH_KEEP_NONE);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLmapCmd --
+ *
+ * Procedure called to compile the "lmap" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "lmap" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLmapCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ return CompileEachloopCmd(interp, parsePtr, cmdPtr, envPtr,
+ TCL_EACH_COLLECT);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompileEachloopCmd --
+ *
+ * Procedure called to compile the "foreach" and "lmap" commands.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "foreach" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CompileEachloopCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr, /* Holds resulting instructions. */
+ int collect) /* Select collecting or accumulating mode
+ * (TCL_EACH_*) */
+{
Proc *procPtr = envPtr->procPtr;
ForeachInfo *infoPtr; /* Points to the structure describing this
* foreach command. Stored in a AuxData
* record in the ByteCode. */
- int firstValueTemp; /* Index of the first temp var in the frame
- * used to point to a value list. */
- int loopCtTemp; /* Index of temp var holding the loop's
- * iteration count. */
+
Tcl_Token *tokenPtr, *bodyTokenPtr;
- unsigned char *jumpPc;
- JumpFixup jumpFalseFixup;
- int jumpBackDist, jumpBackOffset, infoIndex, range, bodyIndex;
- int numWords, numLists, numVars, loopIndex, tempVar, i, j, code;
- int savedStackDepth = envPtr->currStackDepth;
+ int jumpBackOffset, infoIndex, range;
+ int numWords, numLists, numVars, loopIndex, i, j, code;
DefineLineInformation; /* TIP #280 */
/*
@@ -1630,8 +2538,6 @@ TclCompileForeachCmd(
return TCL_ERROR;
}
- bodyIndex = i-1;
-
/*
* Allocate storage for the varcList and varvList arrays if necessary.
*/
@@ -1669,8 +2575,8 @@ TclCompileForeachCmd(
*/
Tcl_DStringInit(&varList);
- Tcl_DStringAppend(&varList, tokenPtr[1].start, tokenPtr[1].size);
- code = Tcl_SplitList(interp, Tcl_DStringValue(&varList),
+ TclDStringAppendToken(&varList, &tokenPtr[1]);
+ code = Tcl_SplitList(NULL, Tcl_DStringValue(&varList),
&varcList[loopIndex], &varvList[loopIndex]);
Tcl_DStringFree(&varList);
if (code != TCL_OK) {
@@ -1702,26 +2608,10 @@ TclCompileForeachCmd(
}
/*
- * We will compile the foreach command. Reserve (numLists + 1) temporary
- * variables:
- * - numLists temps to hold each value list
- * - 1 temp for the loop counter (index of next element in each list)
- *
- * At this time we don't try to reuse temporaries; if there are two
- * nonoverlapping foreach loops, they don't share any temps.
+ * We will compile the foreach command.
*/
code = TCL_OK;
- firstValueTemp = -1;
- for (loopIndex = 0; loopIndex < numLists; loopIndex++) {
- tempVar = TclFindCompiledLocal(NULL, /*nameChars*/ 0,
- /*create*/ 1, envPtr);
- if (loopIndex == 0) {
- firstValueTemp = tempVar;
- }
- }
- loopCtTemp = TclFindCompiledLocal(NULL, /*nameChars*/ 0,
- /*create*/ 1, envPtr);
/*
* Create and initialize the ForeachInfo and ForeachVarList data
@@ -1730,16 +2620,14 @@ TclCompileForeachCmd(
*/
infoPtr = ckalloc(sizeof(ForeachInfo)
- + numLists * sizeof(ForeachVarList *));
+ + (numLists - 1) * sizeof(ForeachVarList *));
infoPtr->numLists = numLists;
- infoPtr->firstValueTemp = firstValueTemp;
- infoPtr->loopCtTemp = loopCtTemp;
for (loopIndex = 0; loopIndex < numLists; loopIndex++) {
ForeachVarList *varListPtr;
numVars = varcList[loopIndex];
varListPtr = ckalloc(sizeof(ForeachVarList)
- + numVars * sizeof(int));
+ + (numVars - 1) * sizeof(int));
varListPtr->numVars = numVars;
for (j = 0; j < numVars; j++) {
const char *varName = varvList[loopIndex][j];
@@ -1750,118 +2638,77 @@ TclCompileForeachCmd(
}
infoPtr->varLists[loopIndex] = varListPtr;
}
- infoIndex = TclCreateAuxData(infoPtr, &tclForeachInfoType, envPtr);
+ infoIndex = TclCreateAuxData(infoPtr, &tclNewForeachInfoType, envPtr);
/*
- * Create an exception record to handle [break] and [continue].
+ * Create the collecting object, unshared.
*/
-
- range = DeclareExceptionRange(envPtr, LOOP_EXCEPTION_RANGE);
-
+
+ if (collect == TCL_EACH_COLLECT) {
+ TclEmitInstInt4(INST_LIST, 0, envPtr);
+ }
+
/*
- * Evaluate then store each value list in the associated temporary.
+ * Evaluate each value list and leave it on stack.
*/
- loopIndex = 0;
for (i = 0, tokenPtr = parsePtr->tokenPtr;
i < numWords-1;
i++, tokenPtr = TokenAfter(tokenPtr)) {
if ((i%2 == 0) && (i > 0)) {
- SetLineInformation(i);
- CompileTokens(envPtr, tokenPtr, interp);
- tempVar = (firstValueTemp + loopIndex);
- if (tempVar <= 255) {
- TclEmitInstInt1(INST_STORE_SCALAR1, tempVar, envPtr);
- } else {
- TclEmitInstInt4(INST_STORE_SCALAR4, tempVar, envPtr);
- }
- TclEmitOpcode(INST_POP, envPtr);
- loopIndex++;
+ CompileWord(envPtr, tokenPtr, interp, i);
}
}
- /*
- * Initialize the temporary var that holds the count of loop iterations.
- */
-
- TclEmitInstInt4(INST_FOREACH_START4, infoIndex, envPtr);
-
- /*
- * Top of loop code: assign each loop variable and check whether
- * to terminate the loop.
- */
-
- ExceptionRangeTarget(envPtr, range, continueOffset);
- TclEmitInstInt4(INST_FOREACH_STEP4, infoIndex, envPtr);
- TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpFalseFixup);
-
+ TclEmitInstInt4(INST_FOREACH_START, infoIndex, envPtr);
+
/*
* Inline compile the loop body.
*/
- SetLineInformation(bodyIndex);
+ range = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
+
ExceptionRangeStarts(envPtr, range);
- CompileBody(envPtr, bodyTokenPtr, interp);
+ BODY(bodyTokenPtr, numWords - 1);
ExceptionRangeEnds(envPtr, range);
- envPtr->currStackDepth = savedStackDepth + 1;
- TclEmitOpcode(INST_POP, envPtr);
-
- /*
- * Jump back to the test at the top of the loop. Generate a 4 byte jump if
- * the distance to the test is > 120 bytes. This is conservative and
- * ensures that we won't have to replace this jump if we later need to
- * replace the ifFalse jump with a 4 byte jump.
- */
-
- jumpBackOffset = CurrentOffset(envPtr);
- jumpBackDist = jumpBackOffset-envPtr->exceptArrayPtr[range].continueOffset;
- if (jumpBackDist > 120) {
- TclEmitInstInt4(INST_JUMP4, -jumpBackDist, envPtr);
+
+ if (collect == TCL_EACH_COLLECT) {
+ TclEmitOpcode(INST_LMAP_COLLECT, envPtr);
} else {
- TclEmitInstInt1(INST_JUMP1, -jumpBackDist, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
}
/*
- * Fix the target of the jump after the foreach_step test.
+ * Bottom of loop code: assign each loop variable and check whether
+ * to terminate the loop. Set the loop's break target.
*/
- if (TclFixupForwardJumpToHere(envPtr, &jumpFalseFixup, 127)) {
- /*
- * Update the loop body's starting PC offset since it moved down.
- */
-
- envPtr->exceptArrayPtr[range].codeOffset += 3;
-
- /*
- * Update the jump back to the test at the top of the loop since it
- * also moved down 3 bytes.
- */
-
- jumpBackOffset += 3;
- jumpPc = (envPtr->codeStart + jumpBackOffset);
- jumpBackDist += 3;
- if (jumpBackDist > 120) {
- TclUpdateInstInt4AtPc(INST_JUMP4, -jumpBackDist, jumpPc);
- } else {
- TclUpdateInstInt1AtPc(INST_JUMP1, -jumpBackDist, jumpPc);
- }
- }
+ ExceptionRangeTarget(envPtr, range, continueOffset);
+ TclEmitOpcode(INST_FOREACH_STEP, envPtr);
+ ExceptionRangeTarget(envPtr, range, breakOffset);
+ TclFinalizeLoopExceptionRange(envPtr, range);
+ TclEmitOpcode(INST_FOREACH_END, envPtr);
+ TclAdjustStackDepth(-(numLists+2), envPtr);
/*
- * Set the loop's break target.
+ * Set the jumpback distance from INST_FOREACH_STEP to the start of the
+ * body's code. Misuse loopCtTemp for storing the jump size.
*/
-
- ExceptionRangeTarget(envPtr, range, breakOffset);
+
+ jumpBackOffset = envPtr->exceptArrayPtr[range].continueOffset -
+ envPtr->exceptArrayPtr[range].codeOffset;
+ infoPtr->loopCtTemp = -jumpBackOffset;
/*
- * The foreach command's result is an empty string.
+ * The command's result is an empty string if not collecting. If
+ * collecting, it is automatically left on stack after FOREACH_END.
*/
- envPtr->currStackDepth = savedStackDepth;
- PushLiteral(envPtr, "", 0);
- envPtr->currStackDepth = savedStackDepth + 1;
-
- done:
+ if (collect != TCL_EACH_COLLECT) {
+ PushStringLiteral(envPtr, "");
+ }
+
+ done:
for (loopIndex = 0; loopIndex < numLists; loopIndex++) {
if (varvList[loopIndex] != NULL) {
ckfree(varvList[loopIndex]);
@@ -2015,611 +2862,58 @@ PrintForeachInfo(
Tcl_AppendToObj(appendObj, "]", -1);
}
}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileGlobalCmd --
- *
- * Procedure called to compile the "global" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "global" command at
- * runtime.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclCompileGlobalCmd(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Parse *parsePtr, /* Points to a parse structure for the command
- * created by Tcl_ParseCommand. */
- Command *cmdPtr, /* Points to defintion of command being
- * compiled. */
- CompileEnv *envPtr) /* Holds resulting instructions. */
-{
- Tcl_Token *varTokenPtr;
- int localIndex, numWords, i;
- DefineLineInformation; /* TIP #280 */
-
- numWords = parsePtr->numWords;
- if (numWords < 2) {
- return TCL_ERROR;
- }
- /*
- * 'global' has no effect outside of proc bodies; handle that at runtime
- */
-
- if (envPtr->procPtr == NULL) {
- return TCL_ERROR;
- }
-
- /*
- * Push the namespace
- */
-
- PushLiteral(envPtr, "::", 2);
-
- /*
- * Loop over the variables.
- */
-
- varTokenPtr = TokenAfter(parsePtr->tokenPtr);
- for (i=2; i<=numWords; varTokenPtr = TokenAfter(varTokenPtr),i++) {
- localIndex = IndexTailVarIfKnown(interp, varTokenPtr, envPtr);
-
- if (localIndex < 0) {
- return TCL_ERROR;
- }
-
- CompileWord(envPtr, varTokenPtr, interp, 1);
- TclEmitInstInt4(INST_NSUPVAR, localIndex, envPtr);
- }
-
- /*
- * Pop the namespace, and set the result to empty
- */
-
- TclEmitOpcode(INST_POP, envPtr);
- PushLiteral(envPtr, "", 0);
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileIfCmd --
- *
- * Procedure called to compile the "if" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "if" command at
- * runtime.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclCompileIfCmd(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Parse *parsePtr, /* Points to a parse structure for the command
- * created by Tcl_ParseCommand. */
- Command *cmdPtr, /* Points to defintion of command being
- * compiled. */
- CompileEnv *envPtr) /* Holds resulting instructions. */
-{
- JumpFixupArray jumpFalseFixupArray;
- /* Used to fix the ifFalse jump after each
- * test when its target PC is determined. */
- JumpFixupArray jumpEndFixupArray;
- /* Used to fix the jump after each "then" body
- * to the end of the "if" when that PC is
- * determined. */
- Tcl_Token *tokenPtr, *testTokenPtr;
- int jumpIndex = 0; /* Avoid compiler warning. */
- int jumpFalseDist, numWords, wordIdx, numBytes, j, code;
- const char *word;
- int savedStackDepth = envPtr->currStackDepth;
- /* Saved stack depth at the start of the first
- * test; the envPtr current depth is restored
- * to this value at the start of each test. */
- int realCond = 1; /* Set to 0 for static conditions:
- * "if 0 {..}" */
- int boolVal; /* Value of static condition. */
- int compileScripts = 1;
- DefineLineInformation; /* TIP #280 */
-
- /*
- * Only compile the "if" command if all arguments are simple words, in
- * order to insure correct substitution [Bug 219166]
- */
-
- tokenPtr = parsePtr->tokenPtr;
- wordIdx = 0;
- numWords = parsePtr->numWords;
-
- for (wordIdx = 0; wordIdx < numWords; wordIdx++) {
- if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_ERROR;
- }
- tokenPtr = TokenAfter(tokenPtr);
- }
-
- TclInitJumpFixupArray(&jumpFalseFixupArray);
- TclInitJumpFixupArray(&jumpEndFixupArray);
- code = TCL_OK;
-
- /*
- * Each iteration of this loop compiles one "if expr ?then? body" or
- * "elseif expr ?then? body" clause.
- */
-
- tokenPtr = parsePtr->tokenPtr;
- wordIdx = 0;
- while (wordIdx < numWords) {
- /*
- * Stop looping if the token isn't "if" or "elseif".
- */
-
- word = tokenPtr[1].start;
- numBytes = tokenPtr[1].size;
- if ((tokenPtr == parsePtr->tokenPtr)
- || ((numBytes == 6) && (strncmp(word, "elseif", 6) == 0))) {
- tokenPtr = TokenAfter(tokenPtr);
- wordIdx++;
- } else {
- break;
- }
- if (wordIdx >= numWords) {
- code = TCL_ERROR;
- goto done;
- }
-
- /*
- * Compile the test expression then emit the conditional jump around
- * the "then" part.
- */
-
- envPtr->currStackDepth = savedStackDepth;
- testTokenPtr = tokenPtr;
-
- if (realCond) {
- /*
- * Find out if the condition is a constant.
- */
-
- Tcl_Obj *boolObj = Tcl_NewStringObj(testTokenPtr[1].start,
- testTokenPtr[1].size);
-
- Tcl_IncrRefCount(boolObj);
- code = Tcl_GetBooleanFromObj(NULL, boolObj, &boolVal);
- TclDecrRefCount(boolObj);
- if (code == TCL_OK) {
- /*
- * A static condition.
- */
-
- realCond = 0;
- if (!boolVal) {
- compileScripts = 0;
- }
- } else {
- SetLineInformation(wordIdx);
- Tcl_ResetResult(interp);
- TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
- if (jumpFalseFixupArray.next >= jumpFalseFixupArray.end) {
- TclExpandJumpFixupArray(&jumpFalseFixupArray);
- }
- jumpIndex = jumpFalseFixupArray.next;
- jumpFalseFixupArray.next++;
- TclEmitForwardJump(envPtr, TCL_FALSE_JUMP,
- jumpFalseFixupArray.fixup+jumpIndex);
- }
- code = TCL_OK;
- }
-
- /*
- * Skip over the optional "then" before the then clause.
- */
-
- tokenPtr = TokenAfter(testTokenPtr);
- wordIdx++;
- if (wordIdx >= numWords) {
- code = TCL_ERROR;
- goto done;
- }
- if (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- word = tokenPtr[1].start;
- numBytes = tokenPtr[1].size;
- if ((numBytes == 4) && (strncmp(word, "then", 4) == 0)) {
- tokenPtr = TokenAfter(tokenPtr);
- wordIdx++;
- if (wordIdx >= numWords) {
- code = TCL_ERROR;
- goto done;
- }
- }
- }
-
- /*
- * Compile the "then" command body.
- */
-
- if (compileScripts) {
- SetLineInformation(wordIdx);
- envPtr->currStackDepth = savedStackDepth;
- CompileBody(envPtr, tokenPtr, interp);
- }
-
- if (realCond) {
- /*
- * Jump to the end of the "if" command. Both jumpFalseFixupArray
- * and jumpEndFixupArray are indexed by "jumpIndex".
- */
-
- if (jumpEndFixupArray.next >= jumpEndFixupArray.end) {
- TclExpandJumpFixupArray(&jumpEndFixupArray);
- }
- jumpEndFixupArray.next++;
- TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
- jumpEndFixupArray.fixup+jumpIndex);
-
- /*
- * Fix the target of the jumpFalse after the test. Generate a 4
- * byte jump if the distance is > 120 bytes. This is conservative,
- * and ensures that we won't have to replace this jump if we later
- * also need to replace the proceeding jump to the end of the "if"
- * with a 4 byte jump.
- */
-
- if (TclFixupForwardJumpToHere(envPtr,
- jumpFalseFixupArray.fixup+jumpIndex, 120)) {
- /*
- * Adjust the code offset for the proceeding jump to the end
- * of the "if" command.
- */
-
- jumpEndFixupArray.fixup[jumpIndex].codeOffset += 3;
- }
- } else if (boolVal) {
- /*
- * We were processing an "if 1 {...}"; stop compiling scripts.
- */
-
- compileScripts = 0;
- } else {
- /*
- * We were processing an "if 0 {...}"; reset so that the rest
- * (elseif, else) is compiled correctly.
- */
-
- realCond = 1;
- compileScripts = 1;
- }
-
- tokenPtr = TokenAfter(tokenPtr);
- wordIdx++;
- }
-
- /*
- * Restore the current stack depth in the environment; the "else" clause
- * (or its default) will add 1 to this.
- */
-
- envPtr->currStackDepth = savedStackDepth;
-
- /*
- * Check for the optional else clause. Do not compile anything if this was
- * an "if 1 {...}" case.
- */
-
- if ((wordIdx < numWords) && (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD)) {
- /*
- * There is an else clause. Skip over the optional "else" word.
- */
-
- word = tokenPtr[1].start;
- numBytes = tokenPtr[1].size;
- if ((numBytes == 4) && (strncmp(word, "else", 4) == 0)) {
- tokenPtr = TokenAfter(tokenPtr);
- wordIdx++;
- if (wordIdx >= numWords) {
- code = TCL_ERROR;
- goto done;
- }
- }
-
- if (compileScripts) {
- /*
- * Compile the else command body.
- */
-
- SetLineInformation(wordIdx);
- CompileBody(envPtr, tokenPtr, interp);
- }
-
- /*
- * Make sure there are no words after the else clause.
- */
-
- wordIdx++;
- if (wordIdx < numWords) {
- code = TCL_ERROR;
- goto done;
- }
- } else {
- /*
- * No else clause: the "if" command's result is an empty string.
- */
-
- if (compileScripts) {
- PushLiteral(envPtr, "", 0);
- }
- }
-
- /*
- * Fix the unconditional jumps to the end of the "if" command.
- */
-
- for (j = jumpEndFixupArray.next; j > 0; j--) {
- jumpIndex = (j - 1); /* i.e. process the closest jump first. */
- if (TclFixupForwardJumpToHere(envPtr,
- jumpEndFixupArray.fixup+jumpIndex, 127)) {
- /*
- * Adjust the immediately preceeding "ifFalse" jump. We moved it's
- * target (just after this jump) down three bytes.
- */
-
- unsigned char *ifFalsePc = envPtr->codeStart
- + jumpFalseFixupArray.fixup[jumpIndex].codeOffset;
- unsigned char opCode = *ifFalsePc;
-
- if (opCode == INST_JUMP_FALSE1) {
- jumpFalseDist = TclGetInt1AtPtr(ifFalsePc + 1);
- jumpFalseDist += 3;
- TclStoreInt1AtPtr(jumpFalseDist, (ifFalsePc + 1));
- } else if (opCode == INST_JUMP_FALSE4) {
- jumpFalseDist = TclGetInt4AtPtr(ifFalsePc + 1);
- jumpFalseDist += 3;
- TclStoreInt4AtPtr(jumpFalseDist, (ifFalsePc + 1));
- } else {
- Tcl_Panic("TclCompileIfCmd: unexpected opcode \"%d\" updating ifFalse jump", (int) opCode);
- }
- }
- }
-
- /*
- * Free the jumpFixupArray array if malloc'ed storage was used.
- */
-
- done:
- envPtr->currStackDepth = savedStackDepth + 1;
- TclFreeJumpFixupArray(&jumpFalseFixupArray);
- TclFreeJumpFixupArray(&jumpEndFixupArray);
- return code;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileIncrCmd --
- *
- * Procedure called to compile the "incr" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "incr" command at
- * runtime.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclCompileIncrCmd(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Parse *parsePtr, /* Points to a parse structure for the command
- * created by Tcl_ParseCommand. */
- Command *cmdPtr, /* Points to defintion of command being
- * compiled. */
- CompileEnv *envPtr) /* Holds resulting instructions. */
+static void
+PrintNewForeachInfo(
+ ClientData clientData,
+ Tcl_Obj *appendObj,
+ ByteCode *codePtr,
+ unsigned int pcOffset)
{
- Tcl_Token *varTokenPtr, *incrTokenPtr;
- int simpleVarName, isScalar, localIndex, haveImmValue, immValue;
- DefineLineInformation; /* TIP #280 */
-
- if ((parsePtr->numWords != 2) && (parsePtr->numWords != 3)) {
- return TCL_ERROR;
- }
-
- varTokenPtr = TokenAfter(parsePtr->tokenPtr);
-
- PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_LARGE_INDEX,
- &localIndex, &simpleVarName, &isScalar, 1);
-
- /*
- * If an increment is given, push it, but see first if it's a small
- * integer.
- */
-
- haveImmValue = 0;
- immValue = 1;
- if (parsePtr->numWords == 3) {
- incrTokenPtr = TokenAfter(varTokenPtr);
- if (incrTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- const char *word = incrTokenPtr[1].start;
- int numBytes = incrTokenPtr[1].size;
- int code;
- Tcl_Obj *intObj = Tcl_NewStringObj(word, numBytes);
-
- Tcl_IncrRefCount(intObj);
- code = TclGetIntFromObj(NULL, intObj, &immValue);
- TclDecrRefCount(intObj);
- if ((code == TCL_OK) && (-127 <= immValue) && (immValue <= 127)) {
- haveImmValue = 1;
- }
- if (!haveImmValue) {
- PushLiteral(envPtr, word, numBytes);
- }
- } else {
- SetLineInformation(2);
- CompileTokens(envPtr, incrTokenPtr, interp);
- }
- } else { /* No incr amount given so use 1. */
- haveImmValue = 1;
- }
-
- /*
- * Emit the instruction to increment the variable.
- */
+ register ForeachInfo *infoPtr = clientData;
+ register ForeachVarList *varsPtr;
+ int i, j;
- if (simpleVarName) {
- if (isScalar) {
- if (localIndex >= 0) {
- if (haveImmValue) {
- TclEmitInstInt1(INST_INCR_SCALAR1_IMM, localIndex, envPtr);
- TclEmitInt1(immValue, envPtr);
- } else {
- TclEmitInstInt1(INST_INCR_SCALAR1, localIndex, envPtr);
- }
- } else {
- if (haveImmValue) {
- TclEmitInstInt1(INST_INCR_SCALAR_STK_IMM, immValue, envPtr);
- } else {
- TclEmitOpcode(INST_INCR_SCALAR_STK, envPtr);
- }
- }
- } else {
- if (localIndex >= 0) {
- if (haveImmValue) {
- TclEmitInstInt1(INST_INCR_ARRAY1_IMM, localIndex, envPtr);
- TclEmitInt1(immValue, envPtr);
- } else {
- TclEmitInstInt1(INST_INCR_ARRAY1, localIndex, envPtr);
- }
- } else {
- if (haveImmValue) {
- TclEmitInstInt1(INST_INCR_ARRAY_STK_IMM, immValue, envPtr);
- } else {
- TclEmitOpcode(INST_INCR_ARRAY_STK, envPtr);
- }
- }
- }
- } else { /* Non-simple variable name. */
- if (haveImmValue) {
- TclEmitInstInt1(INST_INCR_STK_IMM, immValue, envPtr);
- } else {
- TclEmitOpcode(INST_INCR_STK, envPtr);
+ Tcl_AppendPrintfToObj(appendObj, "jumpOffset=%+d, vars=",
+ infoPtr->loopCtTemp);
+ for (i=0 ; i<infoPtr->numLists ; i++) {
+ if (i) {
+ Tcl_AppendToObj(appendObj, ",", -1);
}
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileInfoExistsCmd --
- *
- * Procedure called to compile the "info exists" subcommand.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "info exists"
- * subcommand at runtime.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclCompileInfoExistsCmd(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Parse *parsePtr, /* Points to a parse structure for the command
- * created by Tcl_ParseCommand. */
- Command *cmdPtr, /* Points to defintion of command being
- * compiled. */
- CompileEnv *envPtr) /* Holds resulting instructions. */
-{
- Tcl_Token *tokenPtr;
- int isScalar, simpleVarName, localIndex;
- DefineLineInformation; /* TIP #280 */
-
- if (parsePtr->numWords != 2) {
- return TCL_ERROR;
- }
-
- /*
- * Decide if we can use a frame slot for the var/array name or if we need
- * to emit code to compute and push the name at runtime. We use a frame
- * slot (entry in the array of local vars) if we are compiling a procedure
- * body and if the name is simple text that does not include namespace
- * qualifiers.
- */
-
- tokenPtr = TokenAfter(parsePtr->tokenPtr);
- PushVarNameWord(interp, tokenPtr, envPtr, 0, &localIndex,
- &simpleVarName, &isScalar, 1);
-
- /*
- * Emit instruction to check the variable for existence.
- */
-
- if (simpleVarName) {
- if (isScalar) {
- if (localIndex < 0) {
- TclEmitOpcode(INST_EXIST_STK, envPtr);
- } else {
- TclEmitInstInt4(INST_EXIST_SCALAR, localIndex, envPtr);
- }
- } else {
- if (localIndex < 0) {
- TclEmitOpcode(INST_EXIST_ARRAY_STK, envPtr);
- } else {
- TclEmitInstInt4(INST_EXIST_ARRAY, localIndex, envPtr);
+ Tcl_AppendToObj(appendObj, "[", -1);
+ varsPtr = infoPtr->varLists[i];
+ for (j=0 ; j<varsPtr->numVars ; j++) {
+ if (j) {
+ Tcl_AppendToObj(appendObj, ",", -1);
}
+ Tcl_AppendPrintfToObj(appendObj, "%%v%u",
+ (unsigned) varsPtr->varIndexes[j]);
}
- } else {
- TclEmitOpcode(INST_EXIST_STK, envPtr);
+ Tcl_AppendToObj(appendObj, "]", -1);
}
-
- return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * TclCompileLappendCmd --
+ * TclCompileFormatCmd --
*
- * Procedure called to compile the "lappend" command.
+ * Procedure called to compile the "format" command. Handles cases that
+ * can be done as constants or simple string concatenation only.
*
* Results:
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
* evaluation to runtime.
*
* Side effects:
- * Instructions are added to envPtr to execute the "lappend" command at
+ * Instructions are added to envPtr to execute the "format" command at
* runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileLappendCmd(
+TclCompileFormatCmd(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
* created by Tcl_ParseCommand. */
@@ -2627,1347 +2921,236 @@ TclCompileLappendCmd(
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
- Tcl_Token *varTokenPtr;
- int simpleVarName, isScalar, localIndex, numWords;
DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+ Tcl_Obj **objv, *formatObj, *tmpObj;
+ char *bytes, *start;
+ int i, j, len;
/*
- * If we're not in a procedure, don't compile.
+ * Don't handle any guaranteed-error cases.
*/
- if (envPtr->procPtr == NULL) {
- return TCL_ERROR;
- }
-
- numWords = parsePtr->numWords;
- if (numWords == 1) {
- return TCL_ERROR;
- }
- if (numWords != 3) {
- /*
- * LAPPEND instructions currently only handle one value appends.
- */
-
+ if (parsePtr->numWords < 2) {
return TCL_ERROR;
}
/*
- * Decide if we can use a frame slot for the var/array name or if we
- * need to emit code to compute and push the name at runtime. We use a
- * frame slot (entry in the array of local vars) if we are compiling a
- * procedure body and if the name is simple text that does not include
- * namespace qualifiers.
+ * Check if the argument words are all compile-time-known literals; that's
+ * a case we can handle by compiling to a constant.
*/
- varTokenPtr = TokenAfter(parsePtr->tokenPtr);
-
- PushVarNameWord(interp, varTokenPtr, envPtr, 0,
- &localIndex, &simpleVarName, &isScalar, 1);
-
- /*
- * If we are doing an assignment, push the new value. In the no values
- * case, create an empty object.
- */
-
- if (numWords > 2) {
- Tcl_Token *valueTokenPtr = TokenAfter(varTokenPtr);
-
- CompileWord(envPtr, valueTokenPtr, interp, 2);
- }
-
- /*
- * Emit instructions to set/get the variable.
- */
-
- /*
- * The *_STK opcodes should be refactored to make better use of existing
- * LOAD/STORE instructions.
- */
-
- if (simpleVarName) {
- if (isScalar) {
- if (localIndex < 0) {
- TclEmitOpcode(INST_LAPPEND_STK, envPtr);
- } else if (localIndex <= 255) {
- TclEmitInstInt1(INST_LAPPEND_SCALAR1, localIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_LAPPEND_SCALAR4, localIndex, envPtr);
- }
- } else {
- if (localIndex < 0) {
- TclEmitOpcode(INST_LAPPEND_ARRAY_STK, envPtr);
- } else if (localIndex <= 255) {
- TclEmitInstInt1(INST_LAPPEND_ARRAY1, localIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_LAPPEND_ARRAY4, localIndex, envPtr);
- }
- }
- } else {
- TclEmitOpcode(INST_LAPPEND_STK, envPtr);
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileLassignCmd --
- *
- * Procedure called to compile the "lassign" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "lassign" command at
- * runtime.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclCompileLassignCmd(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Parse *parsePtr, /* Points to a parse structure for the command
- * created by Tcl_ParseCommand. */
- Command *cmdPtr, /* Points to defintion of command being
- * compiled. */
- CompileEnv *envPtr) /* Holds resulting instructions. */
-{
- Tcl_Token *tokenPtr;
- int simpleVarName, isScalar, localIndex, numWords, idx;
- DefineLineInformation; /* TIP #280 */
-
- numWords = parsePtr->numWords;
-
- /*
- * Check for command syntax error, but we'll punt that to runtime.
- */
-
- if (numWords < 3) {
+ formatObj = Tcl_NewObj();
+ Tcl_IncrRefCount(formatObj);
+ tokenPtr = TokenAfter(tokenPtr);
+ if (!TclWordKnownAtCompileTime(tokenPtr, formatObj)) {
+ Tcl_DecrRefCount(formatObj);
return TCL_ERROR;
}
- /*
- * Generate code to push list being taken apart by [lassign].
- */
-
- tokenPtr = TokenAfter(parsePtr->tokenPtr);
- CompileWord(envPtr, tokenPtr, interp, 1);
-
- /*
- * Generate code to assign values from the list to variables.
- */
-
- for (idx=0 ; idx<numWords-2 ; idx++) {
+ objv = ckalloc((parsePtr->numWords-2) * sizeof(Tcl_Obj *));
+ for (i=0 ; i+2 < parsePtr->numWords ; i++) {
tokenPtr = TokenAfter(tokenPtr);
-
- /*
- * Generate the next variable name.
- */
-
- PushVarNameWord(interp, tokenPtr, envPtr, 0, &localIndex,
- &simpleVarName, &isScalar, idx+2);
-
- /*
- * Emit instructions to get the idx'th item out of the list value on
- * the stack and assign it to the variable.
- */
-
- if (simpleVarName) {
- if (isScalar) {
- if (localIndex >= 0) {
- TclEmitOpcode(INST_DUP, envPtr);
- TclEmitInstInt4(INST_LIST_INDEX_IMM, idx, envPtr);
- if (localIndex <= 255) {
- TclEmitInstInt1(INST_STORE_SCALAR1,localIndex,envPtr);
- } else {
- TclEmitInstInt4(INST_STORE_SCALAR4,localIndex,envPtr);
- }
- } else {
- TclEmitInstInt4(INST_OVER, 1, envPtr);
- TclEmitInstInt4(INST_LIST_INDEX_IMM, idx, envPtr);
- TclEmitOpcode(INST_STORE_SCALAR_STK, envPtr);
- }
- } else {
- if (localIndex >= 0) {
- TclEmitInstInt4(INST_OVER, 1, envPtr);
- TclEmitInstInt4(INST_LIST_INDEX_IMM, idx, envPtr);
- if (localIndex <= 255) {
- TclEmitInstInt1(INST_STORE_ARRAY1, localIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_STORE_ARRAY4, localIndex, envPtr);
- }
- } else {
- TclEmitInstInt4(INST_OVER, 2, envPtr);
- TclEmitInstInt4(INST_LIST_INDEX_IMM, idx, envPtr);
- TclEmitOpcode(INST_STORE_ARRAY_STK, envPtr);
- }
- }
- } else {
- TclEmitInstInt4(INST_OVER, 1, envPtr);
- TclEmitInstInt4(INST_LIST_INDEX_IMM, idx, envPtr);
- TclEmitOpcode(INST_STORE_STK, envPtr);
- }
- TclEmitOpcode(INST_POP, envPtr);
- }
-
- /*
- * Generate code to leave the rest of the list on the stack.
- */
-
- TclEmitInstInt4(INST_LIST_RANGE_IMM, idx, envPtr);
- TclEmitInt4(-2, envPtr); /* -2 == "end" */
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileLindexCmd --
- *
- * Procedure called to compile the "lindex" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "lindex" command at
- * runtime.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclCompileLindexCmd(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Parse *parsePtr, /* Points to a parse structure for the command
- * created by Tcl_ParseCommand. */
- Command *cmdPtr, /* Points to defintion of command being
- * compiled. */
- CompileEnv *envPtr) /* Holds resulting instructions. */
-{
- Tcl_Token *idxTokenPtr, *valTokenPtr;
- int i, numWords = parsePtr->numWords;
- DefineLineInformation; /* TIP #280 */
-
- /*
- * Quit if too few args.
- */
-
- if (numWords <= 1) {
- return TCL_ERROR;
- }
-
- valTokenPtr = TokenAfter(parsePtr->tokenPtr);
- if (numWords != 3) {
- goto emitComplexLindex;
- }
-
- idxTokenPtr = TokenAfter(valTokenPtr);
- if (idxTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- Tcl_Obj *tmpObj;
- int idx, result;
-
- tmpObj = Tcl_NewStringObj(idxTokenPtr[1].start, idxTokenPtr[1].size);
- result = TclGetIntFromObj(NULL, tmpObj, &idx);
- TclDecrRefCount(tmpObj);
-
- if (result == TCL_OK && idx >= 0) {
- /*
- * All checks have been completed, and we have exactly this
- * construct:
- * lindex <arbitraryValue> <posInt>
- * This is best compiled as a push of the arbitrary value followed
- * by an "immediate lindex" which is the most efficient variety.
- */
-
- CompileWord(envPtr, valTokenPtr, interp, 1);
- TclEmitInstInt4(INST_LIST_INDEX_IMM, idx, envPtr);
- return TCL_OK;
- }
-
- /*
- * If the conversion failed or the value was negative, we just keep on
- * going with the more complex compilation.
- */
- }
-
- /*
- * Push the operands onto the stack.
- */
-
- emitComplexLindex:
- for (i=1 ; i<numWords ; i++) {
- CompileWord(envPtr, valTokenPtr, interp, i);
- valTokenPtr = TokenAfter(valTokenPtr);
- }
-
- /*
- * Emit INST_LIST_INDEX if objc==3, or INST_LIST_INDEX_MULTI if there are
- * multiple index args.
- */
-
- if (numWords == 3) {
- TclEmitOpcode(INST_LIST_INDEX, envPtr);
- } else {
- TclEmitInstInt4(INST_LIST_INDEX_MULTI, numWords-1, envPtr);
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileListCmd --
- *
- * Procedure called to compile the "list" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "list" command at
- * runtime.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclCompileListCmd(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Parse *parsePtr, /* Points to a parse structure for the command
- * created by Tcl_ParseCommand. */
- Command *cmdPtr, /* Points to defintion of command being
- * compiled. */
- CompileEnv *envPtr) /* Holds resulting instructions. */
-{
- DefineLineInformation; /* TIP #280 */
-
- /*
- * If we're not in a procedure, don't compile.
- */
-
- if (envPtr->procPtr == NULL) {
- return TCL_ERROR;
- }
-
- if (parsePtr->numWords == 1) {
- /*
- * [list] without arguments just pushes an empty object.
- */
-
- PushLiteral(envPtr, "", 0);
- } else {
- /*
- * Push the all values onto the stack.
- */
-
- Tcl_Token *valueTokenPtr;
- int i, numWords;
-
- numWords = parsePtr->numWords;
-
- valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
- for (i = 1; i < numWords; i++) {
- CompileWord(envPtr, valueTokenPtr, interp, i);
- valueTokenPtr = TokenAfter(valueTokenPtr);
- }
- TclEmitInstInt4(INST_LIST, numWords - 1, envPtr);
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileLlengthCmd --
- *
- * Procedure called to compile the "llength" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "llength" command at
- * runtime.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclCompileLlengthCmd(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Parse *parsePtr, /* Points to a parse structure for the command
- * created by Tcl_ParseCommand. */
- Command *cmdPtr, /* Points to defintion of command being
- * compiled. */
- CompileEnv *envPtr) /* Holds resulting instructions. */
-{
- Tcl_Token *varTokenPtr;
- DefineLineInformation; /* TIP #280 */
-
- if (parsePtr->numWords != 2) {
- return TCL_ERROR;
- }
- varTokenPtr = TokenAfter(parsePtr->tokenPtr);
-
- CompileWord(envPtr, varTokenPtr, interp, 1);
- TclEmitOpcode(INST_LIST_LENGTH, envPtr);
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileLsetCmd --
- *
- * Procedure called to compile the "lset" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "lset" command at
- * runtime.
- *
- * The general template for execution of the "lset" command is:
- * (1) Instructions to push the variable name, unless the variable is
- * local to the stack frame.
- * (2) If the variable is an array element, instructions to push the
- * array element name.
- * (3) Instructions to push each of zero or more "index" arguments to the
- * stack, followed with the "newValue" element.
- * (4) Instructions to duplicate the variable name and/or array element
- * name onto the top of the stack, if either was pushed at steps (1)
- * and (2).
- * (5) The appropriate INST_LOAD_* instruction to place the original
- * value of the list variable at top of stack.
- * (6) At this point, the stack contains:
- * varName? arrayElementName? index1 index2 ... newValue oldList
- * The compiler emits one of INST_LSET_FLAT or INST_LSET_LIST
- * according as whether there is exactly one index element (LIST) or
- * either zero or else two or more (FLAT). This instruction removes
- * everything from the stack except for the two names and pushes the
- * new value of the variable.
- * (7) Finally, INST_STORE_* stores the new value in the variable and
- * cleans up the stack.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclCompileLsetCmd(
- Tcl_Interp *interp, /* Tcl interpreter for error reporting. */
- Tcl_Parse *parsePtr, /* Points to a parse structure for the
- * command. */
- Command *cmdPtr, /* Points to defintion of command being
- * compiled. */
- CompileEnv *envPtr) /* Holds the resulting instructions. */
-{
- int tempDepth; /* Depth used for emitting one part of the
- * code burst. */
- Tcl_Token *varTokenPtr; /* Pointer to the Tcl_Token representing the
- * parse of the variable name. */
- int localIndex; /* Index of var in local var table. */
- int simpleVarName; /* Flag == 1 if var name is simple. */
- int isScalar; /* Flag == 1 if scalar, 0 if array. */
- int i;
- DefineLineInformation; /* TIP #280 */
-
- /*
- * Check argument count.
- */
-
- if (parsePtr->numWords < 3) {
- /*
- * Fail at run time, not in compilation.
- */
-
- return TCL_ERROR;
- }
-
- /*
- * Decide if we can use a frame slot for the var/array name or if we need
- * to emit code to compute and push the name at runtime. We use a frame
- * slot (entry in the array of local vars) if we are compiling a procedure
- * body and if the name is simple text that does not include namespace
- * qualifiers.
- */
-
- varTokenPtr = TokenAfter(parsePtr->tokenPtr);
- PushVarNameWord(interp, varTokenPtr, envPtr, 0,
- &localIndex, &simpleVarName, &isScalar, 1);
-
- /*
- * Push the "index" args and the new element value.
- */
-
- for (i=2 ; i<parsePtr->numWords ; ++i) {
- varTokenPtr = TokenAfter(varTokenPtr);
- CompileWord(envPtr, varTokenPtr, interp, i);
- }
-
- /*
- * Duplicate the variable name if it's been pushed.
- */
-
- if (!simpleVarName || localIndex < 0) {
- if (!simpleVarName || isScalar) {
- tempDepth = parsePtr->numWords - 2;
- } else {
- tempDepth = parsePtr->numWords - 1;
+ objv[i] = Tcl_NewObj();
+ Tcl_IncrRefCount(objv[i]);
+ if (!TclWordKnownAtCompileTime(tokenPtr, objv[i])) {
+ goto checkForStringConcatCase;
}
- TclEmitInstInt4(INST_OVER, tempDepth, envPtr);
}
/*
- * Duplicate an array index if one's been pushed.
+ * Everything is a literal, so the result is constant too (or an error if
+ * the format is broken). Do the format now.
*/
- if (simpleVarName && !isScalar) {
- if (localIndex < 0) {
- tempDepth = parsePtr->numWords - 1;
- } else {
- tempDepth = parsePtr->numWords - 2;
- }
- TclEmitInstInt4(INST_OVER, tempDepth, envPtr);
+ tmpObj = Tcl_Format(interp, Tcl_GetString(formatObj),
+ parsePtr->numWords-2, objv);
+ for (; --i>=0 ;) {
+ Tcl_DecrRefCount(objv[i]);
}
-
- /*
- * Emit code to load the variable's value.
- */
-
- if (!simpleVarName) {
- TclEmitOpcode(INST_LOAD_STK, envPtr);
- } else if (isScalar) {
- if (localIndex < 0) {
- TclEmitOpcode(INST_LOAD_SCALAR_STK, envPtr);
- } else if (localIndex < 0x100) {
- TclEmitInstInt1(INST_LOAD_SCALAR1, localIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_LOAD_SCALAR4, localIndex, envPtr);
- }
- } else {
- if (localIndex < 0) {
- TclEmitOpcode(INST_LOAD_ARRAY_STK, envPtr);
- } else if (localIndex < 0x100) {
- TclEmitInstInt1(INST_LOAD_ARRAY1, localIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_LOAD_ARRAY4, localIndex, envPtr);
- }
- }
-
- /*
- * Emit the correct variety of 'lset' instruction.
- */
-
- if (parsePtr->numWords == 4) {
- TclEmitOpcode(INST_LSET_LIST, envPtr);
- } else {
- TclEmitInstInt4(INST_LSET_FLAT, parsePtr->numWords-1, envPtr);
+ ckfree(objv);
+ Tcl_DecrRefCount(formatObj);
+ if (tmpObj == NULL) {
+ TclCompileSyntaxError(interp, envPtr);
+ return TCL_OK;
}
/*
- * Emit code to put the value back in the variable.
+ * Not an error, always a constant result, so just push the result as a
+ * literal. Job done.
*/
- if (!simpleVarName) {
- TclEmitOpcode(INST_STORE_STK, envPtr);
- } else if (isScalar) {
- if (localIndex < 0) {
- TclEmitOpcode(INST_STORE_SCALAR_STK, envPtr);
- } else if (localIndex < 0x100) {
- TclEmitInstInt1(INST_STORE_SCALAR1, localIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_STORE_SCALAR4, localIndex, envPtr);
- }
- } else {
- if (localIndex < 0) {
- TclEmitOpcode(INST_STORE_ARRAY_STK, envPtr);
- } else if (localIndex < 0x100) {
- TclEmitInstInt1(INST_STORE_ARRAY1, localIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_STORE_ARRAY4, localIndex, envPtr);
- }
- }
-
+ bytes = Tcl_GetStringFromObj(tmpObj, &len);
+ PushLiteral(envPtr, bytes, len);
+ Tcl_DecrRefCount(tmpObj);
return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileNamespaceCmd --
- *
- * Procedure called to compile the "namespace" command; currently, only
- * the subcommand "namespace upvar" is compiled to bytecodes, and then
- * only inside a procedure(-like) context.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "namespace upvar"
- * command at runtime.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclCompileNamespaceUpvarCmd(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Parse *parsePtr, /* Points to a parse structure for the command
- * created by Tcl_ParseCommand. */
- Command *cmdPtr, /* Points to defintion of command being
- * compiled. */
- CompileEnv *envPtr) /* Holds resulting instructions. */
-{
- Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr;
- int simpleVarName, isScalar, localIndex, numWords, i;
- DefineLineInformation; /* TIP #280 */
-
- if (envPtr->procPtr == NULL) {
- return TCL_ERROR;
- }
+ checkForStringConcatCase:
/*
- * Only compile [namespace upvar ...]: needs an even number of args, >=4
+ * See if we can generate a sequence of things to concatenate. This
+ * requires that all the % sequences be %s or %%, as everything else is
+ * sufficiently complex that we don't bother.
+ *
+ * First, get the state of the system relatively sensible (cleaning up
+ * after our attempt to spot a literal).
*/
- numWords = parsePtr->numWords;
- if ((numWords % 2) || (numWords < 4)) {
- return TCL_ERROR;
+ for (; i>=0 ; i--) {
+ Tcl_DecrRefCount(objv[i]);
}
-
- /*
- * Push the namespace
- */
-
+ ckfree(objv);
tokenPtr = TokenAfter(parsePtr->tokenPtr);
- CompileWord(envPtr, tokenPtr, interp, 1);
+ tokenPtr = TokenAfter(tokenPtr);
+ i = 0;
/*
- * Loop over the (otherVar, thisVar) pairs. If any of the thisVar is not a
- * local variable, return an error so that the non-compiled command will
- * be called at runtime.
+ * Now scan through and check for non-%s and non-%% substitutions.
*/
- localTokenPtr = tokenPtr;
- for (i=3; i<=numWords; i+=2) {
- otherTokenPtr = TokenAfter(localTokenPtr);
- localTokenPtr = TokenAfter(otherTokenPtr);
-
- CompileWord(envPtr, otherTokenPtr, interp, 1);
- PushVarNameWord(interp, localTokenPtr, envPtr, 0,
- &localIndex, &simpleVarName, &isScalar, 1);
-
- if ((localIndex < 0) || !isScalar) {
+ for (bytes = Tcl_GetString(formatObj) ; *bytes ; bytes++) {
+ if (*bytes == '%') {
+ bytes++;
+ if (*bytes == 's') {
+ i++;
+ continue;
+ } else if (*bytes == '%') {
+ continue;
+ }
+ Tcl_DecrRefCount(formatObj);
return TCL_ERROR;
}
- TclEmitInstInt4(INST_NSUPVAR, localIndex, envPtr);
- }
-
- /*
- * Pop the namespace, and set the result to empty
- */
-
- TclEmitOpcode(INST_POP, envPtr);
- PushLiteral(envPtr, "", 0);
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileRegexpCmd --
- *
- * Procedure called to compile the "regexp" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "regexp" command at
- * runtime.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclCompileRegexpCmd(
- Tcl_Interp *interp, /* Tcl interpreter for error reporting. */
- Tcl_Parse *parsePtr, /* Points to a parse structure for the
- * command. */
- Command *cmdPtr, /* Points to defintion of command being
- * compiled. */
- CompileEnv *envPtr) /* Holds the resulting instructions. */
-{
- Tcl_Token *varTokenPtr; /* Pointer to the Tcl_Token representing the
- * parse of the RE or string. */
- int i, len, nocase, exact, sawLast, simple;
- const char *str;
- DefineLineInformation; /* TIP #280 */
-
- /*
- * We are only interested in compiling simple regexp cases. Currently
- * supported compile cases are:
- * regexp ?-nocase? ?--? staticString $var
- * regexp ?-nocase? ?--? {^staticString$} $var
- */
-
- if (parsePtr->numWords < 3) {
- return TCL_ERROR;
}
- simple = 0;
- nocase = 0;
- sawLast = 0;
- varTokenPtr = parsePtr->tokenPtr;
-
/*
- * We only look for -nocase and -- as options. Everything else gets pushed
- * to runtime execution. This is different than regexp's runtime option
- * handling, but satisfies our stricter needs.
+ * Check if the number of things to concatenate will fit in a byte.
*/
- for (i = 1; i < parsePtr->numWords - 2; i++) {
- varTokenPtr = TokenAfter(varTokenPtr);
- if (varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- /*
- * Not a simple string, so punt to runtime.
- */
-
- return TCL_ERROR;
- }
- str = varTokenPtr[1].start;
- len = varTokenPtr[1].size;
- if ((len == 2) && (str[0] == '-') && (str[1] == '-')) {
- sawLast++;
- i++;
- break;
- } else if ((len > 1) && (strncmp(str,"-nocase",(unsigned)len) == 0)) {
- nocase = 1;
- } else {
- /*
- * Not an option we recognize.
- */
-
- return TCL_ERROR;
- }
- }
-
- if ((parsePtr->numWords - i) != 2) {
- /*
- * We don't support capturing to variables.
- */
-
+ if (i+2 != parsePtr->numWords || i > 125) {
+ Tcl_DecrRefCount(formatObj);
return TCL_ERROR;
}
/*
- * Get the regexp string. If it is not a simple string or can't be
- * converted to a glob pattern, push the word for the INST_REGEXP.
- * Keep changes here in sync with TclCompileSwitchCmd Switch_Regexp.
+ * Generate the pushes of the things to concatenate, a sequence of
+ * literals and compiled tokens (of which at least one is non-literal or
+ * we'd have the case in the first half of this function) which we will
+ * concatenate.
*/
- varTokenPtr = TokenAfter(varTokenPtr);
-
- if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- Tcl_DString ds;
-
- str = varTokenPtr[1].start;
- len = varTokenPtr[1].size;
-
- /*
- * If it has a '-', it could be an incorrectly formed regexp command.
- */
-
- if ((*str == '-') && !sawLast) {
- return TCL_ERROR;
- }
-
- if (len == 0) {
- /*
- * The semantics of regexp are always match on re == "".
- */
-
- PushLiteral(envPtr, "1", 1);
- return TCL_OK;
- }
-
- /*
- * Attempt to convert pattern to glob. If successful, push the
- * converted pattern as a literal.
- */
-
- if (TclReToGlob(NULL, varTokenPtr[1].start, len, &ds, &exact)
- == TCL_OK) {
- simple = 1;
- PushLiteral(envPtr, Tcl_DStringValue(&ds),Tcl_DStringLength(&ds));
- Tcl_DStringFree(&ds);
- }
- }
-
- if (!simple) {
- CompileWord(envPtr, varTokenPtr, interp, parsePtr->numWords-2);
- }
-
- /*
- * Push the string arg.
- */
-
- varTokenPtr = TokenAfter(varTokenPtr);
- CompileWord(envPtr, varTokenPtr, interp, parsePtr->numWords-1);
-
- if (simple) {
- if (exact && !nocase) {
- TclEmitOpcode(INST_STR_EQ, envPtr);
- } else {
- TclEmitInstInt1(INST_STR_MATCH, nocase, envPtr);
- }
- } else {
- /*
- * Pass correct RE compile flags. We use only Int1 (8-bit), but
- * that handles all the flags we want to pass.
- * Don't use TCL_REG_NOSUB as we may have backrefs.
- */
-
- int cflags = TCL_REG_ADVANCED | (nocase ? TCL_REG_NOCASE : 0);
-
- TclEmitInstInt1(INST_REGEXP, cflags, envPtr);
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileReturnCmd --
- *
- * Procedure called to compile the "return" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "return" command at
- * runtime.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclCompileReturnCmd(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Parse *parsePtr, /* Points to a parse structure for the command
- * created by Tcl_ParseCommand. */
- Command *cmdPtr, /* Points to defintion of command being
- * compiled. */
- CompileEnv *envPtr) /* Holds resulting instructions. */
-{
- /*
- * General syntax: [return ?-option value ...? ?result?]
- * An even number of words means an explicit result argument is present.
- */
- int level, code, objc, size, status = TCL_OK;
- int numWords = parsePtr->numWords;
- int explicitResult = (0 == (numWords % 2));
- int numOptionWords = numWords - 1 - explicitResult;
- Tcl_Obj *returnOpts, **objv;
- Tcl_Token *wordTokenPtr = TokenAfter(parsePtr->tokenPtr);
- DefineLineInformation; /* TIP #280 */
-
- /*
- * Check for special case which can always be compiled:
- * return -options <opts> <msg>
- * Unlike the normal [return] compilation, this version does everything at
- * runtime so it can handle arbitrary words and not just literals. Note
- * that if INST_RETURN_STK wasn't already needed for something else
- * ('finally' clause processing) this piece of code would not be present.
- */
-
- if ((numWords == 4) && (wordTokenPtr->type == TCL_TOKEN_SIMPLE_WORD)
- && (wordTokenPtr[1].size == 8)
- && (strncmp(wordTokenPtr[1].start, "-options", 8) == 0)) {
- Tcl_Token *optsTokenPtr = TokenAfter(wordTokenPtr);
- Tcl_Token *msgTokenPtr = TokenAfter(optsTokenPtr);
-
- CompileWord(envPtr, optsTokenPtr, interp, 2);
- CompileWord(envPtr, msgTokenPtr, interp, 3);
- TclEmitOpcode(INST_RETURN_STK, envPtr);
- return TCL_OK;
- }
-
- /*
- * Allocate some working space.
- */
-
- objv = TclStackAlloc(interp, numOptionWords * sizeof(Tcl_Obj *));
-
- /*
- * Scan through the return options. If any are unknown at compile time,
- * there is no value in bytecompiling. Save the option values known in an
- * objv array for merging into a return options dictionary.
- */
-
- for (objc = 0; objc < numOptionWords; objc++) {
- objv[objc] = Tcl_NewObj();
- Tcl_IncrRefCount(objv[objc]);
- if (!TclWordKnownAtCompileTime(wordTokenPtr, objv[objc])) {
- objc++;
- status = TCL_ERROR;
- goto cleanup;
- }
- wordTokenPtr = TokenAfter(wordTokenPtr);
- }
- status = TclMergeReturnOptions(interp, objc, objv,
- &returnOpts, &code, &level);
- cleanup:
- while (--objc >= 0) {
- TclDecrRefCount(objv[objc]);
- }
- TclStackFree(interp, objv);
- if (TCL_ERROR == status) {
- /*
- * Something was bogus in the return options. Clear the error message,
- * and report back to the compiler that this must be interpreted at
- * runtime.
- */
-
- Tcl_ResetResult(interp);
- return TCL_ERROR;
- }
-
- /*
- * All options are known at compile time, so we're going to bytecompile.
- * Emit instructions to push the result on the stack.
- */
-
- if (explicitResult) {
- CompileWord(envPtr, wordTokenPtr, interp, numWords-1);
- } else {
- /*
- * No explict result argument, so default result is empty string.
- */
-
- PushLiteral(envPtr, "", 0);
- }
-
- /*
- * Check for optimization: When [return] is in a proc, and there's no
- * enclosing [catch], and there are no return options, then the INST_DONE
- * instruction is equivalent, and may be more efficient.
- */
+ i = 0; /* The count of things to concat. */
+ j = 2; /* The index into the argument tokens, for
+ * TIP#280 handling. */
+ start = Tcl_GetString(formatObj);
+ /* The start of the currently-scanned literal
+ * in the format string. */
+ tmpObj = Tcl_NewObj(); /* The buffer used to accumulate the literal
+ * being built. */
+ for (bytes = start ; *bytes ; bytes++) {
+ if (*bytes == '%') {
+ Tcl_AppendToObj(tmpObj, start, bytes - start);
+ if (*++bytes == '%') {
+ Tcl_AppendToObj(tmpObj, "%", 1);
+ } else {
+ char *b = Tcl_GetStringFromObj(tmpObj, &len);
- if (numOptionWords == 0 && envPtr->procPtr != NULL) {
- /*
- * We have default return options and we're in a proc ...
- */
+ /*
+ * If there is a non-empty literal from the format string,
+ * push it and reset.
+ */
- int index = envPtr->exceptArrayNext - 1;
- int enclosingCatch = 0;
+ if (len > 0) {
+ PushLiteral(envPtr, b, len);
+ Tcl_DecrRefCount(tmpObj);
+ tmpObj = Tcl_NewObj();
+ i++;
+ }
- while (index >= 0) {
- ExceptionRange range = envPtr->exceptArrayPtr[index];
+ /*
+ * Push the code to produce the string that would be
+ * substituted with %s, except we'll be concatenating
+ * directly.
+ */
- if ((range.type == CATCH_EXCEPTION_RANGE)
- && (range.catchOffset == -1)) {
- enclosingCatch = 1;
- break;
+ CompileWord(envPtr, tokenPtr, interp, j);
+ tokenPtr = TokenAfter(tokenPtr);
+ j++;
+ i++;
}
- index--;
+ start = bytes + 1;
}
- if (!enclosingCatch) {
- /*
- * ... and there is no enclosing catch. Issue the maximally
- * efficient exit instruction.
- */
-
- Tcl_DecrRefCount(returnOpts);
- TclEmitOpcode(INST_DONE, envPtr);
- return TCL_OK;
- }
- }
-
- /* Optimize [return -level 0 $x]. */
- Tcl_DictObjSize(NULL, returnOpts, &size);
- if (size == 0 && level == 0 && code == TCL_OK) {
- Tcl_DecrRefCount(returnOpts);
- return TCL_OK;
}
/*
- * Could not use the optimization, so we push the return options dict, and
- * emit the INST_RETURN_IMM instruction with code and level as operands.
+ * Handle the case of a trailing literal.
*/
- CompileReturnInternal(envPtr, INST_RETURN_IMM, code, level, returnOpts);
- return TCL_OK;
-}
-
-static void
-CompileReturnInternal(
- CompileEnv *envPtr,
- unsigned char op,
- int code,
- int level,
- Tcl_Obj *returnOpts)
-{
- TclEmitPush(TclAddLiteralObj(envPtr, returnOpts, NULL), envPtr);
- TclEmitInstInt4(op, code, envPtr);
- TclEmitInt4(level, envPtr);
-}
-
-void
-TclCompileSyntaxError(
- Tcl_Interp *interp,
- CompileEnv *envPtr)
-{
- Tcl_Obj *msg = Tcl_GetObjResult(interp);
- int numBytes;
- const char *bytes = TclGetStringFromObj(msg, &numBytes);
-
- TclErrorStackResetIf(interp, bytes, numBytes);
- TclEmitPush(TclRegisterNewLiteral(envPtr, bytes, numBytes), envPtr);
- CompileReturnInternal(envPtr, INST_SYNTAX, TCL_ERROR, 0,
- TclNoErrorStack(interp, Tcl_GetReturnOptions(interp, TCL_ERROR)));
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileUpvarCmd --
- *
- * Procedure called to compile the "upvar" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "upvar" command at
- * runtime.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclCompileUpvarCmd(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Parse *parsePtr, /* Points to a parse structure for the command
- * created by Tcl_ParseCommand. */
- Command *cmdPtr, /* Points to defintion of command being
- * compiled. */
- CompileEnv *envPtr) /* Holds resulting instructions. */
-{
- Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr;
- int simpleVarName, isScalar, localIndex, numWords, i;
- DefineLineInformation; /* TIP #280 */
- Tcl_Obj *objPtr = Tcl_NewObj();
-
- if (envPtr->procPtr == NULL) {
- Tcl_DecrRefCount(objPtr);
- return TCL_ERROR;
- }
-
- numWords = parsePtr->numWords;
- if (numWords < 3) {
- Tcl_DecrRefCount(objPtr);
- return TCL_ERROR;
+ Tcl_AppendToObj(tmpObj, start, bytes - start);
+ bytes = Tcl_GetStringFromObj(tmpObj, &len);
+ if (len > 0) {
+ PushLiteral(envPtr, bytes, len);
+ i++;
}
+ Tcl_DecrRefCount(tmpObj);
+ Tcl_DecrRefCount(formatObj);
- /*
- * Push the frame index if it is known at compile time
- */
-
- tokenPtr = TokenAfter(parsePtr->tokenPtr);
- if (TclWordKnownAtCompileTime(tokenPtr, objPtr)) {
- CallFrame *framePtr;
- const Tcl_ObjType *newTypePtr, *typePtr = objPtr->typePtr;
-
+ if (i > 1) {
/*
- * Attempt to convert to a level reference. Note that TclObjGetFrame
- * only changes the obj type when a conversion was successful.
+ * Do the concatenation, which produces the result.
*/
- TclObjGetFrame(interp, objPtr, &framePtr);
- newTypePtr = objPtr->typePtr;
- Tcl_DecrRefCount(objPtr);
-
- if (newTypePtr != typePtr) {
- if (numWords%2) {
- return TCL_ERROR;
- }
- CompileWord(envPtr, tokenPtr, interp, 1);
- otherTokenPtr = TokenAfter(tokenPtr);
- i = 4;
- } else {
- if (!(numWords%2)) {
- return TCL_ERROR;
- }
- PushLiteral(envPtr, "1", 1);
- otherTokenPtr = tokenPtr;
- i = 3;
- }
+ TclEmitInstInt1(INST_STR_CONCAT1, i, envPtr);
} else {
- Tcl_DecrRefCount(objPtr);
- return TCL_ERROR;
- }
-
- /*
- * Loop over the (otherVar, thisVar) pairs. If any of the thisVar is not a
- * local variable, return an error so that the non-compiled command will
- * be called at runtime.
- */
-
- for (; i<=numWords; i+=2, otherTokenPtr = TokenAfter(localTokenPtr)) {
- localTokenPtr = TokenAfter(otherTokenPtr);
-
- CompileWord(envPtr, otherTokenPtr, interp, 1);
- PushVarNameWord(interp, localTokenPtr, envPtr, 0,
- &localIndex, &simpleVarName, &isScalar, 1);
-
- if ((localIndex < 0) || !isScalar) {
- return TCL_ERROR;
- }
- TclEmitInstInt4(INST_UPVAR, localIndex, envPtr);
- }
-
- /*
- * Pop the frame index, and set the result to empty
- */
-
- TclEmitOpcode(INST_POP, envPtr);
- PushLiteral(envPtr, "", 0);
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileVariableCmd --
- *
- * Procedure called to compile the "variable" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "variable" command at
- * runtime.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclCompileVariableCmd(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Parse *parsePtr, /* Points to a parse structure for the command
- * created by Tcl_ParseCommand. */
- Command *cmdPtr, /* Points to defintion of command being
- * compiled. */
- CompileEnv *envPtr) /* Holds resulting instructions. */
-{
- Tcl_Token *varTokenPtr, *valueTokenPtr;
- int localIndex, numWords, i;
- DefineLineInformation; /* TIP #280 */
-
- numWords = parsePtr->numWords;
- if (numWords < 2) {
- return TCL_ERROR;
- }
-
- /*
- * Bail out if not compiling a proc body
- */
-
- if (envPtr->procPtr == NULL) {
- return TCL_ERROR;
- }
-
- /*
- * Loop over the (var, value) pairs.
- */
-
- valueTokenPtr = parsePtr->tokenPtr;
- for (i=2; i<=numWords; i+=2) {
- varTokenPtr = TokenAfter(valueTokenPtr);
- valueTokenPtr = TokenAfter(varTokenPtr);
-
- localIndex = IndexTailVarIfKnown(interp, varTokenPtr, envPtr);
-
- if (localIndex < 0) {
- return TCL_ERROR;
- }
-
- CompileWord(envPtr, varTokenPtr, interp, 1);
- TclEmitInstInt4(INST_VARIABLE, localIndex, envPtr);
-
- if (i != numWords) {
- /*
- * A value has been given: set the variable, pop the value
- */
-
- CompileWord(envPtr, valueTokenPtr, interp, 1);
- if (localIndex < 0x100) {
- TclEmitInstInt1(INST_STORE_SCALAR1, localIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_STORE_SCALAR4, localIndex, envPtr);
- }
- TclEmitOpcode(INST_POP, envPtr);
- }
- }
-
- /*
- * Set the result to empty
- */
-
- PushLiteral(envPtr, "", 0);
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * IndexTailVarIfKnown --
- *
- * Procedure used in compiling [global] and [variable] commands. It
- * inspects the variable name described by varTokenPtr and, if the tail
- * is known at compile time, defines a corresponding local variable.
- *
- * Results:
- * Returns the variable's index in the table of compiled locals if the
- * tail is known at compile time, or -1 otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-IndexTailVarIfKnown(
- Tcl_Interp *interp,
- Tcl_Token *varTokenPtr, /* Token representing the variable name */
- CompileEnv *envPtr) /* Holds resulting instructions. */
-{
- Tcl_Obj *tailPtr;
- const char *tailName, *p;
- int len, n = varTokenPtr->numComponents;
- Tcl_Token *lastTokenPtr;
- int full, localIndex;
-
- /*
- * Determine if the tail is (a) known at compile time, and (b) not an
- * array element. Should any of these fail, return an error so that the
- * non-compiled command will be called at runtime.
- *
- * In order for the tail to be known at compile time, the last token in
- * the word has to be constant and contain "::" if it is not the only one.
- */
-
- if (!EnvHasLVT(envPtr)) {
- return -1;
- }
-
- TclNewObj(tailPtr);
- if (TclWordKnownAtCompileTime(varTokenPtr, tailPtr)) {
- full = 1;
- lastTokenPtr = varTokenPtr;
- } else {
- full = 0;
- lastTokenPtr = varTokenPtr + n;
- if (!TclWordKnownAtCompileTime(lastTokenPtr, tailPtr)) {
- Tcl_DecrRefCount(tailPtr);
- return -1;
- }
- }
-
- tailName = TclGetStringFromObj(tailPtr, &len);
-
- if (len) {
- if (*(tailName+len-1) == ')') {
- /*
- * Possible array: bail out
- */
-
- Tcl_DecrRefCount(tailPtr);
- return -1;
- }
-
/*
- * Get the tail: immediately after the last '::'
+ * EVIL HACK! Force there to be a string representation in the case
+ * where there's just a "%s" in the format; case covered by the test
+ * format-20.1 (and it is horrible...)
*/
- for (p = tailName + len -1; p > tailName; p--) {
- if ((*p == ':') && (*(p-1) == ':')) {
- p++;
- break;
- }
- }
- if (!full && (p == tailName)) {
- /*
- * No :: in the last component.
- */
-
- Tcl_DecrRefCount(tailPtr);
- return -1;
- }
- len -= p - tailName;
- tailName = p;
+ TclEmitOpcode(INST_DUP, envPtr);
+ PushStringLiteral(envPtr, "");
+ TclEmitOpcode(INST_STR_EQ, envPtr);
+ TclEmitOpcode(INST_POP, envPtr);
}
-
- localIndex = TclFindCompiledLocal(tailName, len, 1, envPtr);
- Tcl_DecrRefCount(tailPtr);
- return localIndex;
+ return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * PushVarName --
+ * TclPushVarName --
*
* Procedure used in the compiling where pushing a variable name is
* necessary (append, lappend, set).
*
* Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
+ * The values written to *localIndexPtr and *isScalarPtr signal to
+ * the caller what the instructions emitted by this routine will do:
+ *
+ * *isScalarPtr (*localIndexPtr < 0)
+ * 1 1 Push the varname on the stack. (Stack +1)
+ * 1 0 *localIndexPtr is the index of the compiled
+ * local for this varname. No instructions
+ * emitted. (Stack +0)
+ * 0 1 Push part1 and part2 names of array element
+ * on the stack. (Stack +2)
+ * 0 0 *localIndexPtr is the index of the compiled
+ * local for this array. Element name is pushed
+ * on the stack. (Stack +1)
*
* Side effects:
- * Instructions are added to envPtr to execute the "set" command at
- * runtime.
+ * Instructions are added to envPtr.
*
*----------------------------------------------------------------------
*/
-static int
-PushVarName(
+void
+TclPushVarName(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Token *varTokenPtr, /* Points to a variable token. */
CompileEnv *envPtr, /* Holds resulting instructions. */
- int flags, /* TCL_NO_LARGE_INDEX. */
+ int flags, /* TCL_NO_LARGE_INDEX | TCL_NO_ELEMENT. */
int *localIndexPtr, /* Must not be NULL. */
- int *simpleVarNamePtr, /* Must not be NULL. */
- int *isScalarPtr, /* Must not be NULL. */
- int line, /* Line the token starts on. */
- int *clNext) /* Reference to offset of next hidden cont.
- * line. */
+ int *isScalarPtr) /* Must not be NULL. */
{
register const char *p;
const char *name, *elName;
@@ -4127,8 +3310,7 @@ PushVarName(
*/
if (!hasNsQualifiers) {
- localIndex = TclFindCompiledLocal(name, nameChars,
- 1, envPtr);
+ localIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr);
if ((flags & TCL_NO_LARGE_INDEX) && (localIndex > 255)) {
/*
* We'll push the name.
@@ -4142,17 +3324,16 @@ PushVarName(
}
/*
- * Compile the element script, if any.
+ * Compile the element script, if any, and only if not inhibited. [Bug
+ * 3600328]
*/
- if (elName != NULL) {
+ if (elName != NULL && !(flags & TCL_NO_ELEMENT)) {
if (elNameChars) {
- envPtr->line = line;
- envPtr->clNext = clNext;
TclCompileTokens(interp, elemTokenPtr, elemTokenCount,
envPtr);
} else {
- PushLiteral(envPtr, "", 0);
+ PushStringLiteral(envPtr, "");
}
}
} else {
@@ -4160,8 +3341,6 @@ PushVarName(
* The var name isn't simple: compile and push it.
*/
- envPtr->line = line;
- envPtr->clNext = clNext;
CompileTokens(envPtr, varTokenPtr, interp);
}
@@ -4172,9 +3351,7 @@ PushVarName(
TclStackFree(interp, elemTokenPtr);
}
*localIndexPtr = localIndex;
- *simpleVarNamePtr = simpleVarName;
*isScalarPtr = (elName == NULL);
- return TCL_OK;
}
/*
diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c
new file mode 100644
index 0000000..b3e273f
--- /dev/null
+++ b/generic/tclCompCmdsGR.c
@@ -0,0 +1,3171 @@
+/*
+ * tclCompCmdsGR.c --
+ *
+ * This file contains compilation procedures that compile various Tcl
+ * commands (beginning with the letters 'g' through 'r') into a sequence
+ * of instructions ("bytecodes").
+ *
+ * Copyright (c) 1997-1998 Sun Microsystems, Inc.
+ * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
+ * Copyright (c) 2002 ActiveState Corporation.
+ * Copyright (c) 2004-2013 by Donal K. Fellows.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h"
+#include <assert.h>
+
+/*
+ * Prototypes for procedures defined later in this file:
+ */
+
+static void CompileReturnInternal(CompileEnv *envPtr,
+ unsigned char op, int code, int level,
+ Tcl_Obj *returnOpts);
+static int IndexTailVarIfKnown(Tcl_Interp *interp,
+ Tcl_Token *varTokenPtr, CompileEnv *envPtr);
+
+#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;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileGlobalCmd --
+ *
+ * Procedure called to compile the "global" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "global" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileGlobalCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *varTokenPtr;
+ int localIndex, numWords, i;
+ DefineLineInformation; /* TIP #280 */
+
+ /* TODO: Consider support for compiling expanded args. */
+ numWords = parsePtr->numWords;
+ if (numWords < 2) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * 'global' has no effect outside of proc bodies; handle that at runtime
+ */
+
+ if (envPtr->procPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Push the namespace
+ */
+
+ PushStringLiteral(envPtr, "::");
+
+ /*
+ * Loop over the variables.
+ */
+
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ for (i=1; i<numWords; varTokenPtr = TokenAfter(varTokenPtr),i++) {
+ localIndex = IndexTailVarIfKnown(interp, varTokenPtr, envPtr);
+
+ if (localIndex < 0) {
+ return TCL_ERROR;
+ }
+
+ /* TODO: Consider what value can pass throug the
+ * IndexTailVarIfKnown() screen. Full CompileWord()
+ * likely does not apply here. Push known value instead. */
+ CompileWord(envPtr, varTokenPtr, interp, i);
+ TclEmitInstInt4( INST_NSUPVAR, localIndex, envPtr);
+ }
+
+ /*
+ * Pop the namespace, and set the result to empty
+ */
+
+ TclEmitOpcode( INST_POP, envPtr);
+ PushStringLiteral(envPtr, "");
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileIfCmd --
+ *
+ * Procedure called to compile the "if" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "if" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileIfCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ JumpFixupArray jumpFalseFixupArray;
+ /* Used to fix the ifFalse jump after each
+ * test when its target PC is determined. */
+ JumpFixupArray jumpEndFixupArray;
+ /* Used to fix the jump after each "then" body
+ * to the end of the "if" when that PC is
+ * determined. */
+ Tcl_Token *tokenPtr, *testTokenPtr;
+ int jumpIndex = 0; /* Avoid compiler warning. */
+ int jumpFalseDist, numWords, wordIdx, numBytes, j, code;
+ const char *word;
+ int realCond = 1; /* Set to 0 for static conditions:
+ * "if 0 {..}" */
+ int boolVal; /* Value of static condition. */
+ int compileScripts = 1;
+ DefineLineInformation; /* TIP #280 */
+
+ /*
+ * Only compile the "if" command if all arguments are simple words, in
+ * order to insure correct substitution [Bug 219166]
+ */
+
+ tokenPtr = parsePtr->tokenPtr;
+ wordIdx = 0;
+ numWords = parsePtr->numWords;
+
+ for (wordIdx = 0; wordIdx < numWords; wordIdx++) {
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ return TCL_ERROR;
+ }
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+
+ TclInitJumpFixupArray(&jumpFalseFixupArray);
+ TclInitJumpFixupArray(&jumpEndFixupArray);
+ code = TCL_OK;
+
+ /*
+ * Each iteration of this loop compiles one "if expr ?then? body" or
+ * "elseif expr ?then? body" clause.
+ */
+
+ tokenPtr = parsePtr->tokenPtr;
+ wordIdx = 0;
+ while (wordIdx < numWords) {
+ /*
+ * Stop looping if the token isn't "if" or "elseif".
+ */
+
+ word = tokenPtr[1].start;
+ numBytes = tokenPtr[1].size;
+ if ((tokenPtr == parsePtr->tokenPtr)
+ || ((numBytes == 6) && (strncmp(word, "elseif", 6) == 0))) {
+ tokenPtr = TokenAfter(tokenPtr);
+ wordIdx++;
+ } else {
+ break;
+ }
+ if (wordIdx >= numWords) {
+ code = TCL_ERROR;
+ goto done;
+ }
+
+ /*
+ * Compile the test expression then emit the conditional jump around
+ * the "then" part.
+ */
+
+ testTokenPtr = tokenPtr;
+
+ if (realCond) {
+ /*
+ * Find out if the condition is a constant.
+ */
+
+ Tcl_Obj *boolObj = Tcl_NewStringObj(testTokenPtr[1].start,
+ testTokenPtr[1].size);
+
+ Tcl_IncrRefCount(boolObj);
+ code = Tcl_GetBooleanFromObj(NULL, boolObj, &boolVal);
+ TclDecrRefCount(boolObj);
+ if (code == TCL_OK) {
+ /*
+ * A static condition.
+ */
+
+ realCond = 0;
+ if (!boolVal) {
+ compileScripts = 0;
+ }
+ } else {
+ SetLineInformation(wordIdx);
+ Tcl_ResetResult(interp);
+ TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
+ TclClearNumConversion(envPtr);
+ if (jumpFalseFixupArray.next >= jumpFalseFixupArray.end) {
+ TclExpandJumpFixupArray(&jumpFalseFixupArray);
+ }
+ jumpIndex = jumpFalseFixupArray.next;
+ jumpFalseFixupArray.next++;
+ TclEmitForwardJump(envPtr, TCL_FALSE_JUMP,
+ jumpFalseFixupArray.fixup+jumpIndex);
+ }
+ code = TCL_OK;
+ }
+
+ /*
+ * Skip over the optional "then" before the then clause.
+ */
+
+ tokenPtr = TokenAfter(testTokenPtr);
+ wordIdx++;
+ if (wordIdx >= numWords) {
+ code = TCL_ERROR;
+ goto done;
+ }
+ if (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+ word = tokenPtr[1].start;
+ numBytes = tokenPtr[1].size;
+ if ((numBytes == 4) && (strncmp(word, "then", 4) == 0)) {
+ tokenPtr = TokenAfter(tokenPtr);
+ wordIdx++;
+ if (wordIdx >= numWords) {
+ code = TCL_ERROR;
+ goto done;
+ }
+ }
+ }
+
+ /*
+ * Compile the "then" command body.
+ */
+
+ if (compileScripts) {
+ BODY(tokenPtr, wordIdx);
+ }
+
+ if (realCond) {
+ /*
+ * Jump to the end of the "if" command. Both jumpFalseFixupArray
+ * and jumpEndFixupArray are indexed by "jumpIndex".
+ */
+
+ if (jumpEndFixupArray.next >= jumpEndFixupArray.end) {
+ TclExpandJumpFixupArray(&jumpEndFixupArray);
+ }
+ jumpEndFixupArray.next++;
+ TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
+ jumpEndFixupArray.fixup+jumpIndex);
+
+ /*
+ * Fix the target of the jumpFalse after the test. Generate a 4
+ * byte jump if the distance is > 120 bytes. This is conservative,
+ * and ensures that we won't have to replace this jump if we later
+ * also need to replace the proceeding jump to the end of the "if"
+ * with a 4 byte jump.
+ */
+
+ TclAdjustStackDepth(-1, envPtr);
+ if (TclFixupForwardJumpToHere(envPtr,
+ jumpFalseFixupArray.fixup+jumpIndex, 120)) {
+ /*
+ * Adjust the code offset for the proceeding jump to the end
+ * of the "if" command.
+ */
+
+ jumpEndFixupArray.fixup[jumpIndex].codeOffset += 3;
+ }
+ } else if (boolVal) {
+ /*
+ * We were processing an "if 1 {...}"; stop compiling scripts.
+ */
+
+ compileScripts = 0;
+ } else {
+ /*
+ * We were processing an "if 0 {...}"; reset so that the rest
+ * (elseif, else) is compiled correctly.
+ */
+
+ realCond = 1;
+ compileScripts = 1;
+ }
+
+ tokenPtr = TokenAfter(tokenPtr);
+ wordIdx++;
+ }
+
+ /*
+ * Check for the optional else clause. Do not compile anything if this was
+ * an "if 1 {...}" case.
+ */
+
+ if ((wordIdx < numWords) && (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD)) {
+ /*
+ * There is an else clause. Skip over the optional "else" word.
+ */
+
+ word = tokenPtr[1].start;
+ numBytes = tokenPtr[1].size;
+ if ((numBytes == 4) && (strncmp(word, "else", 4) == 0)) {
+ tokenPtr = TokenAfter(tokenPtr);
+ wordIdx++;
+ if (wordIdx >= numWords) {
+ code = TCL_ERROR;
+ goto done;
+ }
+ }
+
+ if (compileScripts) {
+ /*
+ * Compile the else command body.
+ */
+
+ BODY(tokenPtr, wordIdx);
+ }
+
+ /*
+ * Make sure there are no words after the else clause.
+ */
+
+ wordIdx++;
+ if (wordIdx < numWords) {
+ code = TCL_ERROR;
+ goto done;
+ }
+ } else {
+ /*
+ * No else clause: the "if" command's result is an empty string.
+ */
+
+ if (compileScripts) {
+ PushStringLiteral(envPtr, "");
+ }
+ }
+
+ /*
+ * Fix the unconditional jumps to the end of the "if" command.
+ */
+
+ for (j = jumpEndFixupArray.next; j > 0; j--) {
+ jumpIndex = (j - 1); /* i.e. process the closest jump first. */
+ if (TclFixupForwardJumpToHere(envPtr,
+ jumpEndFixupArray.fixup+jumpIndex, 127)) {
+ /*
+ * Adjust the immediately preceeding "ifFalse" jump. We moved it's
+ * target (just after this jump) down three bytes.
+ */
+
+ unsigned char *ifFalsePc = envPtr->codeStart
+ + jumpFalseFixupArray.fixup[jumpIndex].codeOffset;
+ unsigned char opCode = *ifFalsePc;
+
+ if (opCode == INST_JUMP_FALSE1) {
+ jumpFalseDist = TclGetInt1AtPtr(ifFalsePc + 1);
+ jumpFalseDist += 3;
+ TclStoreInt1AtPtr(jumpFalseDist, (ifFalsePc + 1));
+ } else if (opCode == INST_JUMP_FALSE4) {
+ jumpFalseDist = TclGetInt4AtPtr(ifFalsePc + 1);
+ jumpFalseDist += 3;
+ TclStoreInt4AtPtr(jumpFalseDist, (ifFalsePc + 1));
+ } else {
+ Tcl_Panic("TclCompileIfCmd: unexpected opcode \"%d\" updating ifFalse jump", (int) opCode);
+ }
+ }
+ }
+
+ /*
+ * Free the jumpFixupArray array if malloc'ed storage was used.
+ */
+
+ done:
+ TclFreeJumpFixupArray(&jumpFalseFixupArray);
+ TclFreeJumpFixupArray(&jumpEndFixupArray);
+ return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileIncrCmd --
+ *
+ * Procedure called to compile the "incr" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "incr" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileIncrCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *varTokenPtr, *incrTokenPtr;
+ int isScalar, localIndex, haveImmValue, immValue;
+ DefineLineInformation; /* TIP #280 */
+
+ if ((parsePtr->numWords != 2) && (parsePtr->numWords != 3)) {
+ return TCL_ERROR;
+ }
+
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+ PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_LARGE_INDEX,
+ &localIndex, &isScalar, 1);
+
+ /*
+ * If an increment is given, push it, but see first if it's a small
+ * integer.
+ */
+
+ haveImmValue = 0;
+ immValue = 1;
+ if (parsePtr->numWords == 3) {
+ incrTokenPtr = TokenAfter(varTokenPtr);
+ if (incrTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+ const char *word = incrTokenPtr[1].start;
+ int numBytes = incrTokenPtr[1].size;
+ int code;
+ Tcl_Obj *intObj = Tcl_NewStringObj(word, numBytes);
+
+ Tcl_IncrRefCount(intObj);
+ code = TclGetIntFromObj(NULL, intObj, &immValue);
+ TclDecrRefCount(intObj);
+ if ((code == TCL_OK) && (-127 <= immValue) && (immValue <= 127)) {
+ haveImmValue = 1;
+ }
+ if (!haveImmValue) {
+ PushLiteral(envPtr, word, numBytes);
+ }
+ } else {
+ SetLineInformation(2);
+ CompileTokens(envPtr, incrTokenPtr, interp);
+ TclClearNumConversion(envPtr);
+ }
+ } else { /* No incr amount given so use 1. */
+ haveImmValue = 1;
+ }
+
+ /*
+ * Emit the instruction to increment the variable.
+ */
+
+ if (isScalar) { /* Simple scalar variable. */
+ if (localIndex >= 0) {
+ if (haveImmValue) {
+ TclEmitInstInt1(INST_INCR_SCALAR1_IMM, localIndex, envPtr);
+ TclEmitInt1(immValue, envPtr);
+ } else {
+ TclEmitInstInt1(INST_INCR_SCALAR1, localIndex, envPtr);
+ }
+ } else {
+ if (haveImmValue) {
+ TclEmitInstInt1(INST_INCR_STK_IMM, immValue, envPtr);
+ } else {
+ TclEmitOpcode( INST_INCR_STK, envPtr);
+ }
+ }
+ } else { /* Simple array variable. */
+ if (localIndex >= 0) {
+ if (haveImmValue) {
+ TclEmitInstInt1(INST_INCR_ARRAY1_IMM, localIndex, envPtr);
+ TclEmitInt1(immValue, envPtr);
+ } else {
+ TclEmitInstInt1(INST_INCR_ARRAY1, localIndex, envPtr);
+ }
+ } else {
+ if (haveImmValue) {
+ TclEmitInstInt1(INST_INCR_ARRAY_STK_IMM, immValue, envPtr);
+ } else {
+ TclEmitOpcode( INST_INCR_ARRAY_STK, envPtr);
+ }
+ }
+ }
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileInfo*Cmd --
+ *
+ * Procedures called to compile "info" subcommands.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "info" subcommand at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileInfoCommandsCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr;
+ Tcl_Obj *objPtr;
+ char *bytes;
+
+ /*
+ * We require one compile-time known argument for the case we can compile.
+ */
+
+ if (parsePtr->numWords == 1) {
+ return TclCompileBasic0ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ } else if (parsePtr->numWords != 2) {
+ return TCL_ERROR;
+ }
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ objPtr = Tcl_NewObj();
+ Tcl_IncrRefCount(objPtr);
+ if (!TclWordKnownAtCompileTime(tokenPtr, objPtr)) {
+ goto notCompilable;
+ }
+ bytes = Tcl_GetString(objPtr);
+
+ /*
+ * We require that the argument start with "::" and not have any of "*\[?"
+ * in it. (Theoretically, we should look in only the final component, but
+ * the difference is so slight given current naming practices.)
+ */
+
+ if (bytes[0] != ':' || bytes[1] != ':' || !TclMatchIsTrivial(bytes)) {
+ goto notCompilable;
+ }
+ Tcl_DecrRefCount(objPtr);
+
+ /*
+ * Confirmed as a literal that will not frighten the horses. Compile. Note
+ * that the result needs to be list-ified.
+ */
+
+ /* TODO: Just push the known value */
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ TclEmitOpcode( INST_RESOLVE_COMMAND, envPtr);
+ TclEmitOpcode( INST_DUP, envPtr);
+ TclEmitOpcode( INST_STR_LEN, envPtr);
+ TclEmitInstInt1( INST_JUMP_FALSE1, 7, envPtr);
+ TclEmitInstInt4( INST_LIST, 1, envPtr);
+ return TCL_OK;
+
+ notCompilable:
+ Tcl_DecrRefCount(objPtr);
+ return TclCompileBasic1ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileInfoCoroutineCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Only compile [info coroutine] without arguments.
+ */
+
+ if (parsePtr->numWords != 1) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Not much to do; we compile to a single instruction...
+ */
+
+ TclEmitOpcode( INST_COROUTINE_NAME, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileInfoExistsCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *tokenPtr;
+ int isScalar, localIndex;
+ DefineLineInformation; /* TIP #280 */
+
+ if (parsePtr->numWords != 2) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Decide if we can use a frame slot for the var/array name or if we need
+ * to emit code to compute and push the name at runtime. We use a frame
+ * slot (entry in the array of local vars) if we are compiling a procedure
+ * body and if the name is simple text that does not include namespace
+ * qualifiers.
+ */
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ PushVarNameWord(interp, tokenPtr, envPtr, 0, &localIndex, &isScalar, 1);
+
+ /*
+ * Emit instruction to check the variable for existence.
+ */
+
+ if (isScalar) {
+ if (localIndex < 0) {
+ TclEmitOpcode( INST_EXIST_STK, envPtr);
+ } else {
+ TclEmitInstInt4( INST_EXIST_SCALAR, localIndex, envPtr);
+ }
+ } else {
+ if (localIndex < 0) {
+ TclEmitOpcode( INST_EXIST_ARRAY_STK, envPtr);
+ } else {
+ TclEmitInstInt4( INST_EXIST_ARRAY, localIndex, envPtr);
+ }
+ }
+
+ return TCL_OK;
+}
+
+int
+TclCompileInfoLevelCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Only compile [info level] without arguments or with a single argument.
+ */
+
+ if (parsePtr->numWords == 1) {
+ /*
+ * Not much to do; we compile to a single instruction...
+ */
+
+ TclEmitOpcode( INST_INFO_LEVEL_NUM, envPtr);
+ } else if (parsePtr->numWords != 2) {
+ return TCL_ERROR;
+ } else {
+ DefineLineInformation; /* TIP #280 */
+
+ /*
+ * Compile the argument, then add the instruction to convert it into a
+ * list of arguments.
+ */
+
+ CompileWord(envPtr, TokenAfter(parsePtr->tokenPtr), interp, 1);
+ TclEmitOpcode( INST_INFO_LEVEL_ARGS, envPtr);
+ }
+ return TCL_OK;
+}
+
+int
+TclCompileInfoObjectClassCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+ if (parsePtr->numWords != 2) {
+ return TCL_ERROR;
+ }
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ TclEmitOpcode( INST_TCLOO_CLASS, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileInfoObjectIsACmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+ /*
+ * We only handle [info object isa object <somevalue>]. The first three
+ * words are compressed to a single token by the ensemble compilation
+ * engine.
+ */
+
+ if (parsePtr->numWords != 3) {
+ return TCL_ERROR;
+ }
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD || tokenPtr[1].size < 1
+ || strncmp(tokenPtr[1].start, "object", tokenPtr[1].size)) {
+ return TCL_ERROR;
+ }
+ tokenPtr = TokenAfter(tokenPtr);
+
+ /*
+ * Issue the code.
+ */
+
+ CompileWord(envPtr, tokenPtr, interp, 2);
+ TclEmitOpcode( INST_TCLOO_IS_OBJECT, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileInfoObjectNamespaceCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+ if (parsePtr->numWords != 2) {
+ return TCL_ERROR;
+ }
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ TclEmitOpcode( INST_TCLOO_NS, envPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLappendCmd --
+ *
+ * Procedure called to compile the "lappend" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "lappend" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLappendCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *varTokenPtr, *valueTokenPtr;
+ int isScalar, localIndex, numWords, i, fwd, offsetFwd;
+ DefineLineInformation; /* TIP #280 */
+
+ /*
+ * If we're not in a procedure, don't compile.
+ */
+
+ if (envPtr->procPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ /* TODO: Consider support for compiling expanded args. */
+ numWords = parsePtr->numWords;
+ if (numWords == 1) {
+ return TCL_ERROR;
+ }
+ if (numWords != 3) {
+ /*
+ * LAPPEND instructions currently only handle one value, but we can
+ * handle some multi-value cases by stringing them together.
+ */
+
+ goto lappendMultiple;
+ }
+
+ /*
+ * Decide if we can use a frame slot for the var/array name or if we
+ * need to emit code to compute and push the name at runtime. We use a
+ * frame slot (entry in the array of local vars) if we are compiling a
+ * procedure body and if the name is simple text that does not include
+ * namespace qualifiers.
+ */
+
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+ PushVarNameWord(interp, varTokenPtr, envPtr, 0,
+ &localIndex, &isScalar, 1);
+
+ /*
+ * If we are doing an assignment, push the new value. In the no values
+ * case, create an empty object.
+ */
+
+ if (numWords > 2) {
+ Tcl_Token *valueTokenPtr = TokenAfter(varTokenPtr);
+
+ CompileWord(envPtr, valueTokenPtr, interp, 2);
+ }
+
+ /*
+ * Emit instructions to set/get the variable.
+ */
+
+ /*
+ * The *_STK opcodes should be refactored to make better use of existing
+ * LOAD/STORE instructions.
+ */
+
+ if (isScalar) {
+ if (localIndex < 0) {
+ TclEmitOpcode( INST_LAPPEND_STK, envPtr);
+ } else {
+ Emit14Inst( INST_LAPPEND_SCALAR, localIndex, envPtr);
+ }
+ } else {
+ if (localIndex < 0) {
+ TclEmitOpcode( INST_LAPPEND_ARRAY_STK, envPtr);
+ } else {
+ Emit14Inst( INST_LAPPEND_ARRAY, localIndex, envPtr);
+ }
+ }
+
+ return TCL_OK;
+
+ lappendMultiple:
+ /*
+ * Can only handle the case where we are appending to a local scalar when
+ * there are multiple values to append. Fortunately, this is common.
+ */
+
+ if (envPtr->procPtr == NULL) {
+ return TCL_ERROR;
+ }
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_ELEMENT,
+ &localIndex, &isScalar, 1);
+ if (!isScalar || localIndex < 0) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Definitely appending to a local scalar; generate the words and append
+ * them.
+ */
+
+ valueTokenPtr = TokenAfter(varTokenPtr);
+ for (i = 2 ; i < numWords ; i++) {
+ CompileWord(envPtr, valueTokenPtr, interp, i);
+ valueTokenPtr = TokenAfter(valueTokenPtr);
+ }
+ TclEmitInstInt4( INST_LIST, numWords-2, envPtr);
+ TclEmitInstInt4( INST_EXIST_SCALAR, localIndex, envPtr);
+ offsetFwd = CurrentOffset(envPtr);
+ TclEmitInstInt1( INST_JUMP_FALSE1, 0, envPtr);
+ Emit14Inst( INST_LOAD_SCALAR, localIndex, envPtr);
+ TclEmitInstInt4( INST_REVERSE, 2, envPtr);
+ TclEmitOpcode( INST_LIST_CONCAT, envPtr);
+ fwd = CurrentOffset(envPtr) - offsetFwd;
+ TclStoreInt1AtPtr(fwd, envPtr->codeStart+offsetFwd+1);
+ Emit14Inst( INST_STORE_SCALAR, localIndex, envPtr);
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLassignCmd --
+ *
+ * Procedure called to compile the "lassign" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "lassign" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLassignCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *tokenPtr;
+ int isScalar, localIndex, numWords, idx;
+ DefineLineInformation; /* TIP #280 */
+
+ numWords = parsePtr->numWords;
+
+ /*
+ * Check for command syntax error, but we'll punt that to runtime.
+ */
+
+ if (numWords < 3) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Generate code to push list being taken apart by [lassign].
+ */
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+
+ /*
+ * Generate code to assign values from the list to variables.
+ */
+
+ for (idx=0 ; idx<numWords-2 ; idx++) {
+ tokenPtr = TokenAfter(tokenPtr);
+
+ /*
+ * Generate the next variable name.
+ */
+
+ PushVarNameWord(interp, tokenPtr, envPtr, 0, &localIndex,
+ &isScalar, idx+2);
+
+ /*
+ * Emit instructions to get the idx'th item out of the list value on
+ * the stack and assign it to the variable.
+ */
+
+ if (isScalar) {
+ if (localIndex >= 0) {
+ TclEmitOpcode( INST_DUP, envPtr);
+ TclEmitInstInt4(INST_LIST_INDEX_IMM, idx, envPtr);
+ Emit14Inst( INST_STORE_SCALAR, localIndex, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ } else {
+ TclEmitInstInt4(INST_OVER, 1, envPtr);
+ TclEmitInstInt4(INST_LIST_INDEX_IMM, idx, envPtr);
+ TclEmitOpcode( INST_STORE_STK, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ }
+ } else {
+ if (localIndex >= 0) {
+ TclEmitInstInt4(INST_OVER, 1, envPtr);
+ TclEmitInstInt4(INST_LIST_INDEX_IMM, idx, envPtr);
+ Emit14Inst( INST_STORE_ARRAY, localIndex, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ } else {
+ TclEmitInstInt4(INST_OVER, 2, envPtr);
+ TclEmitInstInt4(INST_LIST_INDEX_IMM, idx, envPtr);
+ TclEmitOpcode( INST_STORE_ARRAY_STK, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ }
+ }
+ }
+
+ /*
+ * Generate code to leave the rest of the list on the stack.
+ */
+
+ TclEmitInstInt4( INST_LIST_RANGE_IMM, idx, envPtr);
+ TclEmitInt4( INDEX_END, envPtr);
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLindexCmd --
+ *
+ * Procedure called to compile the "lindex" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "lindex" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLindexCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *idxTokenPtr, *valTokenPtr;
+ int i, idx, numWords = parsePtr->numWords;
+ DefineLineInformation; /* TIP #280 */
+
+ /*
+ * Quit if too few args.
+ */
+
+ /* TODO: Consider support for compiling expanded args. */
+ if (numWords <= 1) {
+ return TCL_ERROR;
+ }
+
+ valTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ if (numWords != 3) {
+ goto emitComplexLindex;
+ }
+
+ idxTokenPtr = TokenAfter(valTokenPtr);
+ if (GetIndexFromToken(idxTokenPtr, &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.
+ */
+
+ CompileWord(envPtr, valTokenPtr, interp, 1);
+ TclEmitInstInt4( INST_LIST_INDEX_IMM, idx, envPtr);
+ return TCL_OK;
+ }
+
+ /*
+ * If the value was not known at compile time, the conversion failed or
+ * the value was negative, we just keep on going with the more complex
+ * compilation.
+ */
+
+ /*
+ * Push the operands onto the stack.
+ */
+
+ emitComplexLindex:
+ for (i=1 ; i<numWords ; i++) {
+ CompileWord(envPtr, valTokenPtr, interp, i);
+ valTokenPtr = TokenAfter(valTokenPtr);
+ }
+
+ /*
+ * Emit INST_LIST_INDEX if objc==3, or INST_LIST_INDEX_MULTI if there are
+ * multiple index args.
+ */
+
+ if (numWords == 3) {
+ TclEmitOpcode( INST_LIST_INDEX, envPtr);
+ } else {
+ TclEmitInstInt4( INST_LIST_INDEX_MULTI, numWords-1, envPtr);
+ }
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileListCmd --
+ *
+ * Procedure called to compile the "list" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "list" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileListCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *valueTokenPtr;
+ int i, numWords, concat, build;
+ Tcl_Obj *listObj, *objPtr;
+
+ if (parsePtr->numWords == 1) {
+ /*
+ * [list] without arguments just pushes an empty object.
+ */
+
+ PushStringLiteral(envPtr, "");
+ return TCL_OK;
+ }
+
+ /*
+ * Test if all arguments are compile-time known. If they are, we can
+ * implement with a simple push.
+ */
+
+ numWords = parsePtr->numWords;
+ valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ listObj = Tcl_NewObj();
+ for (i = 1; i < numWords && listObj != NULL; i++) {
+ objPtr = Tcl_NewObj();
+ if (TclWordKnownAtCompileTime(valueTokenPtr, objPtr)) {
+ (void) Tcl_ListObjAppendElement(NULL, listObj, objPtr);
+ } else {
+ Tcl_DecrRefCount(objPtr);
+ Tcl_DecrRefCount(listObj);
+ listObj = NULL;
+ }
+ valueTokenPtr = TokenAfter(valueTokenPtr);
+ }
+ if (listObj != NULL) {
+ int len;
+ const char *bytes = Tcl_GetStringFromObj(listObj, &len);
+
+ PushLiteral(envPtr, bytes, len);
+ Tcl_DecrRefCount(listObj);
+ if (len > 0) {
+ /*
+ * Force list interpretation!
+ */
+
+ TclEmitOpcode( INST_DUP, envPtr);
+ TclEmitOpcode( INST_LIST_LENGTH, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ }
+ return TCL_OK;
+ }
+
+ /*
+ * Push the all values onto the stack.
+ */
+
+ numWords = parsePtr->numWords;
+ valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ concat = build = 0;
+ for (i = 1; i < numWords; i++) {
+ if (valueTokenPtr->type == TCL_TOKEN_EXPAND_WORD && build > 0) {
+ TclEmitInstInt4( INST_LIST, build, envPtr);
+ if (concat) {
+ TclEmitOpcode( INST_LIST_CONCAT, envPtr);
+ }
+ build = 0;
+ concat = 1;
+ }
+ CompileWord(envPtr, valueTokenPtr, interp, i);
+ if (valueTokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
+ if (concat) {
+ TclEmitOpcode( INST_LIST_CONCAT, envPtr);
+ } else {
+ concat = 1;
+ }
+ } else {
+ build++;
+ }
+ valueTokenPtr = TokenAfter(valueTokenPtr);
+ }
+ if (build > 0) {
+ TclEmitInstInt4( INST_LIST, build, envPtr);
+ if (concat) {
+ TclEmitOpcode( INST_LIST_CONCAT, envPtr);
+ }
+ }
+
+ /*
+ * If there was just one expanded word, we must ensure that it is a list
+ * at this point. We use an [lrange ... 0 end] for this (instead of
+ * [llength], as with literals) as we must drop any string representation
+ * that might be hanging around.
+ */
+
+ if (concat && numWords == 2) {
+ TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
+ TclEmitInt4( INDEX_END, envPtr);
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLlengthCmd --
+ *
+ * Procedure called to compile the "llength" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "llength" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLlengthCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *varTokenPtr;
+ DefineLineInformation; /* TIP #280 */
+
+ if (parsePtr->numWords != 2) {
+ return TCL_ERROR;
+ }
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+ CompileWord(envPtr, varTokenPtr, interp, 1);
+ TclEmitOpcode( INST_LIST_LENGTH, envPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLrangeCmd --
+ *
+ * How to compile the "lrange" command. We only bother because we needed
+ * the opcode anyway for "lassign".
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLrangeCmd(
+ Tcl_Interp *interp, /* Tcl interpreter for context. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the
+ * command. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds the resulting instructions. */
+{
+ Tcl_Token *tokenPtr, *listTokenPtr;
+ DefineLineInformation; /* TIP #280 */
+ int idx1, idx2;
+
+ 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) {
+ return TCL_ERROR;
+ }
+
+ tokenPtr = TokenAfter(tokenPtr);
+ if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Issue instructions. It's not safe to skip doing the LIST_RANGE, as
+ * we've not proved that the 'list' argument is really a list. Not that it
+ * is worth trying to do that given current knowledge.
+ */
+
+ CompileWord(envPtr, listTokenPtr, interp, 1);
+ TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr);
+ TclEmitInt4( idx2, envPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLinsertCmd --
+ *
+ * How to compile the "linsert" command. We only bother with the case
+ * where the index is constant.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLinsertCmd(
+ Tcl_Interp *interp, /* Tcl interpreter for context. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the
+ * command. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds the resulting instructions. */
+{
+ Tcl_Token *tokenPtr, *listTokenPtr;
+ DefineLineInformation; /* TIP #280 */
+ int idx, i;
+
+ if (parsePtr->numWords < 3) {
+ return TCL_ERROR;
+ }
+ listTokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+ /*
+ * Parse the index. Will only compile if it is constant 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, &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,
+ * 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);
+ return TCL_OK;
+ }
+
+ for (i=3 ; i<parsePtr->numWords ; i++) {
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, i);
+ }
+ TclEmitInstInt4( INST_LIST, i-3, envPtr);
+
+ if (idx == 0 /*start*/) {
+ TclEmitInstInt4( INST_REVERSE, 2, envPtr);
+ TclEmitOpcode( INST_LIST_CONCAT, envPtr);
+ } else if (idx == INDEX_END /*end*/) {
+ TclEmitOpcode( INST_LIST_CONCAT, envPtr);
+ } else {
+ if (idx < 0) {
+ idx++;
+ }
+ TclEmitInstInt4( INST_OVER, 1, envPtr);
+ TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
+ TclEmitInt4( idx-1, envPtr);
+ TclEmitInstInt4( INST_REVERSE, 3, envPtr);
+ TclEmitInstInt4( INST_LIST_RANGE_IMM, idx, envPtr);
+ TclEmitInt4( INDEX_END, envPtr);
+ TclEmitOpcode( INST_LIST_CONCAT, envPtr);
+ TclEmitOpcode( INST_LIST_CONCAT, envPtr);
+ }
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLreplaceCmd --
+ *
+ * How to compile the "lreplace" command. We only bother with the case
+ * where the indices are constant.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLreplaceCmd(
+ Tcl_Interp *interp, /* Tcl interpreter for context. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the
+ * command. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds the resulting instructions. */
+{
+ Tcl_Token *tokenPtr, *listTokenPtr;
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Obj *tmpObj;
+ int idx1, idx2, i, offset;
+
+ 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) {
+ return TCL_ERROR;
+ }
+
+ tokenPtr = TokenAfter(tokenPtr);
+ if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Work out what this [lreplace] is actually doing.
+ */
+
+ 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 (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);
+ 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 (idx1 > 0 && idx2 > 0 && idx2 < idx1) {
+ idx2 = idx1 - 1;
+ } else if (idx1 < 0 && idx2 < 0 && idx2 < idx1) {
+ idx2 = idx1 - 1;
+ }
+ if (idx1 > 0) {
+ tmpObj = Tcl_NewIntObj(idx1);
+ Tcl_IncrRefCount(tmpObj);
+ }
+ 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:
+ 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) {
+ TclEmitOpcode( INST_DUP, envPtr);
+ TclEmitOpcode( INST_LIST_LENGTH, envPtr);
+ TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL), envPtr);
+ TclEmitOpcode( INST_GT, envPtr);
+ offset = CurrentOffset(envPtr);
+ TclEmitInstInt1( INST_JUMP_TRUE1, 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);
+ 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) {
+ TclEmitOpcode( INST_DUP, envPtr);
+ TclEmitOpcode( INST_LIST_LENGTH, envPtr);
+ TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL), envPtr);
+ TclEmitOpcode( INST_GT, envPtr);
+ offset = CurrentOffset(envPtr);
+ TclEmitInstInt1( INST_JUMP_TRUE1, 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);
+ 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.
+ */
+
+ done:
+ if (tmpObj != NULL) {
+ Tcl_DecrRefCount(tmpObj);
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLsetCmd --
+ *
+ * Procedure called to compile the "lset" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "lset" command at
+ * runtime.
+ *
+ * The general template for execution of the "lset" command is:
+ * (1) Instructions to push the variable name, unless the variable is
+ * local to the stack frame.
+ * (2) If the variable is an array element, instructions to push the
+ * array element name.
+ * (3) Instructions to push each of zero or more "index" arguments to the
+ * stack, followed with the "newValue" element.
+ * (4) Instructions to duplicate the variable name and/or array element
+ * name onto the top of the stack, if either was pushed at steps (1)
+ * and (2).
+ * (5) The appropriate INST_LOAD_* instruction to place the original
+ * value of the list variable at top of stack.
+ * (6) At this point, the stack contains:
+ * varName? arrayElementName? index1 index2 ... newValue oldList
+ * The compiler emits one of INST_LSET_FLAT or INST_LSET_LIST
+ * according as whether there is exactly one index element (LIST) or
+ * either zero or else two or more (FLAT). This instruction removes
+ * everything from the stack except for the two names and pushes the
+ * new value of the variable.
+ * (7) Finally, INST_STORE_* stores the new value in the variable and
+ * cleans up the stack.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLsetCmd(
+ Tcl_Interp *interp, /* Tcl interpreter for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the
+ * command. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds the resulting instructions. */
+{
+ int tempDepth; /* Depth used for emitting one part of the
+ * code burst. */
+ Tcl_Token *varTokenPtr; /* Pointer to the Tcl_Token representing the
+ * parse of the variable name. */
+ int localIndex; /* Index of var in local var table. */
+ int isScalar; /* Flag == 1 if scalar, 0 if array. */
+ int i;
+ DefineLineInformation; /* TIP #280 */
+
+ /*
+ * Check argument count.
+ */
+
+ /* TODO: Consider support for compiling expanded args. */
+ if (parsePtr->numWords < 3) {
+ /*
+ * Fail at run time, not in compilation.
+ */
+
+ return TCL_ERROR;
+ }
+
+ /*
+ * Decide if we can use a frame slot for the var/array name or if we need
+ * to emit code to compute and push the name at runtime. We use a frame
+ * slot (entry in the array of local vars) if we are compiling a procedure
+ * body and if the name is simple text that does not include namespace
+ * qualifiers.
+ */
+
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ PushVarNameWord(interp, varTokenPtr, envPtr, 0,
+ &localIndex, &isScalar, 1);
+
+ /*
+ * Push the "index" args and the new element value.
+ */
+
+ for (i=2 ; i<parsePtr->numWords ; ++i) {
+ varTokenPtr = TokenAfter(varTokenPtr);
+ CompileWord(envPtr, varTokenPtr, interp, i);
+ }
+
+ /*
+ * Duplicate the variable name if it's been pushed.
+ */
+
+ if (localIndex < 0) {
+ if (isScalar) {
+ tempDepth = parsePtr->numWords - 2;
+ } else {
+ tempDepth = parsePtr->numWords - 1;
+ }
+ TclEmitInstInt4( INST_OVER, tempDepth, envPtr);
+ }
+
+ /*
+ * Duplicate an array index if one's been pushed.
+ */
+
+ if (!isScalar) {
+ if (localIndex < 0) {
+ tempDepth = parsePtr->numWords - 1;
+ } else {
+ tempDepth = parsePtr->numWords - 2;
+ }
+ TclEmitInstInt4( INST_OVER, tempDepth, envPtr);
+ }
+
+ /*
+ * Emit code to load the variable's value.
+ */
+
+ if (isScalar) {
+ if (localIndex < 0) {
+ TclEmitOpcode( INST_LOAD_STK, envPtr);
+ } else {
+ Emit14Inst( INST_LOAD_SCALAR, localIndex, envPtr);
+ }
+ } else {
+ if (localIndex < 0) {
+ TclEmitOpcode( INST_LOAD_ARRAY_STK, envPtr);
+ } else {
+ Emit14Inst( INST_LOAD_ARRAY, localIndex, envPtr);
+ }
+ }
+
+ /*
+ * Emit the correct variety of 'lset' instruction.
+ */
+
+ if (parsePtr->numWords == 4) {
+ TclEmitOpcode( INST_LSET_LIST, envPtr);
+ } else {
+ TclEmitInstInt4( INST_LSET_FLAT, parsePtr->numWords-1, envPtr);
+ }
+
+ /*
+ * Emit code to put the value back in the variable.
+ */
+
+ if (isScalar) {
+ if (localIndex < 0) {
+ TclEmitOpcode( INST_STORE_STK, envPtr);
+ } else {
+ Emit14Inst( INST_STORE_SCALAR, localIndex, envPtr);
+ }
+ } else {
+ if (localIndex < 0) {
+ TclEmitOpcode( INST_STORE_ARRAY_STK, envPtr);
+ } else {
+ Emit14Inst( INST_STORE_ARRAY, localIndex, envPtr);
+ }
+ }
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileNamespace*Cmd --
+ *
+ * Procedures called to compile the "namespace" command; currently, only
+ * the subcommands "namespace current" and "namespace upvar" are compiled
+ * to bytecodes, and the latter only inside a procedure(-like) context.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "namespace upvar"
+ * command at runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileNamespaceCurrentCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Only compile [namespace current] without arguments.
+ */
+
+ if (parsePtr->numWords != 1) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Not much to do; we compile to a single instruction...
+ */
+
+ TclEmitOpcode( INST_NS_CURRENT, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileNamespaceCodeCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *tokenPtr;
+ DefineLineInformation; /* TIP #280 */
+
+ if (parsePtr->numWords != 2) {
+ return TCL_ERROR;
+ }
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+ /*
+ * The specification of [namespace code] is rather shocking, in that it is
+ * supposed to check if the argument is itself the result of [namespace
+ * code] and not apply itself in that case. Which is excessively cautious,
+ * but what the test suite checks for.
+ */
+
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD || (tokenPtr[1].size > 20
+ && strncmp(tokenPtr[1].start, "::namespace inscope ", 20) == 0)) {
+ /*
+ * Technically, we could just pass a literal '::namespace inscope '
+ * term through, but that's something which really shouldn't be
+ * occurring as something that the user writes so we'll just punt it.
+ */
+
+ return TCL_ERROR;
+ }
+
+ /*
+ * Now we can compile using the same strategy as [namespace code]'s normal
+ * implementation does internally. Note that we can't bind the namespace
+ * name directly here, because TclOO plays complex games with namespaces;
+ * the value needs to be determined at runtime for safety.
+ */
+
+ PushStringLiteral(envPtr, "::namespace");
+ PushStringLiteral(envPtr, "inscope");
+ TclEmitOpcode( INST_NS_CURRENT, envPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ TclEmitInstInt4( INST_LIST, 4, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileNamespaceOriginCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *tokenPtr;
+ DefineLineInformation; /* TIP #280 */
+
+ if (parsePtr->numWords != 2) {
+ return TCL_ERROR;
+ }
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ TclEmitOpcode( INST_ORIGIN_COMMAND, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileNamespaceQualifiersCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ DefineLineInformation; /* TIP #280 */
+ int off;
+
+ if (parsePtr->numWords != 2) {
+ return TCL_ERROR;
+ }
+
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ PushStringLiteral(envPtr, "0");
+ PushStringLiteral(envPtr, "::");
+ TclEmitInstInt4( INST_OVER, 2, envPtr);
+ TclEmitOpcode( INST_STR_FIND_LAST, envPtr);
+ off = CurrentOffset(envPtr);
+ PushStringLiteral(envPtr, "1");
+ TclEmitOpcode( INST_SUB, envPtr);
+ TclEmitInstInt4( INST_OVER, 2, envPtr);
+ TclEmitInstInt4( INST_OVER, 1, envPtr);
+ TclEmitOpcode( INST_STR_INDEX, envPtr);
+ PushStringLiteral(envPtr, ":");
+ TclEmitOpcode( INST_STR_EQ, envPtr);
+ off = off - CurrentOffset(envPtr);
+ TclEmitInstInt1( INST_JUMP_TRUE1, off, envPtr);
+ TclEmitOpcode( INST_STR_RANGE, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileNamespaceTailCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ DefineLineInformation; /* TIP #280 */
+ JumpFixup jumpFixup;
+
+ if (parsePtr->numWords != 2) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Take care; only add 2 to found index if the string was actually found.
+ */
+
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ PushStringLiteral(envPtr, "::");
+ TclEmitInstInt4( INST_OVER, 1, envPtr);
+ TclEmitOpcode( INST_STR_FIND_LAST, envPtr);
+ TclEmitOpcode( INST_DUP, envPtr);
+ PushStringLiteral(envPtr, "0");
+ TclEmitOpcode( INST_GE, envPtr);
+ TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpFixup);
+ PushStringLiteral(envPtr, "2");
+ TclEmitOpcode( INST_ADD, envPtr);
+ TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127);
+ PushStringLiteral(envPtr, "end");
+ TclEmitOpcode( INST_STR_RANGE, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileNamespaceUpvarCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr;
+ int isScalar, localIndex, numWords, i;
+ DefineLineInformation; /* TIP #280 */
+
+ if (envPtr->procPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Only compile [namespace upvar ...]: needs an even number of args, >=4
+ */
+
+ numWords = parsePtr->numWords;
+ if ((numWords % 2) || (numWords < 4)) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Push the namespace
+ */
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+
+ /*
+ * Loop over the (otherVar, thisVar) pairs. If any of the thisVar is not a
+ * local variable, return an error so that the non-compiled command will
+ * be called at runtime.
+ */
+
+ localTokenPtr = tokenPtr;
+ for (i=2; i<numWords; i+=2) {
+ otherTokenPtr = TokenAfter(localTokenPtr);
+ localTokenPtr = TokenAfter(otherTokenPtr);
+
+ CompileWord(envPtr, otherTokenPtr, interp, i);
+ PushVarNameWord(interp, localTokenPtr, envPtr, 0,
+ &localIndex, &isScalar, i+1);
+
+ if ((localIndex < 0) || !isScalar) {
+ return TCL_ERROR;
+ }
+ TclEmitInstInt4( INST_NSUPVAR, localIndex, envPtr);
+ }
+
+ /*
+ * Pop the namespace, and set the result to empty
+ */
+
+ TclEmitOpcode( INST_POP, envPtr);
+ PushStringLiteral(envPtr, "");
+ return TCL_OK;
+}
+
+int
+TclCompileNamespaceWhichCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr, *opt;
+ int idx;
+
+ if (parsePtr->numWords < 2 || parsePtr->numWords > 3) {
+ return TCL_ERROR;
+ }
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ idx = 1;
+
+ /*
+ * If there's an option, check that it's "-command". We don't handle
+ * "-variable" (currently) and anything else is an error.
+ */
+
+ if (parsePtr->numWords == 3) {
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ return TCL_ERROR;
+ }
+ opt = tokenPtr + 1;
+ if (opt->size < 2 || opt->size > 8
+ || strncmp(opt->start, "-command", opt->size) != 0) {
+ return TCL_ERROR;
+ }
+ tokenPtr = TokenAfter(tokenPtr);
+ idx++;
+ }
+
+ /*
+ * Issue the bytecode.
+ */
+
+ CompileWord(envPtr, tokenPtr, interp, idx);
+ TclEmitOpcode( INST_RESOLVE_COMMAND, envPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileRegexpCmd --
+ *
+ * Procedure called to compile the "regexp" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "regexp" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileRegexpCmd(
+ Tcl_Interp *interp, /* Tcl interpreter for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the
+ * command. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds the resulting instructions. */
+{
+ Tcl_Token *varTokenPtr; /* Pointer to the Tcl_Token representing the
+ * parse of the RE or string. */
+ int i, len, nocase, exact, sawLast, simple;
+ const char *str;
+ DefineLineInformation; /* TIP #280 */
+
+ /*
+ * We are only interested in compiling simple regexp cases. Currently
+ * supported compile cases are:
+ * regexp ?-nocase? ?--? staticString $var
+ * regexp ?-nocase? ?--? {^staticString$} $var
+ */
+
+ if (parsePtr->numWords < 3) {
+ return TCL_ERROR;
+ }
+
+ simple = 0;
+ nocase = 0;
+ sawLast = 0;
+ varTokenPtr = parsePtr->tokenPtr;
+
+ /*
+ * We only look for -nocase and -- as options. Everything else gets pushed
+ * to runtime execution. This is different than regexp's runtime option
+ * handling, but satisfies our stricter needs.
+ */
+
+ for (i = 1; i < parsePtr->numWords - 2; i++) {
+ varTokenPtr = TokenAfter(varTokenPtr);
+ if (varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ /*
+ * Not a simple string, so punt to runtime.
+ */
+
+ return TCL_ERROR;
+ }
+ str = varTokenPtr[1].start;
+ len = varTokenPtr[1].size;
+ if ((len == 2) && (str[0] == '-') && (str[1] == '-')) {
+ sawLast++;
+ i++;
+ break;
+ } else if ((len > 1) && (strncmp(str,"-nocase",(unsigned)len) == 0)) {
+ nocase = 1;
+ } else {
+ /*
+ * Not an option we recognize.
+ */
+
+ return TCL_ERROR;
+ }
+ }
+
+ if ((parsePtr->numWords - i) != 2) {
+ /*
+ * We don't support capturing to variables.
+ */
+
+ return TCL_ERROR;
+ }
+
+ /*
+ * Get the regexp string. If it is not a simple string or can't be
+ * converted to a glob pattern, push the word for the INST_REGEXP.
+ * Keep changes here in sync with TclCompileSwitchCmd Switch_Regexp.
+ */
+
+ varTokenPtr = TokenAfter(varTokenPtr);
+
+ if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+ Tcl_DString ds;
+
+ str = varTokenPtr[1].start;
+ len = varTokenPtr[1].size;
+
+ /*
+ * If it has a '-', it could be an incorrectly formed regexp command.
+ */
+
+ if ((*str == '-') && !sawLast) {
+ return TCL_ERROR;
+ }
+
+ if (len == 0) {
+ /*
+ * The semantics of regexp are always match on re == "".
+ */
+
+ PushStringLiteral(envPtr, "1");
+ return TCL_OK;
+ }
+
+ /*
+ * Attempt to convert pattern to glob. If successful, push the
+ * converted pattern as a literal.
+ */
+
+ if (TclReToGlob(NULL, varTokenPtr[1].start, len, &ds, &exact)
+ == TCL_OK) {
+ simple = 1;
+ PushLiteral(envPtr, Tcl_DStringValue(&ds),Tcl_DStringLength(&ds));
+ Tcl_DStringFree(&ds);
+ }
+ }
+
+ if (!simple) {
+ CompileWord(envPtr, varTokenPtr, interp, parsePtr->numWords-2);
+ }
+
+ /*
+ * Push the string arg.
+ */
+
+ varTokenPtr = TokenAfter(varTokenPtr);
+ CompileWord(envPtr, varTokenPtr, interp, parsePtr->numWords-1);
+
+ if (simple) {
+ if (exact && !nocase) {
+ TclEmitOpcode( INST_STR_EQ, envPtr);
+ } else {
+ TclEmitInstInt1( INST_STR_MATCH, nocase, envPtr);
+ }
+ } else {
+ /*
+ * Pass correct RE compile flags. We use only Int1 (8-bit), but
+ * that handles all the flags we want to pass.
+ * Don't use TCL_REG_NOSUB as we may have backrefs.
+ */
+
+ int cflags = TCL_REG_ADVANCED | (nocase ? TCL_REG_NOCASE : 0);
+
+ TclEmitInstInt1( INST_REGEXP, cflags, envPtr);
+ }
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileRegsubCmd --
+ *
+ * Procedure called to compile the "regsub" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "regsub" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileRegsubCmd(
+ Tcl_Interp *interp, /* Tcl interpreter for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the
+ * command. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds the resulting instructions. */
+{
+ /*
+ * We only compile the case with [regsub -all] where the pattern is both
+ * known at compile time and simple (i.e., no RE metacharacters). That is,
+ * the pattern must be translatable into a glob like "*foo*" with no other
+ * glob metacharacters inside it; there must be some "foo" in there too.
+ * The substitution string must also be known at compile time and free of
+ * metacharacters ("\digit" and "&"). Finally, there must not be a
+ * variable mentioned in the [regsub] to write the result back to (because
+ * we can't get the count of substitutions that would be the result in
+ * that case). The key is that these are the conditions under which a
+ * [string map] could be used instead, in particular a [string map] of the
+ * form we can compile to bytecode.
+ *
+ * In short, we look for:
+ *
+ * regsub -all [--] simpleRE string simpleReplacement
+ *
+ * The only optional part is the "--", and no other options are handled.
+ */
+
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr, *stringTokenPtr;
+ Tcl_Obj *patternObj = NULL, *replacementObj = NULL;
+ Tcl_DString pattern;
+ const char *bytes;
+ int len, exact, result = TCL_ERROR;
+
+ if (parsePtr->numWords < 5 || parsePtr->numWords > 6) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Parse the "-all", which must be the first argument (other options not
+ * supported, non-"-all" substitution we can't compile).
+ */
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD || tokenPtr[1].size != 4
+ || strncmp(tokenPtr[1].start, "-all", 4)) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Get the pattern into patternObj, checking for "--" in the process.
+ */
+
+ Tcl_DStringInit(&pattern);
+ tokenPtr = TokenAfter(tokenPtr);
+ patternObj = Tcl_NewObj();
+ if (!TclWordKnownAtCompileTime(tokenPtr, patternObj)) {
+ goto done;
+ }
+ if (Tcl_GetString(patternObj)[0] == '-') {
+ if (strcmp(Tcl_GetString(patternObj), "--") != 0
+ || parsePtr->numWords == 5) {
+ goto done;
+ }
+ tokenPtr = TokenAfter(tokenPtr);
+ Tcl_DecrRefCount(patternObj);
+ patternObj = Tcl_NewObj();
+ if (!TclWordKnownAtCompileTime(tokenPtr, patternObj)) {
+ goto done;
+ }
+ } else if (parsePtr->numWords == 6) {
+ goto done;
+ }
+
+ /*
+ * Identify the code which produces the string to apply the substitution
+ * to (stringTokenPtr), and the replacement string (into replacementObj).
+ */
+
+ stringTokenPtr = TokenAfter(tokenPtr);
+ tokenPtr = TokenAfter(stringTokenPtr);
+ replacementObj = Tcl_NewObj();
+ if (!TclWordKnownAtCompileTime(tokenPtr, replacementObj)) {
+ goto done;
+ }
+
+ /*
+ * Next, higher-level checks. Is the RE a very simple glob? Is the
+ * replacement "simple"?
+ */
+
+ bytes = Tcl_GetStringFromObj(patternObj, &len);
+ if (TclReToGlob(NULL, bytes, len, &pattern, &exact) != TCL_OK || exact) {
+ goto done;
+ }
+ bytes = Tcl_DStringValue(&pattern);
+ if (*bytes++ != '*') {
+ goto done;
+ }
+ while (1) {
+ switch (*bytes) {
+ case '*':
+ if (bytes[1] == '\0') {
+ /*
+ * OK, we've proved there are no metacharacters except for the
+ * '*' at each end.
+ */
+
+ len = Tcl_DStringLength(&pattern) - 2;
+ if (len > 0) {
+ goto isSimpleGlob;
+ }
+
+ /*
+ * The pattern is "**"! I believe that should be impossible,
+ * but we definitely can't handle that at all.
+ */
+ }
+ case '\0': case '?': case '[': case '\\':
+ goto done;
+ }
+ bytes++;
+ }
+ isSimpleGlob:
+ for (bytes = Tcl_GetString(replacementObj); *bytes; bytes++) {
+ switch (*bytes) {
+ case '\\': case '&':
+ goto done;
+ }
+ }
+
+ /*
+ * Proved the simplicity constraints! Time to issue the code.
+ */
+
+ result = TCL_OK;
+ bytes = Tcl_DStringValue(&pattern) + 1;
+ PushLiteral(envPtr, bytes, len);
+ bytes = Tcl_GetStringFromObj(replacementObj, &len);
+ PushLiteral(envPtr, bytes, len);
+ CompileWord(envPtr, stringTokenPtr, interp, parsePtr->numWords-2);
+ TclEmitOpcode( INST_STR_MAP, envPtr);
+
+ done:
+ Tcl_DStringFree(&pattern);
+ if (patternObj) {
+ Tcl_DecrRefCount(patternObj);
+ }
+ if (replacementObj) {
+ Tcl_DecrRefCount(replacementObj);
+ }
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileReturnCmd --
+ *
+ * Procedure called to compile the "return" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "return" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileReturnCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * General syntax: [return ?-option value ...? ?result?]
+ * An even number of words means an explicit result argument is present.
+ */
+ int level, code, objc, size, status = TCL_OK;
+ int numWords = parsePtr->numWords;
+ int explicitResult = (0 == (numWords % 2));
+ int numOptionWords = numWords - 1 - explicitResult;
+ Tcl_Obj *returnOpts, **objv;
+ Tcl_Token *wordTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ DefineLineInformation; /* TIP #280 */
+
+ /*
+ * Check for special case which can always be compiled:
+ * return -options <opts> <msg>
+ * Unlike the normal [return] compilation, this version does everything at
+ * runtime so it can handle arbitrary words and not just literals. Note
+ * that if INST_RETURN_STK wasn't already needed for something else
+ * ('finally' clause processing) this piece of code would not be present.
+ */
+
+ if ((numWords == 4) && (wordTokenPtr->type == TCL_TOKEN_SIMPLE_WORD)
+ && (wordTokenPtr[1].size == 8)
+ && (strncmp(wordTokenPtr[1].start, "-options", 8) == 0)) {
+ Tcl_Token *optsTokenPtr = TokenAfter(wordTokenPtr);
+ Tcl_Token *msgTokenPtr = TokenAfter(optsTokenPtr);
+
+ CompileWord(envPtr, optsTokenPtr, interp, 2);
+ CompileWord(envPtr, msgTokenPtr, interp, 3);
+ TclEmitInvoke(envPtr, INST_RETURN_STK);
+ return TCL_OK;
+ }
+
+ /*
+ * Allocate some working space.
+ */
+
+ objv = TclStackAlloc(interp, numOptionWords * sizeof(Tcl_Obj *));
+
+ /*
+ * Scan through the return options. If any are unknown at compile time,
+ * there is no value in bytecompiling. Save the option values known in an
+ * objv array for merging into a return options dictionary.
+ *
+ * TODO: There is potential for improvement if all option keys are known
+ * at compile time and all option values relating to '-code' and '-level'
+ * are known at compile time.
+ */
+
+ for (objc = 0; objc < numOptionWords; objc++) {
+ objv[objc] = Tcl_NewObj();
+ Tcl_IncrRefCount(objv[objc]);
+ if (!TclWordKnownAtCompileTime(wordTokenPtr, objv[objc])) {
+ /*
+ * Non-literal, so punt to run-time assembly of the dictionary.
+ */
+
+ for (; objc>=0 ; objc--) {
+ TclDecrRefCount(objv[objc]);
+ }
+ TclStackFree(interp, objv);
+ goto issueRuntimeReturn;
+ }
+ wordTokenPtr = TokenAfter(wordTokenPtr);
+ }
+ status = TclMergeReturnOptions(interp, objc, objv,
+ &returnOpts, &code, &level);
+ while (--objc >= 0) {
+ TclDecrRefCount(objv[objc]);
+ }
+ TclStackFree(interp, objv);
+ if (TCL_ERROR == status) {
+ /*
+ * Something was bogus in the return options. Clear the error message,
+ * and report back to the compiler that this must be interpreted at
+ * runtime.
+ */
+
+ Tcl_ResetResult(interp);
+ return TCL_ERROR;
+ }
+
+ /*
+ * All options are known at compile time, so we're going to bytecompile.
+ * Emit instructions to push the result on the stack.
+ */
+
+ if (explicitResult) {
+ CompileWord(envPtr, wordTokenPtr, interp, numWords-1);
+ } else {
+ /*
+ * No explict result argument, so default result is empty string.
+ */
+
+ PushStringLiteral(envPtr, "");
+ }
+
+ /*
+ * Check for optimization: When [return] is in a proc, and there's no
+ * enclosing [catch], and there are no return options, then the INST_DONE
+ * instruction is equivalent, and may be more efficient.
+ */
+
+ if (numOptionWords == 0 && envPtr->procPtr != NULL) {
+ /*
+ * We have default return options and we're in a proc ...
+ */
+
+ int index = envPtr->exceptArrayNext - 1;
+ int enclosingCatch = 0;
+
+ while (index >= 0) {
+ ExceptionRange range = envPtr->exceptArrayPtr[index];
+
+ if ((range.type == CATCH_EXCEPTION_RANGE)
+ && (range.catchOffset == -1)) {
+ enclosingCatch = 1;
+ break;
+ }
+ index--;
+ }
+ if (!enclosingCatch) {
+ /*
+ * ... and there is no enclosing catch. Issue the maximally
+ * efficient exit instruction.
+ */
+
+ Tcl_DecrRefCount(returnOpts);
+ TclEmitOpcode(INST_DONE, envPtr);
+ TclAdjustStackDepth(1, envPtr);
+ return TCL_OK;
+ }
+ }
+
+ /* Optimize [return -level 0 $x]. */
+ Tcl_DictObjSize(NULL, returnOpts, &size);
+ if (size == 0 && level == 0 && code == TCL_OK) {
+ Tcl_DecrRefCount(returnOpts);
+ return TCL_OK;
+ }
+
+ /*
+ * Could not use the optimization, so we push the return options dict, and
+ * emit the INST_RETURN_IMM instruction with code and level as operands.
+ */
+
+ CompileReturnInternal(envPtr, INST_RETURN_IMM, code, level, returnOpts);
+ return TCL_OK;
+
+ issueRuntimeReturn:
+ /*
+ * Assemble the option dictionary (as a list as that's good enough).
+ */
+
+ wordTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ for (objc=1 ; objc<=numOptionWords ; objc++) {
+ CompileWord(envPtr, wordTokenPtr, interp, objc);
+ wordTokenPtr = TokenAfter(wordTokenPtr);
+ }
+ TclEmitInstInt4(INST_LIST, numOptionWords, envPtr);
+
+ /*
+ * Push the result.
+ */
+
+ if (explicitResult) {
+ CompileWord(envPtr, wordTokenPtr, interp, numWords-1);
+ } else {
+ PushStringLiteral(envPtr, "");
+ }
+
+ /*
+ * Issue the RETURN itself.
+ */
+
+ TclEmitInvoke(envPtr, INST_RETURN_STK);
+ return TCL_OK;
+}
+
+static void
+CompileReturnInternal(
+ CompileEnv *envPtr,
+ unsigned char op,
+ int code,
+ int level,
+ Tcl_Obj *returnOpts)
+{
+ if (level == 0 && (code == TCL_BREAK || code == TCL_CONTINUE)) {
+ ExceptionRange *rangePtr;
+ ExceptionAux *exceptAux;
+
+ rangePtr = TclGetInnermostExceptionRange(envPtr, code, &exceptAux);
+ if (rangePtr && rangePtr->type == LOOP_EXCEPTION_RANGE) {
+ TclCleanupStackForBreakContinue(envPtr, exceptAux);
+ if (code == TCL_BREAK) {
+ TclAddLoopBreakFixup(envPtr, exceptAux);
+ } else {
+ TclAddLoopContinueFixup(envPtr, exceptAux);
+ }
+ Tcl_DecrRefCount(returnOpts);
+ return;
+ }
+ }
+
+ TclEmitPush(TclAddLiteralObj(envPtr, returnOpts, NULL), envPtr);
+ TclEmitInstInt4(op, code, envPtr);
+ TclEmitInt4(level, envPtr);
+}
+
+void
+TclCompileSyntaxError(
+ Tcl_Interp *interp,
+ CompileEnv *envPtr)
+{
+ Tcl_Obj *msg = Tcl_GetObjResult(interp);
+ int numBytes;
+ const char *bytes = TclGetStringFromObj(msg, &numBytes);
+
+ TclErrorStackResetIf(interp, bytes, numBytes);
+ TclEmitPush(TclRegisterNewLiteral(envPtr, bytes, numBytes), envPtr);
+ CompileReturnInternal(envPtr, INST_SYNTAX, TCL_ERROR, 0,
+ TclNoErrorStack(interp, Tcl_GetReturnOptions(interp, TCL_ERROR)));
+ Tcl_ResetResult(interp);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileUpvarCmd --
+ *
+ * Procedure called to compile the "upvar" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "upvar" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileUpvarCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr;
+ int isScalar, localIndex, numWords, i;
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Obj *objPtr;
+
+ if (envPtr->procPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ numWords = parsePtr->numWords;
+ if (numWords < 3) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Push the frame index if it is known at compile time
+ */
+
+ objPtr = Tcl_NewObj();
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ if (TclWordKnownAtCompileTime(tokenPtr, objPtr)) {
+ CallFrame *framePtr;
+ const Tcl_ObjType *newTypePtr, *typePtr = objPtr->typePtr;
+
+ /*
+ * Attempt to convert to a level reference. Note that TclObjGetFrame
+ * only changes the obj type when a conversion was successful.
+ */
+
+ TclObjGetFrame(interp, objPtr, &framePtr);
+ newTypePtr = objPtr->typePtr;
+ Tcl_DecrRefCount(objPtr);
+
+ if (newTypePtr != typePtr) {
+ if (numWords%2) {
+ return TCL_ERROR;
+ }
+ /* TODO: Push the known value instead? */
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ otherTokenPtr = TokenAfter(tokenPtr);
+ i = 2;
+ } else {
+ if (!(numWords%2)) {
+ return TCL_ERROR;
+ }
+ PushStringLiteral(envPtr, "1");
+ otherTokenPtr = tokenPtr;
+ i = 1;
+ }
+ } else {
+ Tcl_DecrRefCount(objPtr);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Loop over the (otherVar, thisVar) pairs. If any of the thisVar is not a
+ * local variable, return an error so that the non-compiled command will
+ * be called at runtime.
+ */
+
+ for (; i<numWords; i+=2, otherTokenPtr = TokenAfter(localTokenPtr)) {
+ localTokenPtr = TokenAfter(otherTokenPtr);
+
+ CompileWord(envPtr, otherTokenPtr, interp, i);
+ PushVarNameWord(interp, localTokenPtr, envPtr, 0,
+ &localIndex, &isScalar, i+1);
+
+ if ((localIndex < 0) || !isScalar) {
+ return TCL_ERROR;
+ }
+ TclEmitInstInt4( INST_UPVAR, localIndex, envPtr);
+ }
+
+ /*
+ * Pop the frame index, and set the result to empty
+ */
+
+ TclEmitOpcode( INST_POP, envPtr);
+ PushStringLiteral(envPtr, "");
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileVariableCmd --
+ *
+ * Procedure called to compile the "variable" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "variable" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileVariableCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *varTokenPtr, *valueTokenPtr;
+ int localIndex, numWords, i;
+ DefineLineInformation; /* TIP #280 */
+
+ numWords = parsePtr->numWords;
+ if (numWords < 2) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Bail out if not compiling a proc body
+ */
+
+ if (envPtr->procPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Loop over the (var, value) pairs.
+ */
+
+ valueTokenPtr = parsePtr->tokenPtr;
+ for (i=1; i<numWords; i+=2) {
+ varTokenPtr = TokenAfter(valueTokenPtr);
+ valueTokenPtr = TokenAfter(varTokenPtr);
+
+ localIndex = IndexTailVarIfKnown(interp, varTokenPtr, envPtr);
+
+ if (localIndex < 0) {
+ return TCL_ERROR;
+ }
+
+ /* TODO: Consider what value can pass throug the
+ * IndexTailVarIfKnown() screen. Full CompileWord()
+ * likely does not apply here. Push known value instead. */
+ CompileWord(envPtr, varTokenPtr, interp, i);
+ TclEmitInstInt4( INST_VARIABLE, localIndex, envPtr);
+
+ if (i+1 < numWords) {
+ /*
+ * A value has been given: set the variable, pop the value
+ */
+
+ CompileWord(envPtr, valueTokenPtr, interp, i+1);
+ Emit14Inst( INST_STORE_SCALAR, localIndex, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ }
+ }
+
+ /*
+ * Set the result to empty
+ */
+
+ PushStringLiteral(envPtr, "");
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * IndexTailVarIfKnown --
+ *
+ * Procedure used in compiling [global] and [variable] commands. It
+ * inspects the variable name described by varTokenPtr and, if the tail
+ * is known at compile time, defines a corresponding local variable.
+ *
+ * Results:
+ * Returns the variable's index in the table of compiled locals if the
+ * tail is known at compile time, or -1 otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+IndexTailVarIfKnown(
+ Tcl_Interp *interp,
+ Tcl_Token *varTokenPtr, /* Token representing the variable name */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Obj *tailPtr;
+ const char *tailName, *p;
+ int len, n = varTokenPtr->numComponents;
+ Tcl_Token *lastTokenPtr;
+ int full, localIndex;
+
+ /*
+ * Determine if the tail is (a) known at compile time, and (b) not an
+ * array element. Should any of these fail, return an error so that the
+ * non-compiled command will be called at runtime.
+ *
+ * In order for the tail to be known at compile time, the last token in
+ * the word has to be constant and contain "::" if it is not the only one.
+ */
+
+ if (!EnvHasLVT(envPtr)) {
+ return -1;
+ }
+
+ TclNewObj(tailPtr);
+ if (TclWordKnownAtCompileTime(varTokenPtr, tailPtr)) {
+ full = 1;
+ lastTokenPtr = varTokenPtr;
+ } else {
+ full = 0;
+ lastTokenPtr = varTokenPtr + n;
+ if (!TclWordKnownAtCompileTime(lastTokenPtr, tailPtr)) {
+ Tcl_DecrRefCount(tailPtr);
+ return -1;
+ }
+ }
+
+ tailName = TclGetStringFromObj(tailPtr, &len);
+
+ if (len) {
+ if (*(tailName+len-1) == ')') {
+ /*
+ * Possible array: bail out
+ */
+
+ Tcl_DecrRefCount(tailPtr);
+ return -1;
+ }
+
+ /*
+ * Get the tail: immediately after the last '::'
+ */
+
+ for (p = tailName + len -1; p > tailName; p--) {
+ if ((*p == ':') && (*(p-1) == ':')) {
+ p++;
+ break;
+ }
+ }
+ if (!full && (p == tailName)) {
+ /*
+ * No :: in the last component.
+ */
+
+ Tcl_DecrRefCount(tailPtr);
+ return -1;
+ }
+ len -= p - tailName;
+ tailName = p;
+ }
+
+ localIndex = TclFindCompiledLocal(tailName, len, 1, envPtr);
+ Tcl_DecrRefCount(tailPtr);
+ return localIndex;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclCompileObjectNextCmd, TclCompileObjectSelfCmd --
+ *
+ * Compilations of the TclOO utility commands [next] and [self].
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclCompileObjectNextCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+ int i;
+
+ if (parsePtr->numWords > 255) {
+ return TCL_ERROR;
+ }
+
+ for (i=0 ; i<parsePtr->numWords ; i++) {
+ CompileWord(envPtr, tokenPtr, interp, i);
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+ TclEmitInstInt1( INST_TCLOO_NEXT, i, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileObjectNextToCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+ int i;
+
+ if (parsePtr->numWords < 2 || parsePtr->numWords > 255) {
+ return TCL_ERROR;
+ }
+
+ for (i=0 ; i<parsePtr->numWords ; i++) {
+ CompileWord(envPtr, tokenPtr, interp, i);
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+ TclEmitInstInt1( INST_TCLOO_NEXT_CLASS, i, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileObjectSelfCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * We only handle [self] and [self object] (which is the same operation).
+ * These are the only very common operations on [self] for which
+ * bytecoding is at all reasonable.
+ */
+
+ if (parsePtr->numWords == 1) {
+ goto compileSelfObject;
+ } else if (parsePtr->numWords == 2) {
+ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr), *subcmd;
+
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD || tokenPtr[1].size==0) {
+ return TCL_ERROR;
+ }
+
+ subcmd = tokenPtr + 1;
+ if (strncmp(subcmd->start, "object", subcmd->size) == 0) {
+ goto compileSelfObject;
+ } else if (strncmp(subcmd->start, "namespace", subcmd->size) == 0) {
+ goto compileSelfNamespace;
+ }
+ }
+
+ /*
+ * Can't compile; handle with runtime call.
+ */
+
+ return TCL_ERROR;
+
+ compileSelfObject:
+
+ /*
+ * This delegates the entire problem to a single opcode.
+ */
+
+ TclEmitOpcode( INST_TCLOO_SELF, envPtr);
+ return TCL_OK;
+
+ compileSelfNamespace:
+
+ /*
+ * This is formally only correct with TclOO methods as they are currently
+ * implemented; it assumes that the current namespace is invariably when a
+ * TclOO context is present is the object's namespace, and that's
+ * technically only something that's a matter of current policy. But it
+ * avoids creating another opcode, so that's all good!
+ */
+
+ TclEmitOpcode( INST_TCLOO_SELF, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ TclEmitOpcode( INST_NS_CURRENT, envPtr);
+ return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c
index b950e21..e6ec0a6 100644
--- a/generic/tclCompCmdsSZ.c
+++ b/generic/tclCompCmdsSZ.c
@@ -17,6 +17,7 @@
#include "tclInt.h"
#include "tclCompile.h"
+#include "tclStringTrim.h"
/*
* Prototypes for procedures defined later in this file:
@@ -27,11 +28,6 @@ static void FreeJumptableInfo(ClientData clientData);
static void PrintJumptableInfo(ClientData clientData,
Tcl_Obj *appendObj, ByteCode *codePtr,
unsigned int pcOffset);
-static int PushVarName(Tcl_Interp *interp,
- Tcl_Token *varTokenPtr, CompileEnv *envPtr,
- int flags, int *localIndexPtr,
- int *simpleVarNamePtr, int *isScalarPtr,
- int line, int *clNext);
static int CompileAssociativeBinaryOpCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, const char *identity,
int instruction, CompileEnv *envPtr);
@@ -45,75 +41,28 @@ static int CompileUnaryOpCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, int instruction,
CompileEnv *envPtr);
static void IssueSwitchChainedTests(Tcl_Interp *interp,
- CompileEnv *envPtr, ExtCmdLoc *mapPtr,
- int eclIndex, int mode, int noCase,
- int valueIndex, Tcl_Token *valueTokenPtr,
- int numWords, Tcl_Token **bodyToken,
- int *bodyLines, int **bodyNext);
-static void IssueSwitchJumpTable(Tcl_Interp *interp,
- CompileEnv *envPtr, ExtCmdLoc *mapPtr,
- int eclIndex, int valueIndex,
- Tcl_Token *valueTokenPtr, int numWords,
+ CompileEnv *envPtr, int mode, int noCase,
+ int valueIndex, int numWords,
Tcl_Token **bodyToken, int *bodyLines,
- int **bodyContLines);
-static int IssueTryFinallyInstructions(Tcl_Interp *interp,
+ int **bodyNext);
+static void IssueSwitchJumpTable(Tcl_Interp *interp,
+ CompileEnv *envPtr, int valueIndex,
+ int numWords, Tcl_Token **bodyToken,
+ int *bodyLines, int **bodyContLines);
+static int IssueTryClausesInstructions(Tcl_Interp *interp,
CompileEnv *envPtr, Tcl_Token *bodyToken,
int numHandlers, int *matchCodes,
Tcl_Obj **matchClauses, int *resultVarIndices,
- int *optionVarIndices, Tcl_Token **handlerTokens,
- Tcl_Token *finallyToken);
-static int IssueTryInstructions(Tcl_Interp *interp,
+ int *optionVarIndices, Tcl_Token **handlerTokens);
+static int IssueTryClausesFinallyInstructions(Tcl_Interp *interp,
CompileEnv *envPtr, Tcl_Token *bodyToken,
int numHandlers, int *matchCodes,
Tcl_Obj **matchClauses, int *resultVarIndices,
- int *optionVarIndices, Tcl_Token **handlerTokens);
-
-/*
- * Macro that encapsulates an efficiency trick that avoids a function call for
- * the simplest of compiles. The ANSI C "prototype" for this macro is:
- *
- * static void CompileWord(CompileEnv *envPtr, Tcl_Token *tokenPtr,
- * Tcl_Interp *interp, int word);
- */
-
-#define CompileWord(envPtr, tokenPtr, interp, word) \
- if ((tokenPtr)->type == TCL_TOKEN_SIMPLE_WORD) { \
- TclEmitPush(TclRegisterNewLiteral((envPtr), (tokenPtr)[1].start, \
- (tokenPtr)[1].size), (envPtr)); \
- } else { \
- envPtr->line = mapPtr->loc[eclIndex].line[word]; \
- envPtr->clNext = mapPtr->loc[eclIndex].next[word]; \
- TclCompileTokens((interp), (tokenPtr)+1, (tokenPtr)->numComponents, \
- (envPtr)); \
- }
-
-/*
- * TIP #280: Remember the per-word line information of the current command. An
- * index is used instead of a pointer as recursive compilation may reallocate,
- * i.e. move, the array. This is also the reason to save the nuloc now, it may
- * change during the course of the function.
- *
- * Macro to encapsulate the variable definition and setup.
- */
-
-#define DefineLineInformation \
- ExtCmdLoc *mapPtr = envPtr->extCmdMapPtr; \
- int eclIndex = mapPtr->nuloc - 1
-
-#define SetLineInformation(word) \
- envPtr->line = mapPtr->loc[eclIndex].line[(word)]; \
- envPtr->clNext = mapPtr->loc[eclIndex].next[(word)]
-
-#define PushVarNameWord(i,v,e,f,l,s,sc,word) \
- PushVarName(i,v,e,f,l,s,sc, \
- mapPtr->loc[eclIndex].line[(word)], \
- mapPtr->loc[eclIndex].next[(word)])
-
-/*
- * Flags bits used by PushVarName.
- */
-
-#define TCL_NO_LARGE_INDEX 1 /* Do not return localIndex value > 255 */
+ int *optionVarIndices, Tcl_Token **handlerTokens,
+ Tcl_Token *finallyToken);
+static int IssueTryFinallyInstructions(Tcl_Interp *interp,
+ CompileEnv *envPtr, Tcl_Token *bodyToken,
+ Tcl_Token *finallyToken);
/*
* The structures below define the AuxData types defined in this file.
@@ -133,20 +82,79 @@ const AuxDataType tclJumptableInfoType = {
#define OP(name) TclEmitOpcode(INST_##name, envPtr)
#define OP1(name,val) TclEmitInstInt1(INST_##name,(val),envPtr)
#define OP4(name,val) TclEmitInstInt4(INST_##name,(val),envPtr)
+#define OP14(name,val1,val2) \
+ TclEmitInstInt1(INST_##name,(val1),envPtr);TclEmitInt4((val2),envPtr)
#define OP44(name,val1,val2) \
TclEmitInstInt4(INST_##name,(val1),envPtr);TclEmitInt4((val2),envPtr)
-#define BODY(token,index) \
- SetLineInformation((index));CompileBody(envPtr,(token),interp)
#define PUSH(str) \
- PushLiteral(envPtr,(str),strlen(str))
-#define JUMP(var,name) \
- (var) = CurrentOffset(envPtr);TclEmitInstInt4(INST_##name,0,envPtr)
-#define FIXJUMP(var) \
+ PushStringLiteral(envPtr, str)
+#define JUMP4(name,var) \
+ (var) = CurrentOffset(envPtr);TclEmitInstInt4(INST_##name##4,0,envPtr)
+#define FIXJUMP4(var) \
TclStoreInt4AtPtr(CurrentOffset(envPtr)-(var),envPtr->codeStart+(var)+1)
+#define JUMP1(name,var) \
+ (var) = CurrentOffset(envPtr);TclEmitInstInt1(INST_##name##1,0,envPtr)
+#define FIXJUMP1(var) \
+ TclStoreInt1AtPtr(CurrentOffset(envPtr)-(var),envPtr->codeStart+(var)+1)
#define LOAD(idx) \
if ((idx)<256) {OP1(LOAD_SCALAR1,(idx));} else {OP4(LOAD_SCALAR4,(idx));}
#define STORE(idx) \
if ((idx)<256) {OP1(STORE_SCALAR1,(idx));} else {OP4(STORE_SCALAR4,(idx));}
+#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;
+}
/*
*----------------------------------------------------------------------
@@ -176,7 +184,7 @@ TclCompileSetCmd(
CompileEnv *envPtr) /* Holds resulting instructions. */
{
Tcl_Token *varTokenPtr, *valueTokenPtr;
- int isAssignment, isScalar, simpleVarName, localIndex, numWords;
+ int isAssignment, isScalar, localIndex, numWords;
DefineLineInformation; /* TIP #280 */
numWords = parsePtr->numWords;
@@ -195,7 +203,7 @@ TclCompileSetCmd(
varTokenPtr = TokenAfter(parsePtr->tokenPtr);
PushVarNameWord(interp, varTokenPtr, envPtr, 0,
- &localIndex, &simpleVarName, &isScalar, 1);
+ &localIndex, &isScalar, 1);
/*
* If we are doing an assignment, push the new value.
@@ -210,12 +218,10 @@ TclCompileSetCmd(
* Emit instructions to set/get the variable.
*/
- if (simpleVarName) {
if (isScalar) {
if (localIndex < 0) {
TclEmitOpcode((isAssignment?
- INST_STORE_SCALAR_STK : INST_LOAD_SCALAR_STK),
- envPtr);
+ INST_STORE_STK : INST_LOAD_STK), envPtr);
} else if (localIndex <= 255) {
TclEmitInstInt1((isAssignment?
INST_STORE_SCALAR1 : INST_LOAD_SCALAR1),
@@ -239,9 +245,6 @@ TclCompileSetCmd(
localIndex, envPtr);
}
}
- } else {
- TclEmitOpcode((isAssignment? INST_STORE_STK : INST_LOAD_STK), envPtr);
- }
return TCL_OK;
}
@@ -249,18 +252,18 @@ TclCompileSetCmd(
/*
*----------------------------------------------------------------------
*
- * TclCompileStringCmpCmd --
+ * TclCompileString*Cmd --
*
- * Procedure called to compile the simplest and most common form of the
- * "string compare" command.
+ * Procedures called to compile various subcommands of the "string"
+ * command.
*
* Results:
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
* evaluation to runtime.
*
* Side effects:
- * Instructions are added to envPtr to execute the "string compare"
- * command at runtime.
+ * Instructions are added to envPtr to execute the "string" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
@@ -296,25 +299,6 @@ TclCompileStringCmpCmd(
TclEmitOpcode(INST_STR_CMP, envPtr);
return TCL_OK;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileStringEqualCmd --
- *
- * Procedure called to compile the simplest and most common form of the
- * "string equal" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "string equal" command
- * at runtime.
- *
- *----------------------------------------------------------------------
- */
int
TclCompileStringEqualCmd(
@@ -347,25 +331,70 @@ TclCompileStringEqualCmd(
TclEmitOpcode(INST_STR_EQ, envPtr);
return TCL_OK;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileStringIndexCmd --
- *
- * Procedure called to compile the simplest and most common form of the
- * "string index" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "string index" command
- * at runtime.
- *
- *----------------------------------------------------------------------
- */
+
+int
+TclCompileStringFirstCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr;
+
+ /*
+ * We don't support any flags; the bytecode isn't that sophisticated.
+ */
+
+ if (parsePtr->numWords != 3) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Push the two operands onto the stack and then the test.
+ */
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 2);
+ OP(STR_FIND);
+ return TCL_OK;
+}
+
+int
+TclCompileStringLastCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr;
+
+ /*
+ * We don't support any flags; the bytecode isn't that sophisticated.
+ */
+
+ if (parsePtr->numWords != 3) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Push the two operands onto the stack and then the test.
+ */
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 2);
+ OP(STR_FIND_LAST);
+ return TCL_OK;
+}
int
TclCompileStringIndexCmd(
@@ -394,25 +423,284 @@ TclCompileStringIndexCmd(
TclEmitOpcode(INST_STR_INDEX, envPtr);
return TCL_OK;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileStringMatchCmd --
- *
- * Procedure called to compile the simplest and most common form of the
- * "string match" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "string match" command
- * at runtime.
- *
- *----------------------------------------------------------------------
- */
+
+int
+TclCompileStringIsCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ static const char *const isClasses[] = {
+ "alnum", "alpha", "ascii", "control",
+ "boolean", "digit", "double", "entier",
+ "false", "graph", "integer", "list",
+ "lower", "print", "punct", "space",
+ "true", "upper", "wideinteger", "wordchar",
+ "xdigit", NULL
+ };
+ enum isClasses {
+ STR_IS_ALNUM, STR_IS_ALPHA, STR_IS_ASCII, STR_IS_CONTROL,
+ STR_IS_BOOL, STR_IS_DIGIT, STR_IS_DOUBLE, STR_IS_ENTIER,
+ STR_IS_FALSE, STR_IS_GRAPH, STR_IS_INT, STR_IS_LIST,
+ STR_IS_LOWER, STR_IS_PRINT, STR_IS_PUNCT, STR_IS_SPACE,
+ STR_IS_TRUE, STR_IS_UPPER, STR_IS_WIDE, STR_IS_WORD,
+ STR_IS_XDIGIT
+ };
+ int t, range, allowEmpty = 0, end;
+ InstStringClassType strClassType;
+ Tcl_Obj *isClass;
+
+ if (parsePtr->numWords < 3 || parsePtr->numWords > 6) {
+ return TCL_ERROR;
+ }
+ isClass = Tcl_NewObj();
+ if (!TclWordKnownAtCompileTime(tokenPtr, isClass)) {
+ Tcl_DecrRefCount(isClass);
+ return TCL_ERROR;
+ } else if (Tcl_GetIndexFromObj(interp, isClass, isClasses, "class", 0,
+ &t) != TCL_OK) {
+ Tcl_DecrRefCount(isClass);
+ TclCompileSyntaxError(interp, envPtr);
+ return TCL_OK;
+ }
+ Tcl_DecrRefCount(isClass);
+
+#define GotLiteral(tokenPtr, word) \
+ ((tokenPtr)->type == TCL_TOKEN_SIMPLE_WORD && \
+ (tokenPtr)[1].size > 1 && \
+ (tokenPtr)[1].start[0] == word[0] && \
+ strncmp((tokenPtr)[1].start, (word), (tokenPtr)[1].size) == 0)
+
+ /*
+ * Cannot handle the -failindex option at all, and that's the only legal
+ * way to have more than 4 arguments.
+ */
+
+ if (parsePtr->numWords != 3 && parsePtr->numWords != 4) {
+ return TCL_ERROR;
+ }
+
+ tokenPtr = TokenAfter(tokenPtr);
+ if (parsePtr->numWords == 3) {
+ allowEmpty = 1;
+ } else {
+ if (!GotLiteral(tokenPtr, "-strict")) {
+ return TCL_ERROR;
+ }
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+#undef GotLiteral
+
+ /*
+ * Compile the code. There are several main classes of check here.
+ * 1. Character classes
+ * 2. Booleans
+ * 3. Integers
+ * 4. Floats
+ * 5. Lists
+ */
+
+ CompileWord(envPtr, tokenPtr, interp, parsePtr->numWords-1);
+
+ switch ((enum isClasses) t) {
+ case STR_IS_ALNUM:
+ strClassType = STR_CLASS_ALNUM;
+ goto compileStrClass;
+ case STR_IS_ALPHA:
+ strClassType = STR_CLASS_ALPHA;
+ goto compileStrClass;
+ case STR_IS_ASCII:
+ strClassType = STR_CLASS_ASCII;
+ goto compileStrClass;
+ case STR_IS_CONTROL:
+ strClassType = STR_CLASS_CONTROL;
+ goto compileStrClass;
+ case STR_IS_DIGIT:
+ strClassType = STR_CLASS_DIGIT;
+ goto compileStrClass;
+ case STR_IS_GRAPH:
+ strClassType = STR_CLASS_GRAPH;
+ goto compileStrClass;
+ case STR_IS_LOWER:
+ strClassType = STR_CLASS_LOWER;
+ goto compileStrClass;
+ case STR_IS_PRINT:
+ strClassType = STR_CLASS_PRINT;
+ goto compileStrClass;
+ case STR_IS_PUNCT:
+ strClassType = STR_CLASS_PUNCT;
+ goto compileStrClass;
+ case STR_IS_SPACE:
+ strClassType = STR_CLASS_SPACE;
+ goto compileStrClass;
+ case STR_IS_UPPER:
+ strClassType = STR_CLASS_UPPER;
+ goto compileStrClass;
+ case STR_IS_WORD:
+ strClassType = STR_CLASS_WORD;
+ goto compileStrClass;
+ case STR_IS_XDIGIT:
+ strClassType = STR_CLASS_XDIGIT;
+ compileStrClass:
+ if (allowEmpty) {
+ OP1( STR_CLASS, strClassType);
+ } else {
+ int over, over2;
+
+ OP( DUP);
+ OP1( STR_CLASS, strClassType);
+ JUMP1( JUMP_TRUE, over);
+ OP( POP);
+ PUSH( "0");
+ JUMP1( JUMP, over2);
+ FIXJUMP1(over);
+ PUSH( "");
+ OP( STR_NEQ);
+ FIXJUMP1(over2);
+ }
+ return TCL_OK;
+
+ case STR_IS_BOOL:
+ case STR_IS_FALSE:
+ case STR_IS_TRUE:
+ OP( TRY_CVT_TO_BOOLEAN);
+ switch (t) {
+ int over, over2;
+
+ case STR_IS_BOOL:
+ if (allowEmpty) {
+ JUMP1( JUMP_TRUE, over);
+ PUSH( "");
+ OP( STR_EQ);
+ JUMP1( JUMP, over2);
+ FIXJUMP1(over);
+ OP( POP);
+ PUSH( "1");
+ FIXJUMP1(over2);
+ } else {
+ OP4( REVERSE, 2);
+ OP( POP);
+ }
+ return TCL_OK;
+ case STR_IS_TRUE:
+ JUMP1( JUMP_TRUE, over);
+ if (allowEmpty) {
+ PUSH( "");
+ OP( STR_EQ);
+ } else {
+ OP( POP);
+ PUSH( "0");
+ }
+ FIXJUMP1( over);
+ OP( LNOT);
+ OP( LNOT);
+ return TCL_OK;
+ case STR_IS_FALSE:
+ JUMP1( JUMP_TRUE, over);
+ if (allowEmpty) {
+ PUSH( "");
+ OP( STR_NEQ);
+ } else {
+ OP( POP);
+ PUSH( "1");
+ }
+ FIXJUMP1( over);
+ OP( LNOT);
+ return TCL_OK;
+ }
+
+ case STR_IS_DOUBLE: {
+ int satisfied, isEmpty;
+
+ if (allowEmpty) {
+ OP( DUP);
+ PUSH( "");
+ OP( STR_EQ);
+ JUMP1( JUMP_TRUE, isEmpty);
+ OP( NUM_TYPE);
+ JUMP1( JUMP_TRUE, satisfied);
+ PUSH( "0");
+ JUMP1( JUMP, end);
+ FIXJUMP1( isEmpty);
+ OP( POP);
+ FIXJUMP1( satisfied);
+ } else {
+ OP( NUM_TYPE);
+ JUMP1( JUMP_TRUE, satisfied);
+ PUSH( "0");
+ JUMP1( JUMP, end);
+ TclAdjustStackDepth(-1, envPtr);
+ FIXJUMP1( satisfied);
+ }
+ PUSH( "1");
+ FIXJUMP1( end);
+ return TCL_OK;
+ }
+
+ case STR_IS_INT:
+ case STR_IS_WIDE:
+ case STR_IS_ENTIER:
+ if (allowEmpty) {
+ int testNumType;
+
+ OP( DUP);
+ OP( NUM_TYPE);
+ OP( DUP);
+ JUMP1( JUMP_TRUE, testNumType);
+ OP( POP);
+ PUSH( "");
+ OP( STR_EQ);
+ JUMP1( JUMP, end);
+ TclAdjustStackDepth(1, envPtr);
+ FIXJUMP1( testNumType);
+ OP4( REVERSE, 2);
+ OP( POP);
+ } else {
+ OP( NUM_TYPE);
+ OP( DUP);
+ JUMP1( JUMP_FALSE, end);
+ }
+
+ switch (t) {
+ case STR_IS_INT:
+ PUSH( "1");
+ OP( EQ);
+ break;
+ case STR_IS_WIDE:
+ PUSH( "2");
+ OP( LE);
+ break;
+ case STR_IS_ENTIER:
+ PUSH( "3");
+ OP( LE);
+ break;
+ }
+ FIXJUMP1( end);
+ return TCL_OK;
+
+ case STR_IS_LIST:
+ range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+ OP4( BEGIN_CATCH4, range);
+ ExceptionRangeStarts(envPtr, range);
+ OP( DUP);
+ OP( LIST_LENGTH);
+ OP( POP);
+ ExceptionRangeEnds(envPtr, range);
+ ExceptionRangeTarget(envPtr, range, catchOffset);
+ OP( POP);
+ OP( PUSH_RETURN_CODE);
+ OP( END_CATCH);
+ OP( LNOT);
+ return TCL_OK;
+ }
+
+ return TclCompileBasicMin0ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+}
int
TclCompileStringMatchCmd(
@@ -439,7 +727,7 @@ TclCompileStringMatchCmd(
if (parsePtr->numWords == 4) {
if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_ERROR;
+ return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
}
str = tokenPtr[1].start;
length = tokenPtr[1].size;
@@ -448,7 +736,7 @@ TclCompileStringMatchCmd(
* Fail at run time, not in compilation.
*/
- return TCL_ERROR;
+ return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
}
nocase = 1;
tokenPtr = TokenAfter(tokenPtr);
@@ -494,25 +782,6 @@ TclCompileStringMatchCmd(
}
return TCL_OK;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclCompileStringLenCmd --
- *
- * Procedure called to compile the simplest and most common form of the
- * "string length" command.
- *
- * Results:
- * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
- * evaluation to runtime.
- *
- * Side effects:
- * Instructions are added to envPtr to execute the "string length"
- * command at runtime.
- *
- *----------------------------------------------------------------------
- */
int
TclCompileStringLenCmd(
@@ -553,6 +822,434 @@ TclCompileStringLenCmd(
TclDecrRefCount(objPtr);
return TCL_OK;
}
+
+int
+TclCompileStringMapCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *mapTokenPtr, *stringTokenPtr;
+ Tcl_Obj *mapObj, **objv;
+ char *bytes;
+ int len;
+
+ /*
+ * We only handle the case:
+ *
+ * string map {foo bar} $thing
+ *
+ * That is, a literal two-element list (doesn't need to be brace-quoted,
+ * but does need to be compile-time knowable) and any old argument (the
+ * thing to map).
+ */
+
+ if (parsePtr->numWords != 3) {
+ return TCL_ERROR;
+ }
+ mapTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ stringTokenPtr = TokenAfter(mapTokenPtr);
+ mapObj = Tcl_NewObj();
+ Tcl_IncrRefCount(mapObj);
+ if (!TclWordKnownAtCompileTime(mapTokenPtr, mapObj)) {
+ Tcl_DecrRefCount(mapObj);
+ return TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ } else if (Tcl_ListObjGetElements(NULL, mapObj, &len, &objv) != TCL_OK) {
+ Tcl_DecrRefCount(mapObj);
+ return TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ } else if (len != 2) {
+ Tcl_DecrRefCount(mapObj);
+ return TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ }
+
+ /*
+ * Now issue the opcodes. Note that in the case that we know that the
+ * first word is an empty word, we don't issue the map at all. That is the
+ * correct semantics for mapping.
+ */
+
+ bytes = Tcl_GetStringFromObj(objv[0], &len);
+ if (len == 0) {
+ CompileWord(envPtr, stringTokenPtr, interp, 2);
+ } else {
+ PushLiteral(envPtr, bytes, len);
+ bytes = Tcl_GetStringFromObj(objv[1], &len);
+ PushLiteral(envPtr, bytes, len);
+ CompileWord(envPtr, stringTokenPtr, interp, 2);
+ OP(STR_MAP);
+ }
+ Tcl_DecrRefCount(mapObj);
+ return TCL_OK;
+}
+
+int
+TclCompileStringRangeCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *stringTokenPtr, *fromTokenPtr, *toTokenPtr;
+ int idx1, idx2;
+
+ if (parsePtr->numWords != 4) {
+ return TCL_ERROR;
+ }
+ stringTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ fromTokenPtr = TokenAfter(stringTokenPtr);
+ toTokenPtr = TokenAfter(fromTokenPtr);
+
+ /*
+ * Parse the two indices.
+ */
+
+ if (GetIndexFromToken(fromTokenPtr, &idx1) != TCL_OK) {
+ goto nonConstantIndices;
+ }
+ if (GetIndexFromToken(toTokenPtr, &idx2) != TCL_OK) {
+ goto nonConstantIndices;
+ }
+
+ /*
+ * 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;
+
+ /*
+ * Push the operands onto the stack and then the substring operation.
+ */
+
+ nonConstantIndices:
+ CompileWord(envPtr, stringTokenPtr, interp, 1);
+ CompileWord(envPtr, fromTokenPtr, interp, 2);
+ CompileWord(envPtr, toTokenPtr, interp, 3);
+ OP( STR_RANGE);
+ return TCL_OK;
+}
+
+int
+TclCompileStringReplaceCmd(
+ Tcl_Interp *interp, /* Tcl interpreter for context. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the
+ * command. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds the resulting instructions. */
+{
+ Tcl_Token *tokenPtr, *valueTokenPtr, *replacementTokenPtr = NULL;
+ DefineLineInformation; /* TIP #280 */
+ int idx1, idx2;
+
+ if (parsePtr->numWords < 4 || parsePtr->numWords > 5) {
+ return TCL_ERROR;
+ }
+ valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ if (parsePtr->numWords == 5) {
+ tokenPtr = TokenAfter(valueTokenPtr);
+ tokenPtr = TokenAfter(tokenPtr);
+ replacementTokenPtr = TokenAfter(tokenPtr);
+ }
+
+ /*
+ * 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.
+ */
+
+ tokenPtr = TokenAfter(valueTokenPtr);
+ if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) {
+ goto genericReplace;
+ }
+
+ tokenPtr = TokenAfter(tokenPtr);
+ if (GetIndexFromToken(tokenPtr, &idx2) != 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.
+ */
+
+ if (idx1 == 0 && idx2 == 0) {
+ int notEq, end;
+
+ /*
+ * Just working with the first character.
+ */
+
+ CompileWord(envPtr, valueTokenPtr, interp, 1);
+ if (replacementTokenPtr == NULL) {
+ /* Drop first */
+ OP44( STR_RANGE_IMM, 1, INDEX_END);
+ return TCL_OK;
+ }
+ /* 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);
+ return TCL_OK;
+
+ } else if (idx1 == INDEX_END && idx2 == INDEX_END) {
+ int notEq, end;
+
+ /*
+ * Just working with the last character.
+ */
+
+ 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);
+ OP4( REVERSE, 2);
+ OP1( STR_CONCAT1, 2);
+ FIXJUMP1(end);
+ return TCL_OK;
+
+ } 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.
+ */
+
+ 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);
+ } else {
+ PUSH( "");
+ }
+ OP( STR_REPLACE);
+ return TCL_OK;
+ }
+}
+
+int
+TclCompileStringTrimLCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr;
+
+ if (parsePtr->numWords != 2 && parsePtr->numWords != 3) {
+ return TCL_ERROR;
+ }
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ if (parsePtr->numWords == 3) {
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 2);
+ } else {
+ PushLiteral(envPtr, tclDefaultTrimSet, strlen(tclDefaultTrimSet));
+ }
+ OP( STR_TRIM_LEFT);
+ return TCL_OK;
+}
+
+int
+TclCompileStringTrimRCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr;
+
+ if (parsePtr->numWords != 2 && parsePtr->numWords != 3) {
+ return TCL_ERROR;
+ }
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ if (parsePtr->numWords == 3) {
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 2);
+ } else {
+ PushLiteral(envPtr, tclDefaultTrimSet, strlen(tclDefaultTrimSet));
+ }
+ OP( STR_TRIM_RIGHT);
+ return TCL_OK;
+}
+
+int
+TclCompileStringTrimCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr;
+
+ if (parsePtr->numWords != 2 && parsePtr->numWords != 3) {
+ return TCL_ERROR;
+ }
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ if (parsePtr->numWords == 3) {
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 2);
+ } else {
+ PushLiteral(envPtr, tclDefaultTrimSet, strlen(tclDefaultTrimSet));
+ }
+ OP( STR_TRIM);
+ return TCL_OK;
+}
+
+int
+TclCompileStringToUpperCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr;
+
+ if (parsePtr->numWords != 2) {
+ return TclCompileBasic1To3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ }
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ OP( STR_UPPER);
+ return TCL_OK;
+}
+
+int
+TclCompileStringToLowerCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr;
+
+ if (parsePtr->numWords != 2) {
+ return TclCompileBasic1To3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ }
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ OP( STR_LOWER);
+ return TCL_OK;
+}
+
+int
+TclCompileStringToTitleCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr;
+
+ if (parsePtr->numWords != 2) {
+ return TclCompileBasic1To3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ }
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ OP( STR_TITLE);
+ return TCL_OK;
+}
+
+/*
+ * Support definitions for the [string is] compilation.
+ */
+
+static int
+UniCharIsAscii(
+ int character)
+{
+ return (character >= 0) && (character < 0x80);
+}
+
+static int
+UniCharIsHexDigit(
+ int character)
+{
+ return (character >= 0) && (character < 0x80) && isxdigit(character);
+}
+
+StringClassDesc const tclStringClassTable[] = {
+ {"alnum", Tcl_UniCharIsAlnum},
+ {"alpha", Tcl_UniCharIsAlpha},
+ {"ascii", UniCharIsAscii},
+ {"control", Tcl_UniCharIsControl},
+ {"digit", Tcl_UniCharIsDigit},
+ {"graph", Tcl_UniCharIsGraph},
+ {"lower", Tcl_UniCharIsLower},
+ {"print", Tcl_UniCharIsPrint},
+ {"punct", Tcl_UniCharIsPunct},
+ {"space", Tcl_UniCharIsSpace},
+ {"upper", Tcl_UniCharIsUpper},
+ {"word", Tcl_UniCharIsWordChar},
+ {"xdigit", UniCharIsHexDigit},
+ {NULL, NULL}
+};
/*
*----------------------------------------------------------------------
@@ -656,18 +1353,21 @@ TclSubstCompile(
Tcl_InterpState state = NULL;
TclSubstParse(interp, bytes, numBytes, flags, &parse, &state);
+ if (state != NULL) {
+ Tcl_ResetResult(interp);
+ }
/*
* Tricky point! If the first token does not result in a *guaranteed* push
* of a Tcl_Obj on the stack, we must push an empty object. Otherwise it
- * is possible to get to an INST_CONCAT1 or INST_DONE without enough
+ * is possible to get to an INST_STR_CONCAT1 or INST_DONE without enough
* values on the stack, resulting in a crash. Thanks to Joe Mistachkin for
* identifying a script that could trigger this case.
*/
tokenPtr = parse.tokenPtr;
if (tokenPtr->type != TCL_TOKEN_TEXT && tokenPtr->type != TCL_TOKEN_BS) {
- PushLiteral(envPtr, "", 0);
+ PUSH("");
count++;
}
@@ -694,14 +1394,42 @@ TclSubstCompile(
TclEmitPush(literal, envPtr);
count++;
continue;
+ case TCL_TOKEN_VARIABLE:
+ /*
+ * Check for simple variable access; see if we can only generate
+ * TCL_OK or TCL_ERROR from the substituted variable read; if so,
+ * there is no need to generate elaborate exception-management
+ * code. Note that the first component of TCL_TOKEN_VARIABLE is
+ * always TCL_TOKEN_TEXT...
+ */
+
+ if (tokenPtr->numComponents > 1) {
+ int i, foundCommand = 0;
+
+ for (i=2 ; i<=tokenPtr->numComponents ; i++) {
+ if (tokenPtr[i].type == TCL_TOKEN_COMMAND) {
+ foundCommand = 1;
+ break;
+ }
+ }
+ if (foundCommand) {
+ break;
+ }
+ }
+
+ envPtr->line = bline;
+ TclCompileVarSubst(interp, tokenPtr, envPtr);
+ bline = envPtr->line;
+ count++;
+ continue;
}
while (count > 255) {
- TclEmitInstInt1(INST_CONCAT1, 255, envPtr);
+ OP1( STR_CONCAT1, 255);
count -= 254;
}
if (count > 1) {
- TclEmitInstInt1(INST_CONCAT1, count, envPtr);
+ OP1( STR_CONCAT1, count);
count = 1;
}
@@ -721,8 +1449,8 @@ TclSubstCompile(
}
envPtr->line = bline;
- catchRange = DeclareExceptionRange(envPtr, CATCH_EXCEPTION_RANGE);
- TclEmitInstInt4(INST_BEGIN_CATCH4, catchRange, envPtr);
+ catchRange = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+ OP4( BEGIN_CATCH4, catchRange);
ExceptionRangeStarts(envPtr, catchRange);
switch (tokenPtr->type) {
@@ -743,20 +1471,21 @@ TclSubstCompile(
ExceptionRangeEnds(envPtr, catchRange);
/* Substitution produced TCL_OK */
- TclEmitOpcode(INST_END_CATCH, envPtr);
+ OP( END_CATCH);
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &okFixup);
+ TclAdjustStackDepth(-1, envPtr);
/* Exceptional return codes processed here */
ExceptionRangeTarget(envPtr, catchRange, catchOffset);
- TclEmitOpcode(INST_PUSH_RETURN_OPTIONS, envPtr);
- TclEmitOpcode(INST_PUSH_RESULT, envPtr);
- TclEmitOpcode(INST_PUSH_RETURN_CODE, envPtr);
- TclEmitOpcode(INST_END_CATCH, envPtr);
- TclEmitOpcode(INST_RETURN_CODE_BRANCH, envPtr);
+ OP( PUSH_RETURN_OPTIONS);
+ OP( PUSH_RESULT);
+ OP( PUSH_RETURN_CODE);
+ OP( END_CATCH);
+ OP( RETURN_CODE_BRANCH);
- /* ERROR -> reraise it */
- TclEmitOpcode(INST_RETURN_STK, envPtr);
- TclEmitOpcode(INST_NOP, envPtr);
+ /* ERROR -> reraise it; NB: can't require BREAK/CONTINUE handling */
+ OP( RETURN_STK);
+ OP( NOP);
/* RETURN */
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &returnFixup);
@@ -770,30 +1499,33 @@ TclSubstCompile(
/* OTHER */
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &otherFixup);
+ TclAdjustStackDepth(1, envPtr);
/* BREAK destination */
if (TclFixupForwardJumpToHere(envPtr, &breakFixup, 127)) {
Tcl_Panic("TclCompileSubstCmd: bad break jump distance %d",
(int) (CurrentOffset(envPtr) - breakFixup.codeOffset));
}
- TclEmitOpcode(INST_POP, envPtr);
- TclEmitOpcode(INST_POP, envPtr);
+ OP( POP);
+ OP( POP);
breakJump = CurrentOffset(envPtr) - breakOffset;
if (breakJump > 127) {
- TclEmitInstInt4(INST_JUMP4, -breakJump, envPtr);
+ OP4(JUMP4, -breakJump);
} else {
- TclEmitInstInt1(INST_JUMP1, -breakJump, envPtr);
+ OP1(JUMP1, -breakJump);
}
+ TclAdjustStackDepth(2, envPtr);
/* CONTINUE destination */
if (TclFixupForwardJumpToHere(envPtr, &continueFixup, 127)) {
Tcl_Panic("TclCompileSubstCmd: bad continue jump distance %d",
(int) (CurrentOffset(envPtr) - continueFixup.codeOffset));
}
- TclEmitOpcode(INST_POP, envPtr);
- TclEmitOpcode(INST_POP, envPtr);
+ OP( POP);
+ OP( POP);
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &endFixup);
+ TclAdjustStackDepth(2, envPtr);
/* RETURN + other destination */
if (TclFixupForwardJumpToHere(envPtr, &returnFixup, 127)) {
Tcl_Panic("TclCompileSubstCmd: bad return jump distance %d",
@@ -808,19 +1540,8 @@ TclSubstCompile(
* Pull the result to top of stack, discard options dict.
*/
- TclEmitInstInt4(INST_REVERSE, 2, envPtr);
- TclEmitOpcode(INST_POP, envPtr);
-
- /*
- * We've emitted several POP instructions, and the automatic
- * computations for stack depth requirements have been decrementing
- * for every one. However, we know that every branch actually taken
- * only encounters some of those instructions. No branch passes
- * through them all. So, we now have a stack requirements estimate
- * that is too low. Here we manually fix that up.
- */
-
- TclAdjustStackDepth(5, envPtr);
+ OP4( REVERSE, 2);
+ OP( POP);
/* OK destination */
if (TclFixupForwardJumpToHere(envPtr, &okFixup, 127)) {
@@ -828,7 +1549,7 @@ TclSubstCompile(
(int) (CurrentOffset(envPtr) - okFixup.codeOffset));
}
if (count > 1) {
- TclEmitInstInt1(INST_CONCAT1, count, envPtr);
+ OP1(STR_CONCAT1, count);
count = 1;
}
@@ -840,13 +1561,12 @@ TclSubstCompile(
bline = envPtr->line;
}
-
while (count > 255) {
- TclEmitInstInt1(INST_CONCAT1, 255, envPtr);
+ OP1( STR_CONCAT1, 255);
count -= 254;
}
if (count > 1) {
- TclEmitInstInt1(INST_CONCAT1, count, envPtr);
+ OP1( STR_CONCAT1, count);
}
Tcl_FreeParse(&parse);
@@ -854,6 +1574,7 @@ TclSubstCompile(
if (state != NULL) {
Tcl_RestoreInterpState(interp, state);
TclCompileSyntaxError(interp, envPtr);
+ TclAdjustStackDepth(-1, envPtr);
}
/* Final target of the multi-jump from all BREAKs */
@@ -880,9 +1601,6 @@ TclSubstCompile(
* Instructions are added to envPtr to execute the "switch" command at
* runtime.
*
- * FIXME:
- * Stack depths are probably not calculated correctly.
- *
*----------------------------------------------------------------------
*/
@@ -1082,12 +1800,7 @@ TclCompileSwitchCmd(
if (TCL_OK != TclFindElement(NULL, bytes, numBytes,
&(bodyTokenArray[numWords].start), &bytes,
&(bodyTokenArray[numWords].size), &literal) || !literal) {
- abort:
- ckfree((char *) bodyToken);
- ckfree((char *) bodyTokenArray);
- ckfree((char *) bodyLines);
- ckfree((char *) bodyContLines);
- return TCL_ERROR;
+ goto abort;
}
bodyTokenArray[numWords].type = TCL_TOKEN_TEXT;
@@ -1112,7 +1825,12 @@ TclCompileSwitchCmd(
numWords++;
}
if (numWords % 2) {
- goto abort;
+ abort:
+ ckfree((char *) bodyToken);
+ ckfree((char *) bodyTokenArray);
+ ckfree((char *) bodyLines);
+ ckfree((char *) bodyContLines);
+ return TCL_ERROR;
}
} else if (numWords % 2 || numWords == 0) {
/*
@@ -1173,13 +1891,15 @@ TclCompileSwitchCmd(
* but it handles the most common case well enough.
*/
+ /* Both methods push the value to match against onto the stack. */
+ CompileWord(envPtr, valueTokenPtr, interp, valueIndex);
+
if (mode == Switch_Exact) {
- IssueSwitchJumpTable(interp, envPtr, mapPtr, eclIndex, valueIndex,
- valueTokenPtr, numWords, bodyToken, bodyLines, bodyContLines);
+ IssueSwitchJumpTable(interp, envPtr, valueIndex, numWords, bodyToken,
+ bodyLines, bodyContLines);
} else {
- IssueSwitchChainedTests(interp, envPtr, mapPtr, eclIndex, mode,noCase,
- valueIndex, valueTokenPtr, numWords, bodyToken, bodyLines,
- bodyContLines);
+ IssueSwitchChainedTests(interp, envPtr, mode, noCase, valueIndex,
+ numWords, bodyToken, bodyLines, bodyContLines);
}
result = TCL_OK;
@@ -1217,13 +1937,9 @@ static void
IssueSwitchChainedTests(
Tcl_Interp *interp, /* Context for compiling script bodies. */
CompileEnv *envPtr, /* Holds resulting instructions. */
- ExtCmdLoc *mapPtr, /* For mapping tokens to their source code
- * location. */
- int eclIndex,
int mode, /* Exact, Glob or Regexp */
int noCase, /* Case-insensitivity flag. */
int valueIndex, /* The value to match against. */
- Tcl_Token *valueTokenPtr,
int numBodyTokens, /* Number of tokens describing things the
* switch can match against and bodies to
* execute when the match succeeds. */
@@ -1233,7 +1949,6 @@ IssueSwitchChainedTests(
int **bodyContLines) /* Array of continuation line info. */
{
enum {Switch_Exact, Switch_Glob, Switch_Regexp};
- int savedStackDepth = envPtr->currStackDepth;
int foundDefault; /* Flag to indicate whether a "default" clause
* is present. */
JumpFixup *fixupArray; /* Array of forward-jump fixup records. */
@@ -1249,13 +1964,6 @@ IssueSwitchChainedTests(
int i;
/*
- * First, we push the value we're matching against on the stack.
- */
-
- SetLineInformation(valueIndex);
- CompileTokens(envPtr, valueTokenPtr, interp);
-
- /*
* Generate a test for each arm.
*/
@@ -1268,7 +1976,6 @@ IssueSwitchChainedTests(
foundDefault = 0;
for (i=0 ; i<numBodyTokens ; i+=2) {
nextArmFixupIndex = -1;
- envPtr->currStackDepth = savedStackDepth + 1;
if (i!=numBodyTokens-2 || bodyToken[numBodyTokens-2]->size != 7 ||
memcmp(bodyToken[numBodyTokens-2]->start, "default", 7)) {
/*
@@ -1277,14 +1984,14 @@ IssueSwitchChainedTests(
switch (mode) {
case Switch_Exact:
- TclEmitOpcode(INST_DUP, envPtr);
+ OP( DUP);
TclCompileTokens(interp, bodyToken[i], 1, envPtr);
- TclEmitOpcode(INST_STR_EQ, envPtr);
+ OP( STR_EQ);
break;
case Switch_Glob:
TclCompileTokens(interp, bodyToken[i], 1, envPtr);
- TclEmitInstInt4(INST_OVER, 1, envPtr);
- TclEmitInstInt1(INST_STR_MATCH, noCase, envPtr);
+ OP4( OVER, 1);
+ OP1( STR_MATCH, noCase);
break;
case Switch_Regexp:
simple = exact = 0;
@@ -1302,7 +2009,7 @@ IssueSwitchChainedTests(
* when the RE == "".
*/
- PushLiteral(envPtr, "1", 1);
+ PUSH("1");
break;
}
@@ -1323,7 +2030,7 @@ IssueSwitchChainedTests(
TclCompileTokens(interp, bodyToken[i], 1, envPtr);
}
- TclEmitInstInt4(INST_OVER, 1, envPtr);
+ OP4( OVER, 1);
if (!simple) {
/*
* Pass correct RE compile flags. We use only Int1
@@ -1335,11 +2042,11 @@ IssueSwitchChainedTests(
int cflags = TCL_REG_ADVANCED
| (noCase ? TCL_REG_NOCASE : 0);
- TclEmitInstInt1(INST_REGEXP, cflags, envPtr);
+ OP1(REGEXP, cflags);
} else if (exact && !noCase) {
- TclEmitOpcode(INST_STR_EQ, envPtr);
+ OP( STR_EQ);
} else {
- TclEmitInstInt1(INST_STR_MATCH, noCase, envPtr);
+ OP1(STR_MATCH, noCase);
}
break;
default:
@@ -1399,13 +2106,12 @@ IssueSwitchChainedTests(
}
/*
- * Now do the actual compilation. Note that we do not use CompileBody
+ * Now do the actual compilation. Note that we do not use BODY()
* because we may have synthesized the tokens in a non-standard
* pattern.
*/
- TclEmitOpcode(INST_POP, envPtr);
- envPtr->currStackDepth = savedStackDepth + 1;
+ OP( POP);
envPtr->line = bodyLines[i+1]; /* TIP #280 */
envPtr->clNext = bodyContLines[i+1]; /* TIP #280 */
TclCompileCmdWord(interp, bodyToken[i+1], 1, envPtr);
@@ -1426,8 +2132,8 @@ IssueSwitchChainedTests(
*/
if (!foundDefault) {
- TclEmitOpcode(INST_POP, envPtr);
- PushLiteral(envPtr, "", 0);
+ OP( POP);
+ PUSH("");
}
/*
@@ -1463,8 +2169,6 @@ IssueSwitchChainedTests(
}
TclStackFree(interp, fixupTargetArray);
TclStackFree(interp, fixupArray);
-
- envPtr->currStackDepth = savedStackDepth + 1;
}
/*
@@ -1484,11 +2188,7 @@ static void
IssueSwitchJumpTable(
Tcl_Interp *interp, /* Context for compiling script bodies. */
CompileEnv *envPtr, /* Holds resulting instructions. */
- ExtCmdLoc *mapPtr, /* For mapping tokens to their source code
- * location. */
- int eclIndex,
int valueIndex, /* The value to match against. */
- Tcl_Token *valueTokenPtr,
int numBodyTokens, /* Number of tokens describing things the
* switch can match against and bodies to
* execute when the match succeeds. */
@@ -1504,13 +2204,6 @@ IssueSwitchJumpTable(
Tcl_HashEntry *hPtr;
/*
- * First, we push the value we're matching against on the stack.
- */
-
- SetLineInformation(valueIndex);
- CompileTokens(envPtr, valueTokenPtr, interp);
-
- /*
* Compile the switch by using a jump table, which is basically a
* hashtable that maps from literal values to match against to the offset
* (relative to the INST_JUMP_TABLE instruction) to jump to. The jump
@@ -1537,9 +2230,9 @@ IssueSwitchJumpTable(
*/
jumpLocation = CurrentOffset(envPtr);
- TclEmitInstInt4(INST_JUMP_TABLE, infoIndex, envPtr);
+ OP4( JUMP_TABLE, infoIndex);
jumpToDefault = CurrentOffset(envPtr);
- TclEmitInstInt4(INST_JUMP4, 0, envPtr);
+ OP4( JUMP4, 0);
for (i=0 ; i<numBodyTokens ; i+=2) {
/*
@@ -1558,8 +2251,7 @@ IssueSwitchJumpTable(
*/
Tcl_DStringInit(&buffer);
- Tcl_DStringAppend(&buffer, bodyToken[i]->start,
- bodyToken[i]->size);
+ TclDStringAppendToken(&buffer, bodyToken[i]);
hPtr = Tcl_CreateHashEntry(&jtPtr->hashTable,
Tcl_DStringValue(&buffer), &isNew);
if (isNew) {
@@ -1631,7 +2323,8 @@ IssueSwitchJumpTable(
* rewriting when we fixed this all up.
*/
- TclEmitInstInt4(INST_JUMP4, 0, envPtr);
+ OP4( JUMP4, 0);
+ TclAdjustStackDepth(-1, envPtr);
}
}
@@ -1644,7 +2337,7 @@ IssueSwitchJumpTable(
if (!foundDefault) {
TclStoreInt4AtPtr(CurrentOffset(envPtr)-jumpToDefault,
envPtr->codeStart+jumpToDefault+1);
- PushLiteral(envPtr, "", 0);
+ PUSH("");
}
/*
@@ -1747,6 +2440,53 @@ PrintJumptableInfo(
/*
*----------------------------------------------------------------------
*
+ * TclCompileTailcallCmd --
+ *
+ * Procedure called to compile the "tailcall" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "tailcall" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileTailcallCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+ int i;
+
+ if (parsePtr->numWords < 2 || parsePtr->numWords > 256
+ || envPtr->procPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ /* make room for the nsObjPtr */
+ /* TODO: Doesn't this have to be a known value? */
+ CompileWord(envPtr, tokenPtr, interp, 0);
+ for (i=1 ; i<parsePtr->numWords ; i++) {
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, i);
+ }
+ TclEmitInstInt1( INST_TAILCALL, parsePtr->numWords, envPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclCompileThrowCmd --
*
* Procedure called to compile the "throw" command.
@@ -1775,6 +2515,7 @@ TclCompileThrowCmd(
int numWords = parsePtr->numWords;
Tcl_Token *codeToken, *msgToken;
Tcl_Obj *objPtr;
+ int codeKnown, codeIsList, codeIsValid, len;
if (numWords != 3) {
return TCL_ERROR;
@@ -1784,74 +2525,66 @@ TclCompileThrowCmd(
TclNewObj(objPtr);
Tcl_IncrRefCount(objPtr);
- if (TclWordKnownAtCompileTime(codeToken, objPtr)) {
- Tcl_Obj *errPtr, *dictPtr;
- const char *string;
- int len;
- /*
- * The code is known at compilation time. This allows us to issue a
- * very efficient sequence of instructions.
- */
+ codeKnown = TclWordKnownAtCompileTime(codeToken, objPtr);
- if (Tcl_ListObjLength(interp, objPtr, &len) != TCL_OK) {
- /*
- * Must still do this; might generate an error when getting this
- * "ignored" value prepared as an argument.
- */
+ /*
+ * First we must emit the code to substitute the arguments. This
+ * must come first in case substitution raises errors.
+ */
+ if (!codeKnown) {
+ CompileWord(envPtr, codeToken, interp, 1);
+ PUSH( "-errorcode");
+ }
+ CompileWord(envPtr, msgToken, interp, 2);
- CompileWord(envPtr, msgToken, interp, 2);
- TclCompileSyntaxError(interp, envPtr);
- Tcl_DecrRefCount(objPtr);
- return TCL_OK;
- }
- if (len == 0) {
- /*
- * Must still do this; might generate an error when getting this
- * "ignored" value prepared as an argument.
- */
+ codeIsList = codeKnown && (TCL_OK ==
+ Tcl_ListObjLength(interp, objPtr, &len));
+ codeIsValid = codeIsList && (len != 0);
+
+ if (codeIsValid) {
+ Tcl_Obj *errPtr, *dictPtr;
- CompileWord(envPtr, msgToken, interp, 2);
- goto issueErrorForEmptyCode;
- }
TclNewLiteralStringObj(errPtr, "-errorcode");
TclNewObj(dictPtr);
Tcl_DictObjPut(NULL, dictPtr, errPtr, objPtr);
- Tcl_IncrRefCount(dictPtr);
- string = Tcl_GetStringFromObj(dictPtr, &len);
- CompileWord(envPtr, msgToken, interp, 2);
- PushLiteral(envPtr, string, len);
- TclDecrRefCount(dictPtr);
- OP44( RETURN_IMM, 1, 0);
- } else {
- /*
- * When the code token is not known at compilation time, we need to do
- * a little bit more work. The main tricky bit here is that the error
- * code has to be a list (a [throw] restriction) so we must emit extra
- * instructions to enforce that condition.
- */
+ TclEmitPush(TclAddLiteralObj(envPtr, dictPtr, NULL), envPtr);
+ }
+ TclDecrRefCount(objPtr);
- CompileWord(envPtr, codeToken, interp, 1);
- PUSH( "-errorcode");
- CompileWord(envPtr, msgToken, interp, 2);
- OP4( REVERSE, 3);
- OP( DUP);
- OP( LIST_LENGTH);
- OP1( JUMP_FALSE1, 16);
- OP4( LIST, 2);
- OP44( RETURN_IMM, 1, 0);
+ /*
+ * Simpler bytecodes when we detect invalid arguments at compile time.
+ */
+ if (codeKnown && !codeIsValid) {
+ OP( POP);
+ if (codeIsList) {
+ /* Must be an empty list */
+ goto issueErrorForEmptyCode;
+ }
+ TclCompileSyntaxError(interp, envPtr);
+ return TCL_OK;
+ }
+ if (!codeKnown) {
/*
- * Generate an error for being an empty list. Can't leverage anything
- * else to do this for us.
+ * Argument validity checking has to be done by bytecode at
+ * run time.
*/
-
+ OP4( REVERSE, 3);
+ OP( DUP);
+ OP( LIST_LENGTH);
+ OP1( JUMP_FALSE1, 16);
+ OP4( LIST, 2);
+ OP44( RETURN_IMM, TCL_ERROR, 0);
+ TclAdjustStackDepth(2, envPtr);
+ OP( POP);
+ OP( POP);
+ OP( POP);
issueErrorForEmptyCode:
- PUSH( "type must be non-empty list");
- PUSH( "");
- OP44( RETURN_IMM, 1, 0);
+ PUSH( "type must be non-empty list");
+ PUSH( "-errorcode {TCL OPERATION THROW BADEXCEPTION}");
}
- TclDecrRefCount(objPtr);
+ OP44( RETURN_IMM, TCL_ERROR, 0);
return TCL_OK;
}
@@ -1901,8 +2634,7 @@ TclCompileTryCmd(
*/
DefineLineInformation; /* TIP #280 */
- SetLineInformation(1);
- CompileBody(envPtr, bodyToken, interp);
+ BODY(bodyToken, 1);
return TCL_OK;
}
@@ -1993,12 +2725,11 @@ TclCompileTryCmd(
int len;
const char *varname = Tcl_GetStringFromObj(objv[0], &len);
- if (!TclIsLocalScalar(varname, len)) {
+ resultVarIndices[i] = LocalScalar(varname, len, envPtr);
+ if (resultVarIndices[i] < 0) {
TclDecrRefCount(tmpObj);
goto failedToCompile;
}
- resultVarIndices[i] =
- TclFindCompiledLocal(varname, len, 1, envPtr);
} else {
resultVarIndices[i] = -1;
}
@@ -2006,12 +2737,11 @@ TclCompileTryCmd(
int len;
const char *varname = Tcl_GetStringFromObj(objv[1], &len);
- if (!TclIsLocalScalar(varname, len)) {
+ optionVarIndices[i] = LocalScalar(varname, len, envPtr);
+ if (optionVarIndices[i] < 0) {
TclDecrRefCount(tmpObj);
goto failedToCompile;
}
- optionVarIndices[i] =
- TclFindCompiledLocal(varname, len, 1, envPtr);
} else {
optionVarIndices[i] = -1;
}
@@ -2059,14 +2789,17 @@ TclCompileTryCmd(
* Issue the bytecode.
*/
- if (finallyToken) {
+ if (!finallyToken) {
+ result = IssueTryClausesInstructions(interp, envPtr, bodyToken,
+ numHandlers, matchCodes, matchClauses, resultVarIndices,
+ optionVarIndices, handlerTokens);
+ } else if (numHandlers == 0) {
result = IssueTryFinallyInstructions(interp, envPtr, bodyToken,
+ finallyToken);
+ } else {
+ result = IssueTryClausesFinallyInstructions(interp, envPtr, bodyToken,
numHandlers, matchCodes, matchClauses, resultVarIndices,
optionVarIndices, handlerTokens, finallyToken);
- } else {
- result = IssueTryInstructions(interp, envPtr, bodyToken, numHandlers,
- matchCodes, matchClauses, resultVarIndices, optionVarIndices,
- handlerTokens);
}
/*
@@ -2092,12 +2825,13 @@ TclCompileTryCmd(
/*
*----------------------------------------------------------------------
*
- * IssueTryInstructions, IssueTryFinallyInstructions --
+ * IssueTryClausesInstructions, IssueTryClausesFinallyInstructions,
+ * IssueTryFinallyInstructions --
*
* The code generators for [try]. Split from the parsing engine for
- * reasons of developer sanity, and also split between no-finally and
- * with-finally cases because so many of the details of generation vary
- * between the two.
+ * reasons of developer sanity, and also split between no-finally,
+ * just-finally and with-finally cases because so many of the details of
+ * generation vary between the three.
*
* The macros below make the instruction issuing easier to follow.
*
@@ -2105,7 +2839,7 @@ TclCompileTryCmd(
*/
static int
-IssueTryInstructions(
+IssueTryClausesInstructions(
Tcl_Interp *interp,
CompileEnv *envPtr,
Tcl_Token *bodyToken,
@@ -2118,31 +2852,51 @@ IssueTryInstructions(
{
DefineLineInformation; /* TIP #280 */
int range, resultVar, optionsVar;
- int i, j, len, forwardsNeedFixing = 0;
+ int i, j, len, forwardsNeedFixing = 0, trapZero = 0, afterBody = 0;
int *addrsToFix, *forwardsToFix, notCodeJumpSource, notECJumpSource;
+ int *noError;
char buf[TCL_INTEGER_SPACE];
- resultVar = TclFindCompiledLocal(NULL, 0, 1, envPtr);
- optionsVar = TclFindCompiledLocal(NULL, 0, 1, envPtr);
+ resultVar = AnonymousLocal(envPtr);
+ optionsVar = AnonymousLocal(envPtr);
if (resultVar < 0 || optionsVar < 0) {
return TCL_ERROR;
}
/*
+ * Check if we're supposed to trap a normal TCL_OK completion of the body.
+ * If not, we can handle that case much more efficiently.
+ */
+
+ for (i=0 ; i<numHandlers ; i++) {
+ if (matchCodes[i] == 0) {
+ trapZero = 1;
+ break;
+ }
+ }
+
+ /*
* Compile the body, trapping any error in it so that we can trap on it
* and/or run a finally clause. Note that there must be at least one
* on/trap clause; when none is present, this whole function is not called
* (and it's never called when there's a finally clause).
*/
- range = DeclareExceptionRange(envPtr, CATCH_EXCEPTION_RANGE);
+ range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
OP4( BEGIN_CATCH4, range);
ExceptionRangeStarts(envPtr, range);
BODY( bodyToken, 1);
ExceptionRangeEnds(envPtr, range);
- PUSH( "0");
- OP4( REVERSE, 2);
- OP1( JUMP1, 4);
+ if (!trapZero) {
+ OP( END_CATCH);
+ JUMP4( JUMP, afterBody);
+ TclAdjustStackDepth(-1, envPtr);
+ } else {
+ PUSH( "0");
+ OP4( REVERSE, 2);
+ OP1( JUMP1, 4);
+ TclAdjustStackDepth(-2, envPtr);
+ }
ExceptionRangeTarget(envPtr, range, catchOffset);
OP( PUSH_RETURN_CODE);
OP( PUSH_RESULT);
@@ -2162,14 +2916,17 @@ IssueTryInstructions(
addrsToFix = TclStackAlloc(interp, sizeof(int)*numHandlers);
forwardsToFix = TclStackAlloc(interp, sizeof(int)*numHandlers);
+ noError = TclStackAlloc(interp, sizeof(int)*numHandlers);
for (i=0 ; i<numHandlers ; i++) {
+ noError[i] = -1;
sprintf(buf, "%d", matchCodes[i]);
OP( DUP);
- PUSH( buf);
+ PushLiteral(envPtr, buf, strlen(buf));
OP( EQ);
- JUMP(notCodeJumpSource, JUMP_FALSE4);
+ JUMP4( JUMP_FALSE, notCodeJumpSource);
if (matchClauses[i]) {
+ const char *p;
Tcl_ListObjLength(NULL, matchClauses[i], &len);
/*
@@ -2179,10 +2936,12 @@ IssueTryInstructions(
LOAD( optionsVar);
PUSH( "-errorcode");
OP4( DICT_GET, 1);
+ TclAdjustStackDepth(-1, envPtr);
OP44( LIST_RANGE_IMM, 0, len-1);
- PUSH( TclGetString(matchClauses[i]));
+ p = Tcl_GetStringFromObj(matchClauses[i], &len);
+ PushLiteral(envPtr, p, len);
OP( STR_EQ);
- JUMP(notECJumpSource, JUMP_FALSE4);
+ JUMP4( JUMP_FALSE, notECJumpSource);
} else {
notECJumpSource = -1; /* LINT */
}
@@ -2206,8 +2965,10 @@ IssueTryInstructions(
}
if (!handlerTokens[i]) {
forwardsNeedFixing = 1;
- JUMP(forwardsToFix[i], JUMP4);
+ JUMP4( JUMP, forwardsToFix[i]);
} else {
+ int dontChangeOptions;
+
forwardsToFix[i] = -1;
if (forwardsNeedFixing) {
forwardsNeedFixing = 0;
@@ -2215,18 +2976,44 @@ IssueTryInstructions(
if (forwardsToFix[j] == -1) {
continue;
}
- FIXJUMP(forwardsToFix[j]);
+ FIXJUMP4(forwardsToFix[j]);
forwardsToFix[j] = -1;
}
}
+ range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+ OP4( BEGIN_CATCH4, range);
+ ExceptionRangeStarts(envPtr, range);
BODY( handlerTokens[i], 5+i*4);
+ ExceptionRangeEnds(envPtr, range);
+ OP( END_CATCH);
+ JUMP4( JUMP, noError[i]);
+ ExceptionRangeTarget(envPtr, range, catchOffset);
+ TclAdjustStackDepth(-1, envPtr);
+ OP( PUSH_RESULT);
+ OP( PUSH_RETURN_OPTIONS);
+ OP( PUSH_RETURN_CODE);
+ OP( END_CATCH);
+ PUSH( "1");
+ OP( EQ);
+ JUMP1( JUMP_FALSE, dontChangeOptions);
+ LOAD( optionsVar);
+ OP4( REVERSE, 2);
+ STORE( optionsVar);
+ OP( POP);
+ PUSH( "-during");
+ OP4( REVERSE, 2);
+ OP44( DICT_SET, 1, optionsVar);
+ TclAdjustStackDepth(-1, envPtr);
+ FIXJUMP1( dontChangeOptions);
+ OP4( REVERSE, 2);
+ INVOKE( RETURN_STK);
}
- JUMP(addrsToFix[i], JUMP4);
+ JUMP4( JUMP, addrsToFix[i]);
if (matchClauses[i]) {
- FIXJUMP(notECJumpSource);
+ FIXJUMP4( notECJumpSource);
}
- FIXJUMP(notCodeJumpSource);
+ FIXJUMP4( notCodeJumpSource);
}
/*
@@ -2238,23 +3025,30 @@ IssueTryInstructions(
OP( POP);
LOAD( optionsVar);
LOAD( resultVar);
- OP( RETURN_STK);
+ INVOKE( RETURN_STK);
/*
* Fix all the jumps from taken clauses to here (which is the end of the
* [try]).
*/
+ if (!trapZero) {
+ FIXJUMP4(afterBody);
+ }
for (i=0 ; i<numHandlers ; i++) {
- FIXJUMP(addrsToFix[i]);
+ FIXJUMP4(addrsToFix[i]);
+ if (noError[i] != -1) {
+ FIXJUMP4(noError[i]);
+ }
}
+ TclStackFree(interp, noError);
TclStackFree(interp, forwardsToFix);
TclStackFree(interp, addrsToFix);
return TCL_OK;
}
static int
-IssueTryFinallyInstructions(
+IssueTryClausesFinallyInstructions(
Tcl_Interp *interp,
CompileEnv *envPtr,
Tcl_Token *bodyToken,
@@ -2267,30 +3061,53 @@ IssueTryFinallyInstructions(
Tcl_Token *finallyToken) /* Not NULL */
{
DefineLineInformation; /* TIP #280 */
- int savedStackDepth = envPtr->currStackDepth;
int range, resultVar, optionsVar, i, j, len, forwardsNeedFixing = 0;
+ int trapZero = 0, afterBody = 0, finalOK, finalError, noFinalError;
int *addrsToFix, *forwardsToFix, notCodeJumpSource, notECJumpSource;
char buf[TCL_INTEGER_SPACE];
- resultVar = TclFindCompiledLocal(NULL, 0, 1, envPtr);
- optionsVar = TclFindCompiledLocal(NULL, 0, 1, envPtr);
+ resultVar = AnonymousLocal(envPtr);
+ optionsVar = AnonymousLocal(envPtr);
if (resultVar < 0 || optionsVar < 0) {
return TCL_ERROR;
}
/*
+ * Check if we're supposed to trap a normal TCL_OK completion of the body.
+ * If not, we can handle that case much more efficiently.
+ */
+
+ for (i=0 ; i<numHandlers ; i++) {
+ if (matchCodes[i] == 0) {
+ trapZero = 1;
+ break;
+ }
+ }
+
+ /*
* Compile the body, trapping any error in it so that we can trap on it
* (if any trap matches) and run a finally clause.
*/
- range = DeclareExceptionRange(envPtr, CATCH_EXCEPTION_RANGE);
+ range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
OP4( BEGIN_CATCH4, range);
ExceptionRangeStarts(envPtr, range);
BODY( bodyToken, 1);
ExceptionRangeEnds(envPtr, range);
- PUSH( "0");
- OP4( REVERSE, 2);
- OP1( JUMP1, 4);
+ if (!trapZero) {
+ OP( END_CATCH);
+ STORE( resultVar);
+ OP( POP);
+ PUSH( "-level 0 -code 0");
+ STORE( optionsVar);
+ OP( POP);
+ JUMP4( JUMP, afterBody);
+ } else {
+ PUSH( "0");
+ OP4( REVERSE, 2);
+ OP1( JUMP1, 4);
+ TclAdjustStackDepth(-2, envPtr);
+ }
ExceptionRangeTarget(envPtr, range, catchOffset);
OP( PUSH_RETURN_CODE);
OP( PUSH_RESULT);
@@ -2300,160 +3117,176 @@ IssueTryFinallyInstructions(
OP( POP);
STORE( resultVar);
OP( POP);
- envPtr->currStackDepth = savedStackDepth + 1;
/*
* Now we handle all the registered 'on' and 'trap' handlers in order.
+ *
+ * Slight overallocation, but reduces size of this function.
*/
- if (numHandlers) {
- /*
- * Slight overallocation, but reduces size of this function.
- */
-
- addrsToFix = TclStackAlloc(interp, sizeof(int)*numHandlers);
- forwardsToFix = TclStackAlloc(interp, sizeof(int)*numHandlers);
-
- for (i=0 ; i<numHandlers ; i++) {
- sprintf(buf, "%d", matchCodes[i]);
- OP( DUP);
- PUSH( buf);
- OP( EQ);
- JUMP(notCodeJumpSource, JUMP_FALSE4);
- if (matchClauses[i]) {
- Tcl_ListObjLength(NULL, matchClauses[i], &len);
+ addrsToFix = TclStackAlloc(interp, sizeof(int)*numHandlers);
+ forwardsToFix = TclStackAlloc(interp, sizeof(int)*numHandlers);
- /*
- * Match the errorcode according to try/trap rules.
- */
+ for (i=0 ; i<numHandlers ; i++) {
+ int noTrapError, trapError;
+ const char *p;
- LOAD( optionsVar);
- PUSH( "-errorcode");
- OP4( DICT_GET, 1);
- OP44( LIST_RANGE_IMM, 0, len-1);
- PUSH( TclGetString(matchClauses[i]));
- OP( STR_EQ);
- JUMP(notECJumpSource, JUMP_FALSE4);
- } else {
- notECJumpSource = -1; /* LINT */
- }
+ sprintf(buf, "%d", matchCodes[i]);
+ OP( DUP);
+ PushLiteral(envPtr, buf, strlen(buf));
+ OP( EQ);
+ JUMP4( JUMP_FALSE, notCodeJumpSource);
+ if (matchClauses[i]) {
+ Tcl_ListObjLength(NULL, matchClauses[i], &len);
/*
- * There is a finally clause, so we need a fairly complex sequence
- * of instructions to deal with an on/trap handler because we must
- * call the finally handler *and* we need to substitute the result
- * from a failed trap for the result from the main script.
+ * Match the errorcode according to try/trap rules.
*/
- if (resultVars[i] >= 0 || handlerTokens[i]) {
- range = DeclareExceptionRange(envPtr, CATCH_EXCEPTION_RANGE);
- OP4( BEGIN_CATCH4, range);
- ExceptionRangeStarts(envPtr, range);
- }
- if (resultVars[i] >= 0) {
- LOAD( resultVar);
- STORE( resultVars[i]);
- OP( POP);
- if (optionVars[i] >= 0) {
- LOAD( optionsVar);
- STORE( optionVars[i]);
- OP( POP);
- }
+ LOAD( optionsVar);
+ PUSH( "-errorcode");
+ OP4( DICT_GET, 1);
+ TclAdjustStackDepth(-1, envPtr);
+ OP44( LIST_RANGE_IMM, 0, len-1);
+ p = Tcl_GetStringFromObj(matchClauses[i], &len);
+ PushLiteral(envPtr, p, len);
+ OP( STR_EQ);
+ JUMP4( JUMP_FALSE, notECJumpSource);
+ } else {
+ notECJumpSource = -1; /* LINT */
+ }
+ OP( POP);
- if (!handlerTokens[i]) {
- /*
- * No handler. Will not be the last handler (that is a
- * condition that is checked by the caller). Chain to the
- * next one.
- */
+ /*
+ * There is a finally clause, so we need a fairly complex sequence of
+ * instructions to deal with an on/trap handler because we must call
+ * the finally handler *and* we need to substitute the result from a
+ * failed trap for the result from the main script.
+ */
- ExceptionRangeEnds(envPtr, range);
- OP( END_CATCH);
- forwardsNeedFixing = 1;
- JUMP(forwardsToFix[i], JUMP4);
- goto finishTrapCatchHandling;
- }
- } else if (!handlerTokens[i]) {
+ if (resultVars[i] >= 0 || handlerTokens[i]) {
+ range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+ OP4( BEGIN_CATCH4, range);
+ ExceptionRangeStarts(envPtr, range);
+ }
+ if (resultVars[i] >= 0) {
+ LOAD( resultVar);
+ STORE( resultVars[i]);
+ OP( POP);
+ if (optionVars[i] >= 0) {
+ LOAD( optionsVar);
+ STORE( optionVars[i]);
+ OP( POP);
+ }
+
+ if (!handlerTokens[i]) {
/*
- * No handler. Will not be the last handler (that condition is
- * checked by the caller). Chain to the next one.
+ * No handler. Will not be the last handler (that is a
+ * condition that is checked by the caller). Chain to the next
+ * one.
*/
+ ExceptionRangeEnds(envPtr, range);
+ OP( END_CATCH);
forwardsNeedFixing = 1;
- JUMP(forwardsToFix[i], JUMP4);
- goto endOfThisArm;
+ JUMP4( JUMP, forwardsToFix[i]);
+ goto finishTrapCatchHandling;
}
-
+ } else if (!handlerTokens[i]) {
/*
- * Got a handler. Make sure that any pending patch-up actions from
- * previous unprocessed handlers are dealt with now that we know
- * where they are to jump to.
+ * No handler. Will not be the last handler (that condition is
+ * checked by the caller). Chain to the next one.
*/
- if (forwardsNeedFixing) {
- forwardsNeedFixing = 0;
- OP1( JUMP1, 7);
- for (j=0 ; j<i ; j++) {
- if (forwardsToFix[j] == -1) {
- continue;
- }
- FIXJUMP(forwardsToFix[j]);
- forwardsToFix[j] = -1;
- }
- OP4( BEGIN_CATCH4, range);
- }
- BODY( handlerTokens[i], 5+i*4);
- ExceptionRangeEnds(envPtr, range);
- OP( PUSH_RETURN_OPTIONS);
- OP4( REVERSE, 2);
- OP1( JUMP1, 4);
- forwardsToFix[i] = -1;
-
- /*
- * Error in handler or setting of variables; replace the stored
- * exception with the new one. Note that we only push this if we
- * have either a body or some variable setting here. Otherwise
- * this code is unreachable.
- */
+ forwardsNeedFixing = 1;
+ JUMP4( JUMP, forwardsToFix[i]);
+ goto endOfThisArm;
+ }
- finishTrapCatchHandling:
- ExceptionRangeTarget(envPtr, range, catchOffset);
- OP( PUSH_RETURN_OPTIONS);
- OP( PUSH_RESULT);
- OP( END_CATCH);
- STORE( resultVar);
- OP( POP);
- STORE( optionsVar);
- OP( POP);
+ /*
+ * Got a handler. Make sure that any pending patch-up actions from
+ * previous unprocessed handlers are dealt with now that we know where
+ * they are to jump to.
+ */
- endOfThisArm:
- if (i+1 < numHandlers) {
- JUMP(addrsToFix[i], JUMP4);
- }
- if (matchClauses[i]) {
- FIXJUMP(notECJumpSource);
+ if (forwardsNeedFixing) {
+ forwardsNeedFixing = 0;
+ OP1( JUMP1, 7);
+ for (j=0 ; j<i ; j++) {
+ if (forwardsToFix[j] == -1) {
+ continue;
+ }
+ FIXJUMP4( forwardsToFix[j]);
+ forwardsToFix[j] = -1;
}
- FIXJUMP(notCodeJumpSource);
+ OP4( BEGIN_CATCH4, range);
}
+ BODY( handlerTokens[i], 5+i*4);
+ ExceptionRangeEnds(envPtr, range);
+ PUSH( "0");
+ OP( PUSH_RETURN_OPTIONS);
+ OP4( REVERSE, 3);
+ OP1( JUMP1, 5);
+ TclAdjustStackDepth(-3, envPtr);
+ forwardsToFix[i] = -1;
/*
- * Fix all the jumps from taken clauses to here (the start of the
- * finally clause).
+ * Error in handler or setting of variables; replace the stored
+ * exception with the new one. Note that we only push this if we have
+ * either a body or some variable setting here. Otherwise this code is
+ * unreachable.
*/
- for (i=0 ; i<numHandlers-1 ; i++) {
- FIXJUMP(addrsToFix[i]);
+ finishTrapCatchHandling:
+ ExceptionRangeTarget(envPtr, range, catchOffset);
+ OP( PUSH_RETURN_OPTIONS);
+ OP( PUSH_RETURN_CODE);
+ OP( PUSH_RESULT);
+ OP( END_CATCH);
+ STORE( resultVar);
+ OP( POP);
+ PUSH( "1");
+ OP( EQ);
+ JUMP1( JUMP_FALSE, noTrapError);
+ LOAD( optionsVar);
+ PUSH( "-during");
+ OP4( REVERSE, 3);
+ STORE( optionsVar);
+ OP( POP);
+ OP44( DICT_SET, 1, optionsVar);
+ TclAdjustStackDepth(-1, envPtr);
+ JUMP1( JUMP, trapError);
+ FIXJUMP1( noTrapError);
+ STORE( optionsVar);
+ FIXJUMP1( trapError);
+ /* Skip POP at end; can clean up with subsequent POP */
+ if (i+1 < numHandlers) {
+ OP( POP);
+ }
+
+ endOfThisArm:
+ if (i+1 < numHandlers) {
+ JUMP4( JUMP, addrsToFix[i]);
+ TclAdjustStackDepth(1, envPtr);
}
- TclStackFree(interp, forwardsToFix);
- TclStackFree(interp, addrsToFix);
+ if (matchClauses[i]) {
+ FIXJUMP4( notECJumpSource);
+ }
+ FIXJUMP4( notCodeJumpSource);
}
/*
- * Drop the result code.
+ * Drop the result code, and fix all the jumps from taken clauses - which
+ * drop the result code as their first action - to point straight after
+ * (i.e., to the start of the finally clause).
*/
OP( POP);
- envPtr->currStackDepth = savedStackDepth;
+ for (i=0 ; i<numHandlers-1 ; i++) {
+ FIXJUMP4( addrsToFix[i]);
+ }
+ TclStackFree(interp, forwardsToFix);
+ TclStackFree(interp, addrsToFix);
/*
* Process the finally clause (at last!) Note that we do not wrap this in
@@ -2463,14 +3296,106 @@ IssueTryFinallyInstructions(
* next command (or some inter-command manipulation).
*/
+ if (!trapZero) {
+ FIXJUMP4( afterBody);
+ }
+ range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+ OP4( BEGIN_CATCH4, range);
+ ExceptionRangeStarts(envPtr, range);
BODY( finallyToken, 3 + 4*numHandlers);
+ ExceptionRangeEnds(envPtr, range);
+ OP( END_CATCH);
+ OP( POP);
+ JUMP1( JUMP, finalOK);
+ ExceptionRangeTarget(envPtr, range, catchOffset);
+ OP( PUSH_RESULT);
+ OP( PUSH_RETURN_OPTIONS);
+ OP( PUSH_RETURN_CODE);
+ OP( END_CATCH);
+ PUSH( "1");
+ OP( EQ);
+ JUMP1( JUMP_FALSE, noFinalError);
+ LOAD( optionsVar);
+ PUSH( "-during");
+ OP4( REVERSE, 3);
+ STORE( optionsVar);
+ OP( POP);
+ OP44( DICT_SET, 1, optionsVar);
+ TclAdjustStackDepth(-1, envPtr);
+ OP( POP);
+ JUMP1( JUMP, finalError);
+ TclAdjustStackDepth(1, envPtr);
+ FIXJUMP1( noFinalError);
+ STORE( optionsVar);
+ OP( POP);
+ FIXJUMP1( finalError);
+ STORE( resultVar);
OP( POP);
+ FIXJUMP1( finalOK);
LOAD( optionsVar);
LOAD( resultVar);
- OP( RETURN_STK);
+ INVOKE( RETURN_STK);
return TCL_OK;
}
+
+static int
+IssueTryFinallyInstructions(
+ Tcl_Interp *interp,
+ CompileEnv *envPtr,
+ Tcl_Token *bodyToken,
+ Tcl_Token *finallyToken)
+{
+ DefineLineInformation; /* TIP #280 */
+ int range, jumpOK, jumpSplice;
+
+ /*
+ * Note that this one is simple enough that we can issue it without
+ * needing a local variable table, making it a universal compilation.
+ */
+
+ range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+ OP4( BEGIN_CATCH4, range);
+ ExceptionRangeStarts(envPtr, range);
+ BODY( bodyToken, 1);
+ ExceptionRangeEnds(envPtr, range);
+ OP1( JUMP1, 3);
+ TclAdjustStackDepth(-1, envPtr);
+ ExceptionRangeTarget(envPtr, range, catchOffset);
+ OP( PUSH_RESULT);
+ OP( PUSH_RETURN_OPTIONS);
+ OP( END_CATCH);
+
+ range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+ OP4( BEGIN_CATCH4, range);
+ ExceptionRangeStarts(envPtr, range);
+ BODY( finallyToken, 3);
+ ExceptionRangeEnds(envPtr, range);
+ OP( END_CATCH);
+ OP( POP);
+ JUMP1( JUMP, jumpOK);
+ ExceptionRangeTarget(envPtr, range, catchOffset);
+ OP( PUSH_RESULT);
+ OP( PUSH_RETURN_OPTIONS);
+ OP( PUSH_RETURN_CODE);
+ OP( END_CATCH);
+ PUSH( "1");
+ OP( EQ);
+ JUMP1( JUMP_FALSE, jumpSplice);
+ PUSH( "-during");
+ OP4( OVER, 3);
+ OP4( LIST, 2);
+ OP( LIST_CONCAT);
+ FIXJUMP1( jumpSplice);
+ OP4( REVERSE, 4);
+ OP( POP);
+ OP( POP);
+ OP1( JUMP1, 7);
+ FIXJUMP1( jumpOK);
+ OP4( REVERSE, 2);
+ INVOKE( RETURN_STK);
+ return TCL_OK;
+}
/*
*----------------------------------------------------------------------
@@ -2500,38 +3425,81 @@ TclCompileUnsetCmd(
CompileEnv *envPtr) /* Holds resulting instructions. */
{
Tcl_Token *varTokenPtr;
- int isScalar, simpleVarName, localIndex, numWords, flags, i;
- Tcl_Obj *leadingWord;
+ int isScalar, localIndex, flags = 1, i, varCount = 0, haveFlags = 0;
DefineLineInformation; /* TIP #280 */
- numWords = parsePtr->numWords-1;
- flags = 1;
- varTokenPtr = TokenAfter(parsePtr->tokenPtr);
- leadingWord = Tcl_NewObj();
- if (TclWordKnownAtCompileTime(varTokenPtr, leadingWord)) {
- int len;
- const char *bytes = Tcl_GetStringFromObj(leadingWord, &len);
-
- if (len == 11 && !strncmp("-nocomplain", bytes, 11)) {
- flags = 0;
- varTokenPtr = TokenAfter(varTokenPtr);
- numWords--;
- } else if (len == 2 && !strncmp("--", bytes, 2)) {
- varTokenPtr = TokenAfter(varTokenPtr);
- numWords--;
- }
- } else {
- /*
- * Cannot guarantee that the first word is not '-nocomplain' at
- * evaluation with reasonable effort, so spill to interpreted version.
- */
+ /* TODO: Consider support for compiling expanded args. */
+
+ /*
+ * Verify that all words - except the first non-option one - are known at
+ * compile time so that we can handle them without needing to do a nasty
+ * push/rotate. [Bug 3970f54c4e]
+ */
+
+ for (i=1,varTokenPtr=parsePtr->tokenPtr ; i<parsePtr->numWords ; i++) {
+ Tcl_Obj *leadingWord = Tcl_NewObj();
+
+ varTokenPtr = TokenAfter(varTokenPtr);
+ if (!TclWordKnownAtCompileTime(varTokenPtr, leadingWord)) {
+ TclDecrRefCount(leadingWord);
+ /*
+ * We can tolerate non-trivial substitutions in the first variable
+ * to be unset. If a '--' or '-nocomplain' was present, anything
+ * goes in that one place! (All subsequent variable names must be
+ * constants since we don't want to have to push them all first.)
+ */
+
+ if (varCount == 0) {
+ if (haveFlags) {
+ continue;
+ }
+
+ /*
+ * In fact, we're OK as long as we're the first argument *and*
+ * we provably don't start with a '-'. If that is true, then
+ * even if everything else is varying, we still can't be a
+ * flag. Otherwise we'll spill to runtime to place a limit on
+ * the trickiness.
+ */
+
+ if (varTokenPtr->type == TCL_TOKEN_WORD
+ && varTokenPtr[1].type == TCL_TOKEN_TEXT
+ && varTokenPtr[1].size > 0
+ && varTokenPtr[1].start[0] != '-') {
+ continue;
+ }
+ }
+ return TCL_ERROR;
+ }
+ if (i == 1) {
+ const char *bytes;
+ int len;
+
+ bytes = Tcl_GetStringFromObj(leadingWord, &len);
+ if (len == 11 && !strncmp("-nocomplain", bytes, 11)) {
+ flags = 0;
+ haveFlags = 1;
+ } else if (len == 2 && !strncmp("--", bytes, 2)) {
+ haveFlags = 1;
+ } else {
+ varCount++;
+ }
+ } else {
+ varCount++;
+ }
TclDecrRefCount(leadingWord);
- return TCL_ERROR;
}
- TclDecrRefCount(leadingWord);
- for (i=0 ; i<numWords ; i++) {
+ /*
+ * Issue instructions to unset each of the named variables.
+ */
+
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ if (haveFlags) {
+ varTokenPtr = TokenAfter(varTokenPtr);
+ }
+ for (i=1+haveFlags ; i<parsePtr->numWords ; i++) {
/*
* Decide if we can use a frame slot for the var/array name or if we
* need to emit code to compute and push the name at runtime. We use a
@@ -2541,33 +3509,29 @@ TclCompileUnsetCmd(
*/
PushVarNameWord(interp, varTokenPtr, envPtr, 0,
- &localIndex, &simpleVarName, &isScalar, 1);
+ &localIndex, &isScalar, i);
/*
* Emit instructions to unset the variable.
*/
- if (!simpleVarName) {
- TclEmitInstInt1( INST_UNSET_STK, flags, envPtr);
- } else if (isScalar) {
+ if (isScalar) {
if (localIndex < 0) {
- TclEmitInstInt1(INST_UNSET_STK, flags, envPtr);
+ OP1( UNSET_STK, flags);
} else {
- TclEmitInstInt1(INST_UNSET_SCALAR, flags, envPtr);
- TclEmitInt4( localIndex, envPtr);
+ OP14( UNSET_SCALAR, flags, localIndex);
}
} else {
if (localIndex < 0) {
- TclEmitInstInt1(INST_UNSET_ARRAY_STK, flags, envPtr);
+ OP1( UNSET_ARRAY_STK, flags);
} else {
- TclEmitInstInt1(INST_UNSET_ARRAY, flags, envPtr);
- TclEmitInt4( localIndex, envPtr);
+ OP14( UNSET_ARRAY, flags, localIndex);
}
}
varTokenPtr = TokenAfter(varTokenPtr);
}
- PushLiteral(envPtr, "", 0);
+ PUSH("");
return TCL_OK;
}
@@ -2601,7 +3565,6 @@ TclCompileWhileCmd(
Tcl_Token *testTokenPtr, *bodyTokenPtr;
JumpFixup jumpEvalCondFixup;
int testCodeOffset, bodyCodeOffset, jumpDist, range, code, boolVal;
- int savedStackDepth = envPtr->currStackDepth;
int loopMayEnd = 1; /* This is set to 0 if it is recognized as an
* infinite loop. */
Tcl_Obj *boolObj;
@@ -2659,7 +3622,7 @@ TclCompileWhileCmd(
* implement break and continue.
*/
- range = DeclareExceptionRange(envPtr, LOOP_EXCEPTION_RANGE);
+ range = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
/*
* Jump to the evaluation of the condition. This code uses the "loop
@@ -2685,7 +3648,7 @@ TclCompileWhileCmd(
* INST_START_CMD, and hence counted properly. [Bug 1752146]
*/
- envPtr->atCmdStart = 0;
+ envPtr->atCmdStart &= ~1;
testCodeOffset = CurrentOffset(envPtr);
}
@@ -2693,12 +3656,14 @@ TclCompileWhileCmd(
* Compile the loop body.
*/
- SetLineInformation(2);
bodyCodeOffset = ExceptionRangeStarts(envPtr, range);
- CompileBody(envPtr, bodyTokenPtr, interp);
+ if (!loopMayEnd) {
+ envPtr->exceptArrayPtr[range].continueOffset = testCodeOffset;
+ envPtr->exceptArrayPtr[range].codeOffset = bodyCodeOffset;
+ }
+ BODY(bodyTokenPtr, 2);
ExceptionRangeEnds(envPtr, range);
- envPtr->currStackDepth = savedStackDepth + 1;
- TclEmitOpcode(INST_POP, envPtr);
+ OP( POP);
/*
* Compile the test expression then emit the conditional jump that
@@ -2712,10 +3677,9 @@ TclCompileWhileCmd(
bodyCodeOffset += 3;
testCodeOffset += 3;
}
- envPtr->currStackDepth = savedStackDepth;
SetLineInformation(1);
TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
- envPtr->currStackDepth = savedStackDepth + 1;
+ TclClearNumConversion(envPtr);
jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
if (jumpDist > 127) {
@@ -2739,254 +3703,102 @@ TclCompileWhileCmd(
envPtr->exceptArrayPtr[range].continueOffset = testCodeOffset;
envPtr->exceptArrayPtr[range].codeOffset = bodyCodeOffset;
ExceptionRangeTarget(envPtr, range, breakOffset);
+ TclFinalizeLoopExceptionRange(envPtr, range);
/*
* The while command's result is an empty string.
*/
pushResult:
- envPtr->currStackDepth = savedStackDepth;
- PushLiteral(envPtr, "", 0);
+ PUSH("");
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * PushVarName --
+ * TclCompileYieldCmd --
*
- * Procedure used in the compiling where pushing a variable name is
- * necessary (append, lappend, set).
+ * Procedure called to compile the "yield" command.
*
* Results:
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
* evaluation to runtime.
*
* Side effects:
- * Instructions are added to envPtr to execute the "set" command at
+ * Instructions are added to envPtr to execute the "yield" command at
* runtime.
*
*----------------------------------------------------------------------
*/
-static int
-PushVarName(
+int
+TclCompileYieldCmd(
Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Token *varTokenPtr, /* Points to a variable token. */
- CompileEnv *envPtr, /* Holds resulting instructions. */
- int flags, /* TCL_NO_LARGE_INDEX. */
- int *localIndexPtr, /* Must not be NULL. */
- int *simpleVarNamePtr, /* Must not be NULL. */
- int *isScalarPtr, /* Must not be NULL. */
- int line, /* Line the token starts on. */
- int *clNext) /* Reference to offset of next hidden cont.
- * line. */
-{
- register const char *p;
- const char *name, *elName;
- register int i, n;
- Tcl_Token *elemTokenPtr = NULL;
- int nameChars, elNameChars, simpleVarName, localIndex;
- int elemTokenCount = 0, allocedTokens = 0, removedParen = 0;
-
- /*
- * Decide if we can use a frame slot for the var/array name or if we need
- * to emit code to compute and push the name at runtime. We use a frame
- * slot (entry in the array of local vars) if we are compiling a procedure
- * body and if the name is simple text that does not include namespace
- * qualifiers.
- */
-
- simpleVarName = 0;
- name = elName = NULL;
- nameChars = elNameChars = 0;
- localIndex = -1;
-
- /*
- * Check not only that the type is TCL_TOKEN_SIMPLE_WORD, but whether
- * curly braces surround the variable name. This really matters for array
- * elements to handle things like
- * set {x($foo)} 5
- * which raises an undefined var error if we are not careful here.
- */
-
- if ((varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) &&
- (varTokenPtr->start[0] != '{')) {
- /*
- * A simple variable name. Divide it up into "name" and "elName"
- * strings. If it is not a local variable, look it up at runtime.
- */
-
- simpleVarName = 1;
-
- name = varTokenPtr[1].start;
- nameChars = varTokenPtr[1].size;
- if (name[nameChars-1] == ')') {
- /*
- * last char is ')' => potential array reference.
- */
-
- for (i=0,p=name ; i<nameChars ; i++,p++) {
- if (*p == '(') {
- elName = p + 1;
- elNameChars = nameChars - i - 2;
- nameChars = i;
- break;
- }
- }
-
- if ((elName != NULL) && elNameChars) {
- /*
- * An array element, the element name is a simple string:
- * assemble the corresponding token.
- */
-
- elemTokenPtr = TclStackAlloc(interp, sizeof(Tcl_Token));
- allocedTokens = 1;
- elemTokenPtr->type = TCL_TOKEN_TEXT;
- elemTokenPtr->start = elName;
- elemTokenPtr->size = elNameChars;
- elemTokenPtr->numComponents = 0;
- elemTokenCount = 1;
- }
- }
- } else if (((n = varTokenPtr->numComponents) > 1)
- && (varTokenPtr[1].type == TCL_TOKEN_TEXT)
- && (varTokenPtr[n].type == TCL_TOKEN_TEXT)
- && (varTokenPtr[n].start[varTokenPtr[n].size - 1] == ')')) {
- /*
- * Check for parentheses inside first token.
- */
-
- simpleVarName = 0;
- for (i = 0, p = varTokenPtr[1].start;
- i < varTokenPtr[1].size; i++, p++) {
- if (*p == '(') {
- simpleVarName = 1;
- break;
- }
- }
- if (simpleVarName) {
- int remainingChars;
-
- /*
- * Check the last token: if it is just ')', do not count it.
- * Otherwise, remove the ')' and flag so that it is restored at
- * the end.
- */
-
- if (varTokenPtr[n].size == 1) {
- n--;
- } else {
- varTokenPtr[n].size--;
- removedParen = n;
- }
-
- name = varTokenPtr[1].start;
- nameChars = p - varTokenPtr[1].start;
- elName = p + 1;
- remainingChars = (varTokenPtr[2].start - p) - 1;
- elNameChars = (varTokenPtr[n].start-p) + varTokenPtr[n].size - 2;
-
- if (remainingChars) {
- /*
- * Make a first token with the extra characters in the first
- * token.
- */
-
- elemTokenPtr = TclStackAlloc(interp, n * sizeof(Tcl_Token));
- allocedTokens = 1;
- elemTokenPtr->type = TCL_TOKEN_TEXT;
- elemTokenPtr->start = elName;
- elemTokenPtr->size = remainingChars;
- elemTokenPtr->numComponents = 0;
- elemTokenCount = n;
-
- /*
- * Copy the remaining tokens.
- */
-
- memcpy(elemTokenPtr+1, varTokenPtr+2,
- (n-1) * sizeof(Tcl_Token));
- } else {
- /*
- * Use the already available tokens.
- */
-
- elemTokenPtr = &varTokenPtr[2];
- elemTokenCount = n - 1;
- }
- }
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ if (parsePtr->numWords < 1 || parsePtr->numWords > 2) {
+ return TCL_ERROR;
}
- if (simpleVarName) {
- /*
- * See whether name has any namespace separators (::'s).
- */
-
- int hasNsQualifiers = 0;
-
- for (i = 0, p = name; i < nameChars; i++, p++) {
- if ((*p == ':') && ((i+1) < nameChars) && (*(p+1) == ':')) {
- hasNsQualifiers = 1;
- break;
- }
- }
-
- /*
- * Look up the var name's index in the array of local vars in the proc
- * frame. If retrieving the var's value and it doesn't already exist,
- * push its name and look it up at runtime.
- */
-
- if (!hasNsQualifiers) {
- localIndex = TclFindCompiledLocal(name, nameChars,
- 1, envPtr);
- if ((flags & TCL_NO_LARGE_INDEX) && (localIndex > 255)) {
- /*
- * We'll push the name.
- */
-
- localIndex = -1;
- }
- }
- if (localIndex < 0) {
- PushLiteral(envPtr, name, nameChars);
- }
-
- /*
- * Compile the element script, if any.
- */
-
- if (elName != NULL) {
- if (elNameChars) {
- envPtr->line = line;
- envPtr->clNext = clNext;
- TclCompileTokens(interp, elemTokenPtr, elemTokenCount,
- envPtr);
- } else {
- PushLiteral(envPtr, "", 0);
- }
- }
+ if (parsePtr->numWords == 1) {
+ PUSH("");
} else {
- /*
- * The var name isn't simple: compile and push it.
- */
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
- envPtr->line = line;
- envPtr->clNext = clNext;
- CompileTokens(envPtr, varTokenPtr, interp);
+ CompileWord(envPtr, valueTokenPtr, interp, 1);
}
+ OP( YIELD);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileYieldToCmd --
+ *
+ * Procedure called to compile the "yieldto" command.
+ *
+ * Results:
+ * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ * evaluation to runtime.
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "yieldto" command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
- if (removedParen) {
- varTokenPtr[removedParen].size++;
+int
+TclCompileYieldToCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ int i;
+
+ if (parsePtr->numWords < 2) {
+ return TCL_ERROR;
}
- if (allocedTokens) {
- TclStackFree(interp, elemTokenPtr);
+
+ OP( NS_CURRENT);
+ for (i = 1 ; i < parsePtr->numWords ; i++) {
+ CompileWord(envPtr, tokenPtr, interp, i);
+ tokenPtr = TokenAfter(tokenPtr);
}
- *localIndexPtr = localIndex;
- *simpleVarNamePtr = simpleVarName;
- *isScalarPtr = (elName == NULL);
+ OP4( LIST, i);
+ OP( YIELD_TO_INVOKE);
return TCL_OK;
}
@@ -3061,6 +3873,7 @@ CompileAssociativeBinaryOpCmd(
DefineLineInformation; /* TIP #280 */
int words;
+ /* TODO: Consider support for compiling expanded args. */
for (words=1 ; words<parsePtr->numWords ; words++) {
tokenPtr = TokenAfter(tokenPtr);
CompileWord(envPtr, tokenPtr, interp, words);
@@ -3075,7 +3888,7 @@ CompileAssociativeBinaryOpCmd(
* calcuations, including roundoff errors.
*/
- TclEmitInstInt4(INST_REVERSE, words-1, envPtr);
+ OP4( REVERSE, words-1);
}
while (--words > 1) {
TclEmitOpcode(instruction, envPtr);
@@ -3144,8 +3957,9 @@ CompileComparisonOpCmd(
Tcl_Token *tokenPtr;
DefineLineInformation; /* TIP #280 */
+ /* TODO: Consider support for compiling expanded args. */
if (parsePtr->numWords < 3) {
- PushLiteral(envPtr, "1", 1);
+ PUSH("1");
} else if (parsePtr->numWords == 3) {
tokenPtr = TokenAfter(parsePtr->tokenPtr);
CompileWord(envPtr, tokenPtr, interp, 1);
@@ -3159,38 +3973,26 @@ CompileComparisonOpCmd(
return TCL_ERROR;
} else {
- int tmpIndex = TclFindCompiledLocal(NULL, 0, 1, envPtr);
+ int tmpIndex = AnonymousLocal(envPtr);
int words;
tokenPtr = TokenAfter(parsePtr->tokenPtr);
CompileWord(envPtr, tokenPtr, interp, 1);
tokenPtr = TokenAfter(tokenPtr);
CompileWord(envPtr, tokenPtr, interp, 2);
- if (tmpIndex <= 255) {
- TclEmitInstInt1(INST_STORE_SCALAR1, tmpIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_STORE_SCALAR4, tmpIndex, envPtr);
- }
+ STORE(tmpIndex);
TclEmitOpcode(instruction, envPtr);
for (words=3 ; words<parsePtr->numWords ;) {
- if (tmpIndex <= 255) {
- TclEmitInstInt1(INST_LOAD_SCALAR1, tmpIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_LOAD_SCALAR4, tmpIndex, envPtr);
- }
+ LOAD(tmpIndex);
tokenPtr = TokenAfter(tokenPtr);
CompileWord(envPtr, tokenPtr, interp, words);
if (++words < parsePtr->numWords) {
- if (tmpIndex <= 255) {
- TclEmitInstInt1(INST_STORE_SCALAR1, tmpIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_STORE_SCALAR4, tmpIndex, envPtr);
- }
+ STORE(tmpIndex);
}
TclEmitOpcode(instruction, envPtr);
}
for (; words>3 ; words--) {
- TclEmitOpcode(INST_BITAND, envPtr);
+ OP( BITAND);
}
/*
@@ -3198,13 +4000,7 @@ CompileComparisonOpCmd(
* might be expensive elsewhere.
*/
- PushLiteral(envPtr, "", 0);
- if (tmpIndex <= 255) {
- TclEmitInstInt1(INST_STORE_SCALAR1, tmpIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_STORE_SCALAR4, tmpIndex, envPtr);
- }
- TclEmitOpcode(INST_POP, envPtr);
+ OP14( UNSET_SCALAR, 0, tmpIndex);
}
return TCL_OK;
}
@@ -3334,7 +4130,7 @@ TclCompilePowOpCmd(
CompileWord(envPtr, tokenPtr, interp, words);
}
if (parsePtr->numWords <= 2) {
- PushLiteral(envPtr, "1", 1);
+ PUSH("1");
words++;
}
while (--words > 1) {
@@ -3499,6 +4295,7 @@ TclCompileMinusOpCmd(
DefineLineInformation; /* TIP #280 */
int words;
+ /* TODO: Consider support for compiling expanded args. */
if (parsePtr->numWords == 1) {
/*
* Fallback to direct eval to report syntax error.
@@ -3544,6 +4341,7 @@ TclCompileDivOpCmd(
DefineLineInformation; /* TIP #280 */
int words;
+ /* TODO: Consider support for compiling expanded args. */
if (parsePtr->numWords == 1) {
/*
* Fallback to direct eval to report syntax error.
@@ -3552,7 +4350,7 @@ TclCompileDivOpCmd(
return TCL_ERROR;
}
if (parsePtr->numWords == 2) {
- PushLiteral(envPtr, "1.0", 3);
+ PUSH("1.0");
}
for (words=1 ; words<parsePtr->numWords ; words++) {
tokenPtr = TokenAfter(tokenPtr);
diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c
index d1d7403..94c1bd6 100644
--- a/generic/tclCompExpr.c
+++ b/generic/tclCompExpr.c
@@ -167,135 +167,135 @@ enum Marks {
/* Leaf lexemes */
-#define NUMBER ( LEAF | 1) /* For literal numbers */
-#define SCRIPT ( LEAF | 2) /* Script substitution; [foo] */
-#define BOOLEAN ( LEAF | BAREWORD) /* For literal booleans */
-#define BRACED ( LEAF | 4) /* Braced string; {foo bar} */
-#define VARIABLE ( LEAF | 5) /* Variable substitution; $x */
-#define QUOTED ( LEAF | 6) /* Quoted string; "foo $bar [soom]" */
-#define EMPTY ( LEAF | 7) /* Used only for an empty argument
- * list to a function. Represents the
- * empty string within parens in the
- * expression: rand() */
+#define NUMBER (LEAF | 1)
+ /* For literal numbers */
+#define SCRIPT (LEAF | 2)
+ /* Script substitution; [foo] */
+#define BOOLEAN (LEAF | BAREWORD)
+ /* For literal booleans */
+#define BRACED (LEAF | 4)
+ /* Braced string; {foo bar} */
+#define VARIABLE (LEAF | 5)
+ /* Variable substitution; $x */
+#define QUOTED (LEAF | 6)
+ /* Quoted string; "foo $bar [soom]" */
+#define EMPTY (LEAF | 7)
+ /* Used only for an empty argument list to a
+ * function. Represents the empty string
+ * within parens in the expression: rand() */
/* Unary operator lexemes */
-#define UNARY_PLUS ( UNARY | PLUS)
-#define UNARY_MINUS ( UNARY | MINUS)
-#define FUNCTION ( UNARY | BAREWORD) /* This is a bit of "creative
- * interpretation" on the part of the
- * parser. A function call is parsed
- * into the parse tree according to
- * the perspective that the function
- * name is a unary operator and its
- * argument list, enclosed in parens,
- * is its operand. The additional
- * requirements not implied generally
- * by treatment as a unary operator --
- * for example, the requirement that
- * the operand be enclosed in parens
- * -- are hard coded in the relevant
- * portions of ParseExpr(). We trade
- * off the need to include such
- * exceptional handling in the code
- * against the need we would otherwise
- * have for more lexeme categories. */
-#define START ( UNARY | 4) /* This lexeme isn't parsed from the
- * expression text at all. It
- * represents the start of the
- * expression and sits at the root of
- * the parse tree where it serves as
- * the start/end point of
- * traversals. */
-#define OPEN_PAREN ( UNARY | 5) /* Another bit of creative
- * interpretation, where we treat "("
- * as a unary operator with the
- * sub-expression between it and its
- * matching ")" as its operand. See
- * CLOSE_PAREN below. */
-#define NOT ( UNARY | 6)
-#define BIT_NOT ( UNARY | 7)
+#define UNARY_PLUS (UNARY | PLUS)
+#define UNARY_MINUS (UNARY | MINUS)
+#define FUNCTION (UNARY | BAREWORD)
+ /* This is a bit of "creative interpretation"
+ * on the part of the parser. A function call
+ * is parsed into the parse tree according to
+ * the perspective that the function name is a
+ * unary operator and its argument list,
+ * enclosed in parens, is its operand. The
+ * additional requirements not implied
+ * generally by treatment as a unary operator
+ * -- for example, the requirement that the
+ * operand be enclosed in parens -- are hard
+ * coded in the relevant portions of
+ * ParseExpr(). We trade off the need to
+ * include such exceptional handling in the
+ * code against the need we would otherwise
+ * have for more lexeme categories. */
+#define START (UNARY | 4)
+ /* This lexeme isn't parsed from the
+ * expression text at all. It represents the
+ * start of the expression and sits at the
+ * root of the parse tree where it serves as
+ * the start/end point of traversals. */
+#define OPEN_PAREN (UNARY | 5)
+ /* Another bit of creative interpretation,
+ * where we treat "(" as a unary operator with
+ * the sub-expression between it and its
+ * matching ")" as its operand. See
+ * CLOSE_PAREN below. */
+#define NOT (UNARY | 6)
+#define BIT_NOT (UNARY | 7)
/* Binary operator lexemes */
-#define BINARY_PLUS ( BINARY | PLUS)
-#define BINARY_MINUS ( BINARY | MINUS)
-#define COMMA ( BINARY | 3) /* The "," operator is a low
- * precedence binary operator that
- * separates the arguments in a
- * function call. The additional
- * constraint that this operator can
- * only legally appear at the right
- * places within a function call
- * argument list are hard coded within
- * ParseExpr(). */
-#define MULT ( BINARY | 4)
-#define DIVIDE ( BINARY | 5)
-#define MOD ( BINARY | 6)
-#define LESS ( BINARY | 7)
-#define GREATER ( BINARY | 8)
-#define BIT_AND ( BINARY | 9)
-#define BIT_XOR ( BINARY | 10)
-#define BIT_OR ( BINARY | 11)
-#define QUESTION ( BINARY | 12) /* These two lexemes make up the */
-#define COLON ( BINARY | 13) /* ternary conditional operator,
- * $x ? $y : $z . We treat them as two
- * binary operators to avoid another
- * lexeme category, and code the
- * additional constraints directly in
- * ParseExpr(). For instance, the
- * right operand of a "?" operator
- * must be a ":" operator. */
-#define LEFT_SHIFT ( BINARY | 14)
-#define RIGHT_SHIFT ( BINARY | 15)
-#define LEQ ( BINARY | 16)
-#define GEQ ( BINARY | 17)
-#define EQUAL ( BINARY | 18)
-#define NEQ ( BINARY | 19)
-#define AND ( BINARY | 20)
-#define OR ( BINARY | 21)
-#define STREQ ( BINARY | 22)
-#define STRNEQ ( BINARY | 23)
-#define EXPON ( BINARY | 24) /* Unlike the other binary operators,
- * EXPON is right associative and this
- * distinction is coded directly in
- * ParseExpr(). */
-#define IN_LIST ( BINARY | 25)
-#define NOT_IN_LIST ( BINARY | 26)
-#define CLOSE_PAREN ( BINARY | 27) /* By categorizing the CLOSE_PAREN
- * lexeme as a BINARY operator, the
- * normal parsing rules for binary
- * operators assure that a close paren
- * will not directly follow another
- * operator, and the machinery already
- * in place to connect operands to
- * operators according to precedence
- * performs most of the work of
- * matching open and close parens for
- * us. In the end though, a close
- * paren is not really a binary
- * operator, and some special coding
- * in ParseExpr() make sure we never
- * put an actual CLOSE_PAREN node in
- * the parse tree. The sub-expression
- * between parens becomes the single
- * argument of the matching OPEN_PAREN
- * unary operator. */
-#define END ( BINARY | 28) /* This lexeme represents the end of
- * the string being parsed. Treating
- * it as a binary operator follows the
- * same logic as the CLOSE_PAREN
- * lexeme and END pairs with START, in
- * the same way that CLOSE_PAREN pairs
- * with OPEN_PAREN. */
+#define BINARY_PLUS (BINARY | PLUS)
+#define BINARY_MINUS (BINARY | MINUS)
+#define COMMA (BINARY | 3)
+ /* The "," operator is a low precedence binary
+ * operator that separates the arguments in a
+ * function call. The additional constraint
+ * that this operator can only legally appear
+ * at the right places within a function call
+ * argument list are hard coded within
+ * ParseExpr(). */
+#define MULT (BINARY | 4)
+#define DIVIDE (BINARY | 5)
+#define MOD (BINARY | 6)
+#define LESS (BINARY | 7)
+#define GREATER (BINARY | 8)
+#define BIT_AND (BINARY | 9)
+#define BIT_XOR (BINARY | 10)
+#define BIT_OR (BINARY | 11)
+#define QUESTION (BINARY | 12)
+ /* These two lexemes make up the */
+#define COLON (BINARY | 13)
+ /* ternary conditional operator, $x ? $y : $z.
+ * We treat them as two binary operators to
+ * avoid another lexeme category, and code the
+ * additional constraints directly in
+ * ParseExpr(). For instance, the right
+ * operand of a "?" operator must be a ":"
+ * operator. */
+#define LEFT_SHIFT (BINARY | 14)
+#define RIGHT_SHIFT (BINARY | 15)
+#define LEQ (BINARY | 16)
+#define GEQ (BINARY | 17)
+#define EQUAL (BINARY | 18)
+#define NEQ (BINARY | 19)
+#define AND (BINARY | 20)
+#define OR (BINARY | 21)
+#define STREQ (BINARY | 22)
+#define STRNEQ (BINARY | 23)
+#define EXPON (BINARY | 24)
+ /* Unlike the other binary operators, EXPON is
+ * right associative and this distinction is
+ * coded directly in ParseExpr(). */
+#define IN_LIST (BINARY | 25)
+#define NOT_IN_LIST (BINARY | 26)
+#define CLOSE_PAREN (BINARY | 27)
+ /* By categorizing the CLOSE_PAREN lexeme as a
+ * BINARY operator, the normal parsing rules
+ * for binary operators assure that a close
+ * paren will not directly follow another
+ * operator, and the machinery already in
+ * place to connect operands to operators
+ * according to precedence performs most of
+ * the work of matching open and close parens
+ * for us. In the end though, a close paren is
+ * not really a binary operator, and some
+ * special coding in ParseExpr() make sure we
+ * never put an actual CLOSE_PAREN node in the
+ * parse tree. The sub-expression between
+ * parens becomes the single argument of the
+ * matching OPEN_PAREN unary operator. */
+#define END (BINARY | 28)
+ /* This lexeme represents the end of the
+ * string being parsed. Treating it as a
+ * binary operator follows the same logic as
+ * the CLOSE_PAREN lexeme and END pairs with
+ * START, in the same way that CLOSE_PAREN
+ * pairs with OPEN_PAREN. */
+
/*
* When ParseExpr() builds the parse tree it must choose which operands to
* connect to which operators. This is done according to operator precedence.
- * The greater an operator's precedence the greater claim it has to link to
- * an available operand. The Precedence enumeration lists the precedence
- * values used by Tcl expression operators, from lowest to highest claim.
- * Each precedence level is commented with the operators that hold that
- * precedence.
+ * The greater an operator's precedence the greater claim it has to link to an
+ * available operand. The Precedence enumeration lists the precedence values
+ * used by Tcl expression operators, from lowest to highest claim. Each
+ * precedence level is commented with the operators that hold that precedence.
*/
enum Precedence {
@@ -320,9 +320,9 @@ enum Precedence {
};
/*
- * Here the same information contained in the comments above is stored
- * in inverted form, so that given a lexeme, one can quickly look up
- * its precedence value.
+ * Here the same information contained in the comments above is stored in
+ * inverted form, so that given a lexeme, one can quickly look up its
+ * precedence value.
*/
static const unsigned char prec[] = {
@@ -436,7 +436,7 @@ static const unsigned char instruction[] = {
* ParseLexeme().
*/
-static unsigned char Lexeme[] = {
+static const unsigned char Lexeme[] = {
INVALID /* NUL */, INVALID /* SOH */,
INVALID /* STX */, INVALID /* ETX */,
INVALID /* EOT */, INVALID /* ENQ */,
@@ -490,13 +490,6 @@ typedef struct JumpList {
JumpFixup jump; /* Pass this argument to matching calls of
* TclEmitForwardJump() and
* TclFixupForwardJump(). */
- int depth; /* Remember the currStackDepth of the
- * CompileEnv here. */
- int offset; /* Data used to compute jump lengths to pass
- * to TclFixupForwardJump() */
- int convert; /* Temporary storage used to compute whether
- * numeric conversion will be needed following
- * the operator we're compiling. */
struct JumpList *next; /* Point to next item on the stack */
} JumpList;
@@ -599,7 +592,10 @@ ParseExpr(
* actual leaf at the time the complete tree
* is needed. */
- /* These variables control generation of the error message. */
+ /*
+ * These variables control generation of the error message.
+ */
+
Tcl_Obj *msg = NULL; /* The error message. */
Tcl_Obj *post = NULL; /* In a few cases, an additional postscript
* for the error message, supplying more
@@ -659,11 +655,6 @@ ParseExpr(
Tcl_Obj *literal; /* Filled by the ParseLexeme() call when a
* literal is parsed that has a Tcl_Obj rep
* worth preserving. */
- const char *lastStart = start - scanned;
- /* Compute where the lexeme parsed the
- * previous pass through the loop began. This
- * is helpful for detecting invalid octals and
- * providing more complete error messages. */
/*
* Each pass through this loop adds up to one more OpNode. Allocate
@@ -754,33 +745,39 @@ ParseExpr(
Tcl_AppendPrintfToObj(post, " or \"%.*s%s(...)\" or ...",
(scanned < limit) ? scanned : limit - 3,
start, (scanned < limit) ? "" : "...");
- if (NotOperator(lastParsed)) {
- errCode = "BADNUMBER";
- if ((lastStart[0] == '0')
- && ((lastStart[1] == 'o')
- || (lastStart[1] == 'O'))
- && (lastStart[2] >= '0')
- && (lastStart[2] <= '9')) {
- const char *end = lastStart + 2;
- Tcl_Obj *copy;
-
- while (isdigit(UCHAR(*end))) {
- end++;
- }
- copy = Tcl_NewStringObj(lastStart, end-lastStart);
- if (TclCheckBadOctal(NULL, Tcl_GetString(copy))) {
+ errCode = "BAREWORD";
+ if (start[0] == '0') {
+ const char *stop;
+ TclParseNumber(NULL, NULL, NULL, start, scanned,
+ &stop, TCL_PARSE_NO_WHITESPACE);
+
+ if (isdigit(UCHAR(*stop)) || (stop == start + 1)) {
+ switch (start[1]) {
+ case 'b':
+ Tcl_AppendToObj(post,
+ " (invalid binary number?)", -1);
+ parsePtr->errorType = TCL_PARSE_BAD_NUMBER;
+ errCode = "BADNUMBER";
+ subErrCode = "BINARY";
+ break;
+ case 'o':
Tcl_AppendToObj(post,
" (invalid octal number?)", -1);
+ parsePtr->errorType = TCL_PARSE_BAD_NUMBER;
errCode = "BADNUMBER";
subErrCode = "OCTAL";
+ break;
+ default:
+ if (isdigit(UCHAR(start[1]))) {
+ Tcl_AppendToObj(post,
+ " (invalid octal number?)", -1);
+ parsePtr->errorType = TCL_PARSE_BAD_NUMBER;
+ errCode = "BADNUMBER";
+ subErrCode = "OCTAL";
+ }
+ break;
}
- Tcl_DecrRefCount(copy);
}
- scanned = 0;
- insertMark = 1;
- parsePtr->errorType = TCL_PARSE_BAD_NUMBER;
- } else {
- errCode = "BAREWORD";
}
goto error;
}
@@ -800,17 +797,19 @@ ParseExpr(
}
} /* Uncategorized lexemes */
- /* Handle lexeme based on its category. */
- switch (NODE_TYPE & lexeme) {
-
/*
- * Each LEAF results in either a literal getting appended to the
- * litList, or a sequence of Tcl_Tokens representing a Tcl word
- * getting appended to the parsePtr->tokens. No OpNode is filled for
- * this lexeme.
+ * Handle lexeme based on its category.
*/
+ switch (NODE_TYPE & lexeme) {
case LEAF: {
+ /*
+ * Each LEAF results in either a literal getting appended to the
+ * litList, or a sequence of Tcl_Tokens representing a Tcl word
+ * getting appended to the parsePtr->tokens. No OpNode is filled
+ * for this lexeme.
+ */
+
Tcl_Token *tokenPtr;
const char *end = start;
int wordIndex;
@@ -824,22 +823,13 @@ ParseExpr(
if (NotOperator(lastParsed)) {
msg = Tcl_ObjPrintf("missing operator at %s", mark);
errCode = "MISSING";
- if (lastStart[0] == '0') {
- Tcl_Obj *copy = Tcl_NewStringObj(lastStart,
- start + scanned - lastStart);
-
- if (TclCheckBadOctal(NULL, Tcl_GetString(copy))) {
- TclNewLiteralStringObj(post,
- "looks like invalid octal number");
- errCode = "BADNUMBER_OCTAL";
- }
- Tcl_DecrRefCount(copy);
- }
scanned = 0;
insertMark = 1;
- parsePtr->errorType = TCL_PARSE_BAD_NUMBER;
- /* Free any literal to avoid a memleak. */
+ /*
+ * Free any literal to avoid a memleak.
+ */
+
if ((lexeme == NUMBER) || (lexeme == BOOLEAN)) {
Tcl_DecrRefCount(literal);
}
@@ -1038,7 +1028,10 @@ ParseExpr(
goto error;
}
- /* Create an OpNode for the unary operator */
+ /*
+ * Create an OpNode for the unary operator.
+ */
+
nodePtr->lexeme = lexeme;
nodePtr->precedence = prec[lexeme];
nodePtr->mark = MARK_RIGHT;
@@ -1509,7 +1502,10 @@ ConvertTreeToTokens(
case OT_LITERAL:
- /* Skip any white space that comes before the literal */
+ /*
+ * Skip any white space that comes before the literal.
+ */
+
scanned = TclParseAllWhiteSpace(start, numBytes);
start += scanned;
numBytes -= scanned;
@@ -1592,7 +1588,10 @@ ConvertTreeToTokens(
default:
- /* Advance to the child node, which is an operator. */
+ /*
+ * Advance to the child node, which is an operator.
+ */
+
nodePtr = nodes + next;
/*
@@ -1673,7 +1672,10 @@ ConvertTreeToTokens(
case MARK_RIGHT:
next = nodePtr->right;
- /* Skip any white space that comes before the operator */
+ /*
+ * Skip any white space that comes before the operator.
+ */
+
scanned = TclParseAllWhiteSpace(start, numBytes);
start += scanned;
numBytes -= scanned;
@@ -1690,7 +1692,10 @@ ConvertTreeToTokens(
case COMMA:
case COLON:
- /* No tokens for these lexemes -> nothing to do. */
+ /*
+ * No tokens for these lexemes -> nothing to do.
+ */
+
break;
default:
@@ -1725,7 +1730,10 @@ ConvertTreeToTokens(
case OPEN_PAREN:
- /* Skip past matching close paren. */
+ /*
+ * Skip past matching close paren.
+ */
+
scanned = TclParseAllWhiteSpace(start, numBytes);
start += scanned;
numBytes -= scanned;
@@ -1734,7 +1742,7 @@ ConvertTreeToTokens(
numBytes -= scanned;
break;
- default: {
+ default:
/*
* Before we leave this node/operator/subexpression for the
@@ -1768,7 +1776,6 @@ ConvertTreeToTokens(
subExprTokenIdx = parentIdx;
break;
}
- }
/*
* Since we're returning to parent, skip child handling code.
@@ -1996,14 +2003,55 @@ ParseLexeme(
literal = Tcl_NewObj();
if (TclParseNumber(NULL, literal, NULL, start, numBytes, &end,
TCL_PARSE_NO_WHITESPACE) == TCL_OK) {
- TclInitStringRep(literal, start, end-start);
- *lexemePtr = NUMBER;
- if (literalPtr) {
- *literalPtr = literal;
+ if (end < start + numBytes && !isalnum(UCHAR(*end))
+ && UCHAR(*end) != '_') {
+
+ number:
+ TclInitStringRep(literal, start, end-start);
+ *lexemePtr = NUMBER;
+ if (literalPtr) {
+ *literalPtr = literal;
+ } else {
+ Tcl_DecrRefCount(literal);
+ }
+ return (end-start);
} else {
- Tcl_DecrRefCount(literal);
+ unsigned char lexeme;
+
+ /*
+ * We have a number followed directly by bareword characters
+ * (alpha, digit, underscore). Is this a number followed by
+ * bareword syntax error? Or should we join into one bareword?
+ * Example: Inf + luence + () becomes a valid function call.
+ * [Bug 3401704]
+ */
+ if (literal->typePtr == &tclDoubleType) {
+ const char *p = start;
+
+ while (p < end) {
+ if (!isalnum(UCHAR(*p++))) {
+ /*
+ * The number has non-bareword characters, so we
+ * must treat it as a number.
+ */
+ goto number;
+ }
+ }
+ }
+ ParseLexeme(end, numBytes-(end-start), &lexeme, NULL);
+ if ((NODE_TYPE & lexeme) == BINARY) {
+ /*
+ * The bareword characters following the number take the
+ * form of an operator (eq, ne, in, ni, ...) so we treat
+ * as number + operator.
+ */
+ goto number;
+ }
+
+ /*
+ * Otherwise, fall through and parse the whole as a bareword.
+ */
}
- return (end-start);
}
if (Tcl_UtfCharComplete(start, numBytes)) {
@@ -2015,7 +2063,7 @@ ParseLexeme(
utfBytes[numBytes] = '\0';
scanned = Tcl_UtfToUniChar(utfBytes, &ch);
}
- if (!isalpha(UCHAR(ch))) {
+ if (!isalnum(UCHAR(ch))) {
*lexemePtr = INVALID;
Tcl_DecrRefCount(literal);
return scanned;
@@ -2152,7 +2200,7 @@ ExecConstantExprTree(
TclInitByteCodeObj(byteCodeObj, envPtr);
TclFreeCompileEnv(envPtr);
TclStackFree(interp, envPtr);
- byteCodePtr = byteCodeObj->internalRep.otherValuePtr;
+ byteCodePtr = byteCodeObj->internalRep.twoPtrValue.ptr1;
TclNRExecuteByteCode(interp, byteCodePtr);
code = TclNRRunCallbacks(interp, TCL_OK, rootPtr);
Tcl_DecrRefCount(byteCodeObj);
@@ -2206,30 +2254,8 @@ CompileExprTree(
if (nodePtr->mark == MARK_LEFT) {
next = nodePtr->left;
- switch (nodePtr->lexeme) {
- case QUESTION:
- newJump = TclStackAlloc(interp, sizeof(JumpList));
- newJump->next = jumpPtr;
- jumpPtr = newJump;
- newJump = TclStackAlloc(interp, sizeof(JumpList));
- newJump->next = jumpPtr;
- jumpPtr = newJump;
- jumpPtr->depth = envPtr->currStackDepth;
+ if (nodePtr->lexeme == QUESTION) {
convert = 1;
- break;
- case AND:
- case OR:
- newJump = TclStackAlloc(interp, sizeof(JumpList));
- newJump->next = jumpPtr;
- jumpPtr = newJump;
- newJump = TclStackAlloc(interp, sizeof(JumpList));
- newJump->next = jumpPtr;
- jumpPtr = newJump;
- newJump = TclStackAlloc(interp, sizeof(JumpList));
- newJump->next = jumpPtr;
- jumpPtr = newJump;
- jumpPtr->depth = envPtr->currStackDepth;
- break;
}
} else if (nodePtr->mark == MARK_RIGHT) {
next = nodePtr->right;
@@ -2241,7 +2267,7 @@ CompileExprTree(
int length;
Tcl_DStringInit(&cmdName);
- Tcl_DStringAppend(&cmdName, "tcl::mathfunc::", -1);
+ TclDStringAppendLiteral(&cmdName, "tcl::mathfunc::");
p = TclGetStringFromObj(*funcObjv, &length);
funcObjv++;
Tcl_DStringAppend(&cmdName, p, length);
@@ -2262,25 +2288,35 @@ CompileExprTree(
break;
}
case QUESTION:
- TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &(jumpPtr->jump));
+ newJump = TclStackAlloc(interp, sizeof(JumpList));
+ newJump->next = jumpPtr;
+ jumpPtr = newJump;
+ TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpPtr->jump);
break;
case COLON:
- CLANG_ASSERT(jumpPtr);
+ newJump = TclStackAlloc(interp, sizeof(JumpList));
+ newJump->next = jumpPtr;
+ jumpPtr = newJump;
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
- &(jumpPtr->next->jump));
- envPtr->currStackDepth = jumpPtr->depth;
- jumpPtr->offset = (envPtr->codeNext - envPtr->codeStart);
- jumpPtr->convert = convert;
+ &jumpPtr->jump);
+ TclAdjustStackDepth(-1, envPtr);
+ if (convert) {
+ jumpPtr->jump.jumpType = TCL_TRUE_JUMP;
+ }
convert = 1;
break;
case AND:
- TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &(jumpPtr->jump));
- break;
case OR:
- TclEmitForwardJump(envPtr, TCL_TRUE_JUMP, &(jumpPtr->jump));
+ newJump = TclStackAlloc(interp, sizeof(JumpList));
+ newJump->next = jumpPtr;
+ jumpPtr = newJump;
+ TclEmitForwardJump(envPtr, (nodePtr->lexeme == AND)
+ ? TCL_FALSE_JUMP : TCL_TRUE_JUMP, &jumpPtr->jump);
break;
}
} else {
+ int pc1, pc2, target;
+
switch (nodePtr->lexeme) {
case START:
case QUESTION:
@@ -2299,9 +2335,9 @@ CompileExprTree(
*/
if (numWords < 255) {
- TclEmitInstInt1(INST_INVOKE_STK1, numWords, envPtr);
+ TclEmitInvoke(envPtr, INST_INVOKE_STK1, numWords);
} else {
- TclEmitInstInt4(INST_INVOKE_STK4, numWords, envPtr);
+ TclEmitInvoke(envPtr, INST_INVOKE_STK4, numWords);
}
/*
@@ -2320,18 +2356,20 @@ CompileExprTree(
break;
case COLON:
CLANG_ASSERT(jumpPtr);
- if (TclFixupForwardJump(envPtr, &(jumpPtr->next->jump),
- (envPtr->codeNext - envPtr->codeStart)
- - jumpPtr->next->jump.codeOffset, 127)) {
- jumpPtr->offset += 3;
+ if (jumpPtr->jump.jumpType == TCL_TRUE_JUMP) {
+ jumpPtr->jump.jumpType = TCL_UNCONDITIONAL_JUMP;
+ convert = 1;
+ }
+ target = jumpPtr->jump.codeOffset + 2;
+ if (TclFixupForwardJumpToHere(envPtr, &jumpPtr->jump, 127)) {
+ target += 3;
}
- TclFixupForwardJump(envPtr, &(jumpPtr->jump),
- jumpPtr->offset - jumpPtr->jump.codeOffset, 127);
- convert |= jumpPtr->convert;
- envPtr->currStackDepth = jumpPtr->depth + 1;
freePtr = jumpPtr;
jumpPtr = jumpPtr->next;
TclStackFree(interp, freePtr);
+ TclFixupForwardJump(envPtr, &jumpPtr->jump,
+ target - jumpPtr->jump.codeOffset, 127);
+
freePtr = jumpPtr;
jumpPtr = jumpPtr->next;
TclStackFree(interp, freePtr);
@@ -2339,29 +2377,24 @@ CompileExprTree(
case AND:
case OR:
CLANG_ASSERT(jumpPtr);
- TclEmitForwardJump(envPtr, (nodePtr->lexeme == AND)
- ? TCL_FALSE_JUMP : TCL_TRUE_JUMP,
- &(jumpPtr->next->jump));
+ pc1 = CurrentOffset(envPtr);
+ TclEmitInstInt1((nodePtr->lexeme == AND) ? INST_JUMP_FALSE1
+ : INST_JUMP_TRUE1, 0, envPtr);
TclEmitPush(TclRegisterNewLiteral(envPtr,
(nodePtr->lexeme == AND) ? "1" : "0", 1), envPtr);
- TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
- &(jumpPtr->next->next->jump));
- TclFixupForwardJumpToHere(envPtr, &(jumpPtr->next->jump), 127);
- if (TclFixupForwardJumpToHere(envPtr, &(jumpPtr->jump), 127)) {
- jumpPtr->next->next->jump.codeOffset += 3;
+ pc2 = CurrentOffset(envPtr);
+ TclEmitInstInt1(INST_JUMP1, 0, envPtr);
+ TclAdjustStackDepth(-1, envPtr);
+ TclStoreInt1AtPtr(CurrentOffset(envPtr) - pc1,
+ envPtr->codeStart + pc1 + 1);
+ if (TclFixupForwardJumpToHere(envPtr, &jumpPtr->jump, 127)) {
+ pc2 += 3;
}
TclEmitPush(TclRegisterNewLiteral(envPtr,
(nodePtr->lexeme == AND) ? "0" : "1", 1), envPtr);
- TclFixupForwardJumpToHere(envPtr, &(jumpPtr->next->next->jump),
- 127);
+ TclStoreInt1AtPtr(CurrentOffset(envPtr) - pc2,
+ envPtr->codeStart + pc2 + 1);
convert = 0;
- envPtr->currStackDepth = jumpPtr->depth + 1;
- freePtr = jumpPtr;
- jumpPtr = jumpPtr->next;
- TclStackFree(interp, freePtr);
- freePtr = jumpPtr;
- jumpPtr = jumpPtr->next;
- TclStackFree(interp, freePtr);
freePtr = jumpPtr;
jumpPtr = jumpPtr->next;
TclStackFree(interp, freePtr);
@@ -2372,8 +2405,8 @@ CompileExprTree(
break;
}
if (nodePtr == rootPtr) {
-
/* We're done */
+
return;
}
nodePtr = nodes + nodePtr->p.parent;
@@ -2390,14 +2423,11 @@ CompileExprTree(
Tcl_Obj *literal = *litObjv;
if (optimize) {
- int length, index;
+ int length;
const char *bytes = TclGetStringFromObj(literal, &length);
- LiteralEntry *lePtr;
- Tcl_Obj *objPtr;
-
- index = TclRegisterNewLiteral(envPtr, bytes, length);
- lePtr = envPtr->literalArrayPtr + index;
- objPtr = lePtr->objPtr;
+ int index = TclRegisterNewLiteral(envPtr, bytes, length);
+ Tcl_Obj *objPtr = TclFetchLiteral(envPtr, index);
+
if ((objPtr->typePtr == NULL) && (literal->typePtr != NULL)) {
/*
* Would like to do this:
@@ -2433,8 +2463,7 @@ CompileExprTree(
break;
}
case OT_TOKENS:
- TclCompileTokens(interp, tokenPtr+1, tokenPtr->numComponents,
- envPtr);
+ CompileTokens(envPtr, tokenPtr, interp);
tokenPtr += tokenPtr->numComponents + 1;
break;
default:
@@ -2443,8 +2472,34 @@ CompileExprTree(
if (ExecConstantExprTree(interp, nodes, next, litObjvPtr)
== TCL_OK) {
- TclEmitPush(TclAddLiteralObj(envPtr,
- Tcl_GetObjResult(interp), NULL), envPtr);
+ int index;
+ Tcl_Obj *objPtr = Tcl_GetObjResult(interp);
+
+ /*
+ * Don't generate a string rep, but if we have one
+ * already, then use it to share via the literal table.
+ */
+
+ if (objPtr->bytes) {
+ Tcl_Obj *tableValue;
+
+ index = TclRegisterNewLiteral(envPtr, objPtr->bytes,
+ objPtr->length);
+ tableValue = TclFetchLiteral(envPtr, index);
+ if ((tableValue->typePtr == NULL) &&
+ (objPtr->typePtr != NULL)) {
+ /*
+ * Same intrep surgery as for OT_LITERAL.
+ */
+
+ tableValue->typePtr = objPtr->typePtr;
+ tableValue->internalRep = objPtr->internalRep;
+ objPtr->typePtr = NULL;
+ }
+ } else {
+ index = TclAddLiteralObj(envPtr, objPtr, NULL);
+ }
+ TclEmitPush(index, envPtr);
} else {
TclCompileSyntaxError(interp, envPtr);
}
@@ -2461,6 +2516,7 @@ CompileExprTree(
*----------------------------------------------------------------------
*
* TclSingleOpCmd --
+ *
* Implements the commands: ~, !, <<, >>, %, !=, ne, in, ni
* in the ::tcl::mathop namespace. These commands have no
* extension to arbitrary arguments; they accept only exactly one
@@ -2487,7 +2543,7 @@ TclSingleOpCmd(
OpNode nodes[2];
Tcl_Obj *const *litObjv = objv + 1;
- if (objc != 1+occdPtr->i.numArgs) {
+ if (objc != 1 + occdPtr->i.numArgs) {
Tcl_WrongNumArgs(interp, 1, objv, occdPtr->expected);
return TCL_ERROR;
}
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
index ae633ea..347e3f0 100644
--- a/generic/tclCompile.c
+++ b/generic/tclCompile.c
@@ -14,6 +14,7 @@
#include "tclInt.h"
#include "tclCompile.h"
+#include <assert.h>
/*
* Table of all AuxData types.
@@ -37,7 +38,7 @@ TCL_DECLARE_MUTEX(tableMutex)
int tclTraceCompile = 0;
static int traceInitialized = 0;
#endif
-
+
/*
* A table describing the Tcl bytecode instructions. Entries in this table
* must correspond to the instruction opcode definitions in tclCompile.h. The
@@ -62,7 +63,7 @@ InstructionDesc const tclInstructionTable[] = {
/* Pop the topmost stack object */
{"dup", 1, +1, 0, {OPERAND_NONE}},
/* Duplicate the topmost stack object and push the result */
- {"concat1", 2, INT_MIN, 1, {OPERAND_UINT1}},
+ {"strcat", 2, INT_MIN, 1, {OPERAND_UINT1}},
/* Concatenate the top op1 items and push result */
{"invokeStk1", 2, INT_MIN, 1, {OPERAND_UINT1}},
/* Invoke command named objv[0]; <objc,objv> = <op1,top op1> */
@@ -309,7 +310,7 @@ InstructionDesc const tclInstructionTable[] = {
{"pushReturnOpts", 1, +1, 0, {OPERAND_NONE}},
/* Push the interpreter's return option dictionary as an object on the
* stack. */
- {"returnStk", 1, -2, 0, {OPERAND_NONE}},
+ {"returnStk", 1, -1, 0, {OPERAND_NONE}},
/* Compiled [return]; options and result are on the stack, code and
* level are in the options. */
@@ -372,17 +373,18 @@ InstructionDesc const tclInstructionTable[] = {
* Stack: ... value => ...
* Note that the jump table contains offsets relative to the PC when
* it points to this instruction; the code is relocatable. */
- {"upvar", 5, 0, 1, {OPERAND_LVT4}},
+ {"upvar", 5, -1, 1, {OPERAND_LVT4}},
/* finds level and otherName in stack, links to local variable at
* index op1. Leaves the level on stack. */
- {"nsupvar", 5, 0, 1, {OPERAND_LVT4}},
+ {"nsupvar", 5, -1, 1, {OPERAND_LVT4}},
/* finds namespace and otherName in stack, links to local variable at
* index op1. Leaves the namespace on stack. */
- {"variable", 5, 0, 1, {OPERAND_LVT4}},
+ {"variable", 5, -1, 1, {OPERAND_LVT4}},
/* finds namespace and otherName in stack, links to local variable at
* index op1. Leaves the namespace on stack. */
{"syntax", 9, -1, 2, {OPERAND_INT4, OPERAND_UINT4}},
- /* Compiled bytecodes to signal syntax error. */
+ /* Compiled bytecodes to signal syntax error. Equivalent to returnImm
+ * except for the ERR_ALREADY_LOGGED flag in the interpreter. */
{"reverse", 5, 0, 1, {OPERAND_UINT4}},
/* Reverse the order of the arg elements at the top of stack */
@@ -421,6 +423,233 @@ InstructionDesc const tclInstructionTable[] = {
/* Make general variable cease to exist; unparsed variable name is
* stktop; op1 is 1 for errors on problems, 0 otherwise */
+ {"dictExpand", 1, -1, 0, {OPERAND_NONE}},
+ /* Probe into a dict and extract it (or a subdict of it) into
+ * variables with matched names. Produces list of keys bound as
+ * result. Part of [dict with].
+ * Stack: ... dict path => ... keyList */
+ {"dictRecombineStk", 1, -3, 0, {OPERAND_NONE}},
+ /* Map variable contents back into a dictionary in a variable. Part of
+ * [dict with].
+ * Stack: ... dictVarName path keyList => ... */
+ {"dictRecombineImm", 5, -2, 1, {OPERAND_LVT4}},
+ /* Map variable contents back into a dictionary in the local variable
+ * indicated by the LVT index. Part of [dict with].
+ * Stack: ... path keyList => ... */
+ {"dictExists", 5, INT_MIN, 1, {OPERAND_UINT4}},
+ /* The top op4 words (min 1) are a key path into the dictionary just
+ * below the keys on the stack, and all those values are replaced by a
+ * boolean indicating whether it is possible to read out a value from
+ * that key-path (like [dict exists]).
+ * Stack: ... dict key1 ... keyN => ... boolean */
+ {"verifyDict", 1, -1, 0, {OPERAND_NONE}},
+ /* Verifies that the word on the top of the stack is a dictionary,
+ * popping it if it is and throwing an error if it is not.
+ * Stack: ... value => ... */
+
+ {"strmap", 1, -2, 0, {OPERAND_NONE}},
+ /* Simplified version of [string map] that only applies one change
+ * string, and only case-sensitively.
+ * Stack: ... from to string => ... changedString */
+ {"strfind", 1, -1, 0, {OPERAND_NONE}},
+ /* Find the first index of a needle string in a haystack string,
+ * producing the index (integer) or -1 if nothing found.
+ * Stack: ... needle haystack => ... index */
+ {"strrfind", 1, -1, 0, {OPERAND_NONE}},
+ /* Find the last index of a needle string in a haystack string,
+ * producing the index (integer) or -1 if nothing found.
+ * Stack: ... needle haystack => ... index */
+ {"strrangeImm", 9, 0, 2, {OPERAND_IDX4, OPERAND_IDX4}},
+ /* String Range: push (string range stktop op4 op4) */
+ {"strrange", 1, -2, 0, {OPERAND_NONE}},
+ /* String Range with non-constant arguments.
+ * Stack: ... string idxA idxB => ... substring */
+
+ {"yield", 1, 0, 0, {OPERAND_NONE}},
+ /* Makes the current coroutine yield the value at the top of the
+ * stack, and places the response back on top of the stack when it
+ * resumes.
+ * Stack: ... valueToYield => ... resumeValue */
+ {"coroName", 1, +1, 0, {OPERAND_NONE}},
+ /* Push the name of the interpreter's current coroutine as an object
+ * on the stack. */
+ {"tailcall", 2, INT_MIN, 1, {OPERAND_UINT1}},
+ /* Do a tailcall with the opnd items on the stack as the thing to
+ * tailcall to; opnd must be greater than 0 for the semantics to work
+ * right. */
+
+ {"currentNamespace", 1, +1, 0, {OPERAND_NONE}},
+ /* Push the name of the interpreter's current namespace as an object
+ * on the stack. */
+ {"infoLevelNumber", 1, +1, 0, {OPERAND_NONE}},
+ /* Push the stack depth (i.e., [info level]) of the interpreter as an
+ * object on the stack. */
+ {"infoLevelArgs", 1, 0, 0, {OPERAND_NONE}},
+ /* Push the argument words to a stack depth (i.e., [info level <n>])
+ * of the interpreter as an object on the stack.
+ * Stack: ... depth => ... argList */
+ {"resolveCmd", 1, 0, 0, {OPERAND_NONE}},
+ /* Resolves the command named on the top of the stack to its fully
+ * qualified version, or produces the empty string if no such command
+ * exists. Never generates errors.
+ * Stack: ... cmdName => ... fullCmdName */
+
+ {"tclooSelf", 1, +1, 0, {OPERAND_NONE}},
+ /* Push the identity of the current TclOO object (i.e., the name of
+ * its current public access command) on the stack. */
+ {"tclooClass", 1, 0, 0, {OPERAND_NONE}},
+ /* Push the class of the TclOO object named at the top of the stack
+ * onto the stack.
+ * Stack: ... object => ... class */
+ {"tclooNamespace", 1, 0, 0, {OPERAND_NONE}},
+ /* Push the namespace of the TclOO object named at the top of the
+ * stack onto the stack.
+ * Stack: ... object => ... namespace */
+ {"tclooIsObject", 1, 0, 0, {OPERAND_NONE}},
+ /* Push whether the value named at the top of the stack is a TclOO
+ * object (i.e., a boolean). Can corrupt the interpreter result
+ * despite not throwing, so not safe for use in a post-exception
+ * context.
+ * Stack: ... value => ... boolean */
+
+ {"arrayExistsStk", 1, 0, 0, {OPERAND_NONE}},
+ /* Looks up the element on the top of the stack and tests whether it
+ * is an array. Pushes a boolean describing whether this is the
+ * case. Also runs the whole-array trace on the named variable, so can
+ * throw anything.
+ * Stack: ... varName => ... boolean */
+ {"arrayExistsImm", 5, +1, 1, {OPERAND_UINT4}},
+ /* Looks up the variable indexed by opnd and tests whether it is an
+ * array. Pushes a boolean describing whether this is the case. Also
+ * runs the whole-array trace on the named variable, so can throw
+ * anything.
+ * Stack: ... => ... boolean */
+ {"arrayMakeStk", 1, -1, 0, {OPERAND_NONE}},
+ /* Forces the element on the top of the stack to be the name of an
+ * array.
+ * Stack: ... varName => ... */
+ {"arrayMakeImm", 5, 0, 1, {OPERAND_UINT4}},
+ /* Forces the variable indexed by opnd to be an array. Does not touch
+ * the stack. */
+
+ {"invokeReplace", 6, INT_MIN, 2, {OPERAND_UINT4,OPERAND_UINT1}},
+ /* Invoke command named objv[0], replacing the first two words with
+ * the word at the top of the stack;
+ * <objc,objv> = <op4,top op4 after popping 1> */
+
+ {"listConcat", 1, -1, 0, {OPERAND_NONE}},
+ /* Concatenates the two lists at the top of the stack into a single
+ * list and pushes that resulting list onto the stack.
+ * Stack: ... list1 list2 => ... [lconcat list1 list2] */
+
+ {"expandDrop", 1, 0, 0, {OPERAND_NONE}},
+ /* Drops an element from the auxiliary stack, popping stack elements
+ * until the matching stack depth is reached. */
+
+ /* New foreach implementation */
+ {"foreach_start", 5, +2, 1, {OPERAND_AUX4}},
+ /* Initialize execution of a foreach loop. Operand is aux data index
+ * of the ForeachInfo structure for the foreach command. It pushes 2
+ * elements which hold runtime params for foreach_step, they are later
+ * dropped by foreach_end together with the value lists. NOTE that the
+ * iterator-tracker and info reference must not be passed to bytecodes
+ * that handle normal Tcl values. NOTE that this instruction jumps to
+ * the foreach_step instruction paired with it; the stack info below
+ * is only nominal.
+ * Stack: ... listObjs... => ... listObjs... iterTracker info */
+ {"foreach_step", 1, 0, 0, {OPERAND_NONE}},
+ /* "Step" or begin next iteration of foreach loop. Assigns to foreach
+ * iteration variables. May jump to straight after the foreach_start
+ * that pushed the iterTracker and info values. MUST be followed
+ * immediately by a foreach_end.
+ * Stack: ... listObjs... iterTracker info =>
+ * ... listObjs... iterTracker info */
+ {"foreach_end", 1, 0, 0, {OPERAND_NONE}},
+ /* Clean up a foreach loop by dropping the info value, the tracker
+ * value and the lists that were being iterated over.
+ * Stack: ... listObjs... iterTracker info => ... */
+ {"lmap_collect", 1, -1, 0, {OPERAND_NONE}},
+ /* Appends the value at the top of the stack to the list located on
+ * the stack the "other side" of the foreach-related values.
+ * Stack: ... collector listObjs... iterTracker info value =>
+ * ... collector listObjs... iterTracker info */
+
+ {"strtrim", 1, -1, 0, {OPERAND_NONE}},
+ /* [string trim] core: removes the characters (designated by the value
+ * at the top of the stack) from both ends of the string and pushes
+ * the resulting string.
+ * Stack: ... string charset => ... trimmedString */
+ {"strtrimLeft", 1, -1, 0, {OPERAND_NONE}},
+ /* [string trimleft] core: removes the characters (designated by the
+ * value at the top of the stack) from the left of the string and
+ * pushes the resulting string.
+ * Stack: ... string charset => ... trimmedString */
+ {"strtrimRight", 1, -1, 0, {OPERAND_NONE}},
+ /* [string trimright] core: removes the characters (designated by the
+ * value at the top of the stack) from the right of the string and
+ * pushes the resulting string.
+ * Stack: ... string charset => ... trimmedString */
+
+ {"concatStk", 5, INT_MIN, 1, {OPERAND_UINT4}},
+ /* Wrapper round Tcl_ConcatObj(), used for [concat] and [eval]. opnd
+ * is number of values to concatenate.
+ * Operation: push concat(stk1 stk2 ... stktop) */
+
+ {"strcaseUpper", 1, 0, 0, {OPERAND_NONE}},
+ /* [string toupper] core: converts whole string to upper case using
+ * the default (extended "C" locale) rules.
+ * Stack: ... string => ... newString */
+ {"strcaseLower", 1, 0, 0, {OPERAND_NONE}},
+ /* [string tolower] core: converts whole string to upper case using
+ * the default (extended "C" locale) rules.
+ * Stack: ... string => ... newString */
+ {"strcaseTitle", 1, 0, 0, {OPERAND_NONE}},
+ /* [string totitle] core: converts whole string to upper case using
+ * the default (extended "C" locale) rules.
+ * Stack: ... string => ... newString */
+ {"strreplace", 1, -3, 0, {OPERAND_NONE}},
+ /* [string replace] core: replaces a non-empty range of one string
+ * with the contents of another.
+ * Stack: ... string fromIdx toIdx replacement => ... newString */
+
+ {"originCmd", 1, 0, 0, {OPERAND_NONE}},
+ /* Reports which command was the origin (via namespace import chain)
+ * of the command named on the top of the stack.
+ * Stack: ... cmdName => ... fullOriginalCmdName */
+
+ {"tclooNext", 2, INT_MIN, 1, {OPERAND_UINT1}},
+ /* Call the next item on the TclOO call chain, passing opnd arguments
+ * (min 1, max 255, *includes* "next"). The result of the invoked
+ * method implementation will be pushed on the stack in place of the
+ * arguments (similar to invokeStk).
+ * Stack: ... "next" arg2 arg3 -- argN => ... result */
+ {"tclooNextClass", 2, INT_MIN, 1, {OPERAND_UINT1}},
+ /* Call the following item on the TclOO call chain defined by class
+ * className, passing opnd arguments (min 2, max 255, *includes*
+ * "nextto" and the class name). The result of the invoked method
+ * implementation will be pushed on the stack in place of the
+ * arguments (similar to invokeStk).
+ * Stack: ... "nextto" className arg3 arg4 -- argN => ... result */
+
+ {"yieldToInvoke", 1, 0, 0, {OPERAND_NONE}},
+ /* Makes the current coroutine yield the value at the top of the
+ * stack, invoking the given command/args with resolution in the given
+ * namespace (all packed into a list), and places the list of values
+ * that are the response back on top of the stack when it resumes.
+ * Stack: ... [list ns cmd arg1 ... argN] => ... resumeList */
+
+ {"numericType", 1, 0, 0, {OPERAND_NONE}},
+ /* Pushes the numeric type code of the word at the top of the stack.
+ * Stack: ... value => ... typeCode */
+ {"tryCvtToBoolean", 1, +1, 0, {OPERAND_NONE}},
+ /* Try converting stktop to boolean if possible. No errors.
+ * Stack: ... value => ... value isStrictBool */
+ {"strclass", 2, 0, 1, {OPERAND_SCLS1}},
+ /* See if all the characters of the given string are a member of the
+ * specified (by opnd) character class. Note that an empty string will
+ * satisfy the class check (standard definition of "all").
+ * Stack: ... stringValue => ... boolean */
+
{NULL, 0, 0, 0, {OPERAND_NONE}}
};
@@ -441,11 +670,15 @@ static void EnterCmdStartData(CompileEnv *envPtr,
static void FreeByteCodeInternalRep(Tcl_Obj *objPtr);
static void FreeSubstCodeInternalRep(Tcl_Obj *objPtr);
static int GetCmdLocEncodingSize(CompileEnv *envPtr);
+static int IsCompactibleCompileEnv(Tcl_Interp *interp,
+ CompileEnv *envPtr);
#ifdef TCL_COMPILE_STATS
static void RecordByteCodeStats(ByteCode *codePtr);
#endif /* TCL_COMPILE_STATS */
+static void RegisterAuxDataType(const AuxDataType *typePtr);
static int SetByteCodeFromAny(Tcl_Interp *interp,
Tcl_Obj *objPtr);
+static void StartExpanding(CompileEnv *envPtr);
static int FormatInstruction(ByteCode *codePtr,
const unsigned char *pc, Tcl_Obj *bufferObj);
static void PrintSourceToObj(Tcl_Obj *appendObj,
@@ -460,6 +693,7 @@ static void EnterCmdWordData(ExtCmdLoc *eclPtr, int srcOffset,
Tcl_Token *tokenPtr, const char *cmd, int len,
int numWords, int line, int *clNext, int **lines,
CompileEnv *envPtr);
+static void ReleaseCmdWordData(ExtCmdLoc *eclPtr);
/*
* The structure below defines the bytecode Tcl object type by means of
@@ -499,6 +733,13 @@ static const Tcl_ObjType tclInstNameType = {
UpdateStringOfInstName, /* updateStringProc */
NULL, /* setFromAnyProc */
};
+
+/*
+ * Helper macros.
+ */
+
+#define TclIncrUInt4AtPtr(ptr, delta) \
+ TclStoreInt4AtPtr(TclGetUInt4AtPtr(ptr)+(delta), (ptr));
/*
*----------------------------------------------------------------------
@@ -537,11 +778,9 @@ TclSetByteCodeFromAny(
Interp *iPtr = (Interp *) interp;
CompileEnv compEnv; /* Compilation environment structure allocated
* in frame. */
- register const AuxData *auxDataPtr;
- LiteralEntry *entryPtr;
- register int i;
int length, result = TCL_OK;
const char *stringPtr;
+ Proc *procPtr = iPtr->compiledProcPtr;
ContLineLoc *clLocPtr;
#ifdef TCL_COMPILE_DEBUG
@@ -579,9 +818,7 @@ TclSetByteCodeFromAny(
clLocPtr = TclContinuationsGet(objPtr);
if (clLocPtr) {
- compEnv.clLoc = clLocPtr;
- compEnv.clNext = &compEnv.clLoc->loc[0];
- Tcl_Preserve(compEnv.clLoc);
+ compEnv.clNext = &clLocPtr->loc[0];
}
TclCompileScript(interp, stringPtr, length, &compEnv);
@@ -593,6 +830,40 @@ TclSetByteCodeFromAny(
TclEmitOpcode(INST_DONE, &compEnv);
/*
+ * Check for optimizations!
+ *
+ * Test if the generated code is free of most hazards; if so, recompile
+ * but with generation of INST_START_CMD disabled. This produces somewhat
+ * faster code in some cases, and more compact code in more.
+ */
+
+ if (Tcl_GetMaster(interp) == NULL &&
+ !Tcl_LimitTypeEnabled(interp, TCL_LIMIT_COMMANDS|TCL_LIMIT_TIME)
+ && IsCompactibleCompileEnv(interp, &compEnv)) {
+ TclFreeCompileEnv(&compEnv);
+ iPtr->compiledProcPtr = procPtr;
+ TclInitCompileEnv(interp, &compEnv, stringPtr, length,
+ iPtr->invokeCmdFramePtr, iPtr->invokeWord);
+ if (clLocPtr) {
+ compEnv.clNext = &clLocPtr->loc[0];
+ }
+ compEnv.atCmdStart = 2; /* The disabling magic. */
+ TclCompileScript(interp, stringPtr, length, &compEnv);
+ assert (compEnv.atCmdStart > 1);
+ TclEmitOpcode(INST_DONE, &compEnv);
+ assert (compEnv.atCmdStart > 1);
+ }
+
+ /*
+ * Apply some peephole optimizations that can cross specific/generic
+ * instruction generator boundaries.
+ */
+
+ if (iPtr->extra.optimizer) {
+ (iPtr->extra.optimizer)(&compEnv);
+ }
+
+ /*
* Invoke the compilation hook procedure if one exists.
*/
@@ -609,35 +880,14 @@ TclSetByteCodeFromAny(
TclVerifyLocalLiteralTable(&compEnv);
#endif /*TCL_COMPILE_DEBUG*/
- TclInitByteCodeObj(objPtr, &compEnv);
-#ifdef TCL_COMPILE_DEBUG
- if (tclTraceCompile >= 2) {
- TclPrintByteCodeObj(interp, objPtr);
- fflush(stdout);
- }
-#endif /* TCL_COMPILE_DEBUG */
-
- if (result != TCL_OK) {
- /*
- * Handle any error from the hookProc
- */
-
- entryPtr = compEnv.literalArrayPtr;
- for (i = 0; i < compEnv.literalArrayNext; i++) {
- TclReleaseLiteral(interp, entryPtr->objPtr);
- entryPtr++;
- }
+ if (result == TCL_OK) {
+ TclInitByteCodeObj(objPtr, &compEnv);
#ifdef TCL_COMPILE_DEBUG
- TclVerifyGlobalLiteralTable(iPtr);
-#endif /*TCL_COMPILE_DEBUG*/
-
- auxDataPtr = compEnv.auxDataArrayPtr;
- for (i = 0; i < compEnv.auxDataArrayNext; i++) {
- if (auxDataPtr->type->freeProc != NULL) {
- auxDataPtr->type->freeProc(auxDataPtr->clientData);
- }
- auxDataPtr++;
+ if (tclTraceCompile >= 2) {
+ TclPrintByteCodeObj(interp, objPtr);
+ fflush(stdout);
}
+#endif /* TCL_COMPILE_DEBUG */
}
TclFreeCompileEnv(&compEnv);
@@ -676,8 +926,7 @@ SetByteCodeFromAny(
if (interp == NULL) {
return TCL_ERROR;
}
- TclSetByteCodeFromAny(interp, objPtr, NULL, NULL);
- return TCL_OK;
+ return TclSetByteCodeFromAny(interp, objPtr, NULL, NULL);
}
/*
@@ -731,10 +980,9 @@ static void
FreeByteCodeInternalRep(
register Tcl_Obj *objPtr) /* Object whose internal rep to free. */
{
- register ByteCode *codePtr = objPtr->internalRep.otherValuePtr;
+ register ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
objPtr->typePtr = NULL;
- objPtr->internalRep.otherValuePtr = NULL;
codePtr->refCount--;
if (codePtr->refCount <= 0) {
TclCleanupByteCode(codePtr);
@@ -754,9 +1002,8 @@ FreeByteCodeInternalRep(
* None.
*
* Side effects:
- * Frees objPtr's bytecode internal representation and sets its type and
- * objPtr->internalRep.otherValuePtr NULL. Also releases its literals and
- * frees its auxiliary data items.
+ * Frees objPtr's bytecode internal representation and sets its type NULL
+ * Also releases its literals and frees its auxiliary data items.
*
*----------------------------------------------------------------------
*/
@@ -831,7 +1078,7 @@ TclCleanupByteCode(
* released.
*/
- if ((codePtr->flags & TCL_BYTECODE_PRECOMPILED) || (interp == NULL)) {
+ if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
objArrayPtr = codePtr->objArrayPtr;
for (i = 0; i < numLitObjects; i++) {
@@ -844,17 +1091,9 @@ TclCleanupByteCode(
codePtr->numLitObjects = 0;
} else {
objArrayPtr = codePtr->objArrayPtr;
- for (i = 0; i < numLitObjects; i++) {
- /*
- * TclReleaseLiteral sets a ByteCode's object array entry NULL to
- * indicate that it has already freed the literal.
- */
-
- objPtr = *objArrayPtr;
- if (objPtr != NULL) {
- TclReleaseLiteral(interp, objPtr);
- }
- objArrayPtr++;
+ while (numLitObjects--) {
+ /* TclReleaseLiteral calls Tcl_DecrRefCount() for us */
+ TclReleaseLiteral(interp, *objArrayPtr++);
}
}
@@ -879,22 +1118,7 @@ TclCleanupByteCode(
(char *) codePtr);
if (hePtr) {
- ExtCmdLoc *eclPtr = Tcl_GetHashValue(hePtr);
-
- if (eclPtr->type == TCL_LOCATION_SOURCE) {
- Tcl_DecrRefCount(eclPtr->path);
- }
- for (i=0 ; i<eclPtr->nuloc ; i++) {
- ckfree(eclPtr->loc[i].line);
- }
-
- if (eclPtr->loc != NULL) {
- ckfree(eclPtr->loc);
- }
-
- Tcl_DeleteHashTable(&eclPtr->litInfo);
-
- ckfree(eclPtr);
+ ReleaseCmdWordData(Tcl_GetHashValue(hePtr));
Tcl_DeleteHashEntry(hePtr);
}
}
@@ -908,6 +1132,77 @@ TclCleanupByteCode(
}
/*
+ * ---------------------------------------------------------------------
+ *
+ * IsCompactibleCompileEnv --
+ *
+ * Checks to see if we may apply some basic compaction optimizations to a
+ * piece of bytecode. Idempotent.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+static int
+IsCompactibleCompileEnv(
+ Tcl_Interp *interp,
+ CompileEnv *envPtr)
+{
+ unsigned char *pc;
+ int size;
+
+ /*
+ * Special: procedures in the '::tcl' namespace (or its children) are
+ * considered to be well-behaved and so can have compaction applied even
+ * if it would otherwise be invalid.
+ */
+
+ if (envPtr->procPtr != NULL && envPtr->procPtr->cmdPtr != NULL
+ && envPtr->procPtr->cmdPtr->nsPtr != NULL) {
+ Namespace *nsPtr = envPtr->procPtr->cmdPtr->nsPtr;
+
+ if (strcmp(nsPtr->fullName, "::tcl") == 0
+ || strncmp(nsPtr->fullName, "::tcl::", 7) == 0) {
+ return 1;
+ }
+ }
+
+ /*
+ * Go through and ensure that no operation involved can cause a desired
+ * change of bytecode sequence during running. This comes down to ensuring
+ * that there are no mapped variables (due to traces) or calls to external
+ * commands (traces, [uplevel] trickery). This is actually a very
+ * conservative check; it turns down a lot of code that is OK in practice.
+ */
+
+ for (pc = envPtr->codeStart ; pc < envPtr->codeNext ; pc += size) {
+ switch (*pc) {
+ /* Invokes */
+ case INST_INVOKE_STK1:
+ case INST_INVOKE_STK4:
+ case INST_INVOKE_EXPANDED:
+ case INST_INVOKE_REPLACE:
+ return 0;
+ /* Runtime evals */
+ case INST_EVAL_STK:
+ case INST_EXPR_STK:
+ case INST_YIELD:
+ return 0;
+ /* Upvars */
+ case INST_UPVAR:
+ case INST_NSUPVAR:
+ case INST_VARIABLE:
+ return 0;
+ default:
+ size = tclInstructionTable[*pc].numBytes;
+ assert (size > 0);
+ break;
+ }
+ }
+
+ return 1;
+}
+
+/*
*----------------------------------------------------------------------
*
* Tcl_SubstObj --
@@ -1031,14 +1326,19 @@ CompileSubstObj(
objPtr->typePtr = &substCodeType;
TclFreeCompileEnv(&compEnv);
- codePtr = objPtr->internalRep.otherValuePtr;
+ codePtr = objPtr->internalRep.twoPtrValue.ptr1;
objPtr->internalRep.ptrAndLongRep.ptr = codePtr;
objPtr->internalRep.ptrAndLongRep.value = flags;
if (iPtr->varFramePtr->localCachePtr) {
codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr;
codePtr->localCachePtr->refCount++;
}
- /* TODO: Debug printing? */
+#ifdef TCL_COMPILE_DEBUG
+ if (tclTraceCompile >= 2) {
+ TclPrintByteCodeObj(interp, objPtr);
+ fflush(stdout);
+ }
+#endif /* TCL_COMPILE_DEBUG */
}
return codePtr;
}
@@ -1070,12 +1370,31 @@ FreeSubstCodeInternalRep(
register ByteCode *codePtr = objPtr->internalRep.ptrAndLongRep.ptr;
objPtr->typePtr = NULL;
- objPtr->internalRep.otherValuePtr = NULL;
codePtr->refCount--;
if (codePtr->refCount <= 0) {
TclCleanupByteCode(codePtr);
}
}
+
+static void
+ReleaseCmdWordData(
+ ExtCmdLoc *eclPtr)
+{
+ int i;
+
+ if (eclPtr->type == TCL_LOCATION_SOURCE) {
+ Tcl_DecrRefCount(eclPtr->path);
+ }
+ for (i=0 ; i<eclPtr->nuloc ; i++) {
+ ckfree((char *) eclPtr->loc[i].line);
+ }
+
+ if (eclPtr->loc != NULL) {
+ ckfree((char *) eclPtr->loc);
+ }
+
+ ckfree((char *) eclPtr);
+}
/*
*----------------------------------------------------------------------
@@ -1108,6 +1427,8 @@ TclInitCompileEnv(
{
Interp *iPtr = (Interp *) interp;
+ assert(tclInstructionTable[LAST_INST_OPCODE+1].name == NULL);
+
envPtr->iPtr = iPtr;
envPtr->source = stringPtr;
envPtr->numSrcBytes = numBytes;
@@ -1131,6 +1452,7 @@ TclInitCompileEnv(
envPtr->mallocedLiteralArray = 0;
envPtr->exceptArrayPtr = envPtr->staticExceptArraySpace;
+ envPtr->exceptAuxArrayPtr = envPtr->staticExAuxArraySpace;
envPtr->exceptArrayNext = 0;
envPtr->exceptArrayEnd = COMPILEENV_INIT_EXCEPT_RANGES;
envPtr->mallocedExceptArray = 0;
@@ -1139,6 +1461,7 @@ TclInitCompileEnv(
envPtr->cmdMapEnd = COMPILEENV_INIT_CMD_MAP_SIZE;
envPtr->mallocedCmdMap = 0;
envPtr->atCmdStart = 1;
+ envPtr->expandCount = 0;
/*
* TIP #280: Set up the extended command location information, based on
@@ -1154,9 +1477,8 @@ TclInitCompileEnv(
envPtr->extCmdMapPtr->nloc = 0;
envPtr->extCmdMapPtr->nuloc = 0;
envPtr->extCmdMapPtr->path = NULL;
- Tcl_InitHashTable(&envPtr->extCmdMapPtr->litInfo, TCL_ONE_WORD_KEYS);
- if ((invoker == NULL) || (invoker->type == TCL_LOCATION_EVAL_LIST)) {
+ if (invoker == NULL) {
/*
* Initialize the compiler for relative counting in case of a
* dynamic context.
@@ -1270,7 +1592,6 @@ TclInitCompileEnv(
* data is available.
*/
- envPtr->clLoc = NULL;
envPtr->clNext = NULL;
envPtr->auxDataArrayPtr = envPtr->staticAuxDataArraySpace;
@@ -1309,6 +1630,32 @@ TclFreeCompileEnv(
ckfree(envPtr->localLitTable.buckets);
envPtr->localLitTable.buckets = envPtr->localLitTable.staticBuckets;
}
+ if (envPtr->iPtr) {
+ /*
+ * We never converted to Bytecode, so free the things we would
+ * have transferred to it.
+ */
+
+ int i;
+ LiteralEntry *entryPtr = envPtr->literalArrayPtr;
+ AuxData *auxDataPtr = envPtr->auxDataArrayPtr;
+
+ for (i = 0; i < envPtr->literalArrayNext; i++) {
+ TclReleaseLiteral((Tcl_Interp *)envPtr->iPtr, entryPtr->objPtr);
+ entryPtr++;
+ }
+
+#ifdef TCL_COMPILE_DEBUG
+ TclVerifyGlobalLiteralTable(envPtr->iPtr);
+#endif /*TCL_COMPILE_DEBUG*/
+
+ for (i = 0; i < envPtr->auxDataArrayNext; i++) {
+ if (auxDataPtr->type->freeProc != NULL) {
+ auxDataPtr->type->freeProc(auxDataPtr->clientData);
+ }
+ auxDataPtr++;
+ }
+ }
if (envPtr->mallocedCodeArray) {
ckfree(envPtr->codeStart);
}
@@ -1317,6 +1664,7 @@ TclFreeCompileEnv(
}
if (envPtr->mallocedExceptArray) {
ckfree(envPtr->exceptArrayPtr);
+ ckfree(envPtr->exceptAuxArrayPtr);
}
if (envPtr->mallocedCmdMap) {
ckfree(envPtr->cmdMapPtr);
@@ -1325,17 +1673,8 @@ TclFreeCompileEnv(
ckfree(envPtr->auxDataArrayPtr);
}
if (envPtr->extCmdMapPtr) {
- ckfree(envPtr->extCmdMapPtr);
- }
-
- /*
- * If we used data about invisible continuation lines, then now is the
- * time to release on our hold on it. The lock was set in function
- * TclSetByteCodeFromAny(), found in this file.
- */
-
- if (envPtr->clLoc) {
- Tcl_Release(envPtr->clLoc);
+ ReleaseCmdWordData(envPtr->extCmdMapPtr);
+ envPtr->extCmdMapPtr = NULL;
}
}
@@ -1437,452 +1776,467 @@ TclWordKnownAtCompileTime(
*----------------------------------------------------------------------
*/
+static int
+ExpandRequested(
+ Tcl_Token *tokenPtr,
+ int numWords)
+{
+ /* Determine whether any words of the command require expansion */
+ while (numWords--) {
+ if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
+ return 1;
+ }
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+ return 0;
+}
+
+static void
+CompileCmdLiteral(
+ Tcl_Interp *interp,
+ Tcl_Obj *cmdObj,
+ CompileEnv *envPtr)
+{
+ int numBytes;
+ const char *bytes = Tcl_GetStringFromObj(cmdObj, &numBytes);
+ int cmdLitIdx = TclRegisterNewCmdLiteral(envPtr, bytes, numBytes);
+ Command *cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, cmdObj);
+
+ if (cmdPtr) {
+ TclSetCmdNameObj(interp, TclFetchLiteral(envPtr, cmdLitIdx), cmdPtr);
+ }
+ TclEmitPush(cmdLitIdx, envPtr);
+}
+
void
-TclCompileScript(
- Tcl_Interp *interp, /* Used for error and status reporting. Also
- * serves as context for finding and compiling
- * commands. May not be NULL. */
- const char *script, /* The source script to compile. */
- int numBytes, /* Number of bytes in script. If < 0, the
- * script consists of all bytes up to the
- * first null character. */
- CompileEnv *envPtr) /* Holds resulting instructions. */
+TclCompileInvocation(
+ Tcl_Interp *interp,
+ Tcl_Token *tokenPtr,
+ Tcl_Obj *cmdObj,
+ int numWords,
+ CompileEnv *envPtr)
{
- Interp *iPtr = (Interp *) interp;
- int lastTopLevelCmdIndex = -1;
- /* Index of most recent toplevel command in
- * the command location table. Initialized to
- * avoid compiler warning. */
- int startCodeOffset = -1; /* Offset of first byte of current command's
- * code. Init. to avoid compiler warning. */
- unsigned char *entryCodeNext = envPtr->codeNext;
- const char *p, *next;
- Namespace *cmdNsPtr;
- Command *cmdPtr;
- Tcl_Token *tokenPtr;
- int bytesLeft, isFirstCmd, wordIdx, currCmdIndex, commandLength, objIndex;
- Tcl_DString ds;
- /* TIP #280 */
- ExtCmdLoc *eclPtr = envPtr->extCmdMapPtr;
- int *wlines, wlineat, cmdLine, *clNext;
- Tcl_Parse *parsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse));
+ int wordIdx = 0, depth = TclGetStackDepth(envPtr);
+ DefineLineInformation;
+
+ if (cmdObj) {
+ CompileCmdLiteral(interp, cmdObj, envPtr);
+ wordIdx = 1;
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+
+ for (; wordIdx < numWords; wordIdx++, tokenPtr = TokenAfter(tokenPtr)) {
+ int objIdx;
- Tcl_DStringInit(&ds);
+ SetLineInformation(wordIdx);
+
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ CompileTokens(envPtr, tokenPtr, interp);
+ continue;
+ }
- if (numBytes < 0) {
- numBytes = strlen(script);
+ objIdx = TclRegisterNewLiteral(envPtr,
+ tokenPtr[1].start, tokenPtr[1].size);
+ if (envPtr->clNext) {
+ TclContinuationsEnterDerived(TclFetchLiteral(envPtr, objIdx),
+ tokenPtr[1].start - envPtr->source, envPtr->clNext);
+ }
+ TclEmitPush(objIdx, envPtr);
}
- Tcl_ResetResult(interp);
- isFirstCmd = 1;
- if (envPtr->procPtr != NULL) {
- cmdNsPtr = envPtr->procPtr->cmdPtr->nsPtr;
+ if (wordIdx <= 255) {
+ TclEmitInvoke(envPtr, INST_INVOKE_STK1, wordIdx);
} else {
- cmdNsPtr = NULL; /* use current NS */
+ TclEmitInvoke(envPtr, INST_INVOKE_STK4, wordIdx);
}
+ TclCheckStackDepth(depth+1, envPtr);
+}
- /*
- * Each iteration through the following loop compiles the next command
- * from the script.
- */
+static void
+CompileExpanded(
+ Tcl_Interp *interp,
+ Tcl_Token *tokenPtr,
+ Tcl_Obj *cmdObj,
+ int numWords,
+ CompileEnv *envPtr)
+{
+ int wordIdx = 0;
+ DefineLineInformation;
+ int depth = TclGetStackDepth(envPtr);
+
+ StartExpanding(envPtr);
+ if (cmdObj) {
+ CompileCmdLiteral(interp, cmdObj, envPtr);
+ wordIdx = 1;
+ tokenPtr = TokenAfter(tokenPtr);
+ }
- p = script;
- bytesLeft = numBytes;
- cmdLine = envPtr->line;
- clNext = envPtr->clNext;
- do {
- if (Tcl_ParseCommand(interp, p, bytesLeft, 0, parsePtr) != TCL_OK) {
- /*
- * Compile bytecodes to report the parse error at runtime.
- */
+ for (; wordIdx < numWords; wordIdx++, tokenPtr = TokenAfter(tokenPtr)) {
+ int objIdx;
- Tcl_LogCommandInfo(interp, script, parsePtr->commandStart,
- /* Drop the command terminator (";","]") if appropriate */
- (parsePtr->term ==
- parsePtr->commandStart + parsePtr->commandSize - 1)?
- parsePtr->commandSize - 1 : parsePtr->commandSize);
- TclCompileSyntaxError(interp, envPtr);
- break;
+ SetLineInformation(wordIdx);
+
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ CompileTokens(envPtr, tokenPtr, interp);
+ if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
+ TclEmitInstInt4(INST_EXPAND_STKTOP,
+ envPtr->currStackDepth, envPtr);
+ }
+ continue;
}
- /*
- * TIP #280: We have to count newlines before the command even in the
- * degenerate case when the command has no words. (See test
- * info-30.33).
- * So make that counting here, and not in the (numWords > 0) branch
- * below.
- */
+ objIdx = TclRegisterNewLiteral(envPtr,
+ tokenPtr[1].start, tokenPtr[1].size);
+ if (envPtr->clNext) {
+ TclContinuationsEnterDerived(TclFetchLiteral(envPtr, objIdx),
+ tokenPtr[1].start - envPtr->source, envPtr->clNext);
+ }
+ TclEmitPush(objIdx, envPtr);
+ }
- TclAdvanceLines(&cmdLine, p, parsePtr->commandStart);
- TclAdvanceContinuations(&cmdLine, &clNext,
- parsePtr->commandStart - envPtr->source);
+ /*
+ * The stack depth during argument expansion can only be managed at
+ * runtime, as the number of elements in the expanded lists is not known
+ * at compile time. We adjust here the stack depth estimate so that it is
+ * correct after the command with expanded arguments returns.
+ *
+ * The end effect of this command's invocation is that all the words of
+ * the command are popped from the stack, and the result is pushed: the
+ * stack top changes by (1-wordIdx).
+ *
+ * Note that the estimates are not correct while the command is being
+ * prepared and run, INST_EXPAND_STKTOP is not stack-neutral in general.
+ */
- if (parsePtr->numWords > 0) {
- int expand = 0; /* Set if there are dynamic expansions to
- * handle */
+ TclEmitInvoke(envPtr, INST_INVOKE_EXPANDED, wordIdx);
+ TclCheckStackDepth(depth+1, envPtr);
+}
- /*
- * If not the first command, pop the previous command's result
- * and, if we're compiling a top level command, update the last
- * command's code size to account for the pop instruction.
- */
+static int
+CompileCmdCompileProc(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr,
+ CompileEnv *envPtr)
+{
+ int unwind = 0, incrOffset = -1;
+ DefineLineInformation;
+ int depth = TclGetStackDepth(envPtr);
- if (!isFirstCmd) {
- TclEmitOpcode(INST_POP, envPtr);
- envPtr->cmdMapPtr[lastTopLevelCmdIndex].numCodeBytes =
- (envPtr->codeNext - envPtr->codeStart)
- - startCodeOffset;
- }
+ /*
+ * Emit of the INST_START_CMD instruction is controlled by the value of
+ * envPtr->atCmdStart:
+ *
+ * atCmdStart == 2 : We are not using the INST_START_CMD instruction.
+ * atCmdStart == 1 : INST_START_CMD was the last instruction emitted.
+ * : We do not need to emit another. Instead we
+ * : increment the number of cmds started at it (except
+ * : for the special case at the start of a script.)
+ * atCmdStart == 0 : The last instruction was something else. We need
+ * : to emit INST_START_CMD here.
+ */
+ switch (envPtr->atCmdStart) {
+ case 0:
+ unwind = tclInstructionTable[INST_START_CMD].numBytes;
+ TclEmitInstInt4(INST_START_CMD, 0, envPtr);
+ incrOffset = envPtr->codeNext - envPtr->codeStart;
+ TclEmitInt4(0, envPtr);
+ break;
+ case 1:
+ if (envPtr->codeNext > envPtr->codeStart) {
+ incrOffset = envPtr->codeNext - 4 - envPtr->codeStart;
+ }
+ break;
+ case 2:
+ /* Nothing to do */
+ ;
+ }
+
+ if (TCL_OK == TclAttemptCompileProc(interp, parsePtr, 1, cmdPtr, envPtr)) {
+ if (incrOffset >= 0) {
/*
- * Determine the actual length of the command.
+ * We successfully compiled a command. Increment the number of
+ * commands that start at the currently active INST_START_CMD.
*/
- commandLength = parsePtr->commandSize;
- if (parsePtr->term == parsePtr->commandStart + commandLength-1) {
- /*
- * The command terminator character (such as ; or ]) is the
- * last character in the parsed command. Reduce the length by
- * one so that the trace message doesn't include the
- * terminator character.
- */
+ unsigned char *incrPtr = envPtr->codeStart + incrOffset;
+ unsigned char *startPtr = incrPtr - 5;
- commandLength -= 1;
+ TclIncrUInt4AtPtr(incrPtr, 1);
+ if (unwind) {
+ /* We started the INST_START_CMD. Record the code length. */
+ TclStoreInt4AtPtr(envPtr->codeNext - startPtr, startPtr + 1);
}
+ }
+ TclCheckStackDepth(depth+1, envPtr);
+ return TCL_OK;
+ }
-#ifdef TCL_COMPILE_DEBUG
- /*
- * If tracing, print a line for each top level command compiled.
- */
+ envPtr->codeNext -= unwind; /* Unwind INST_START_CMD */
- if ((tclTraceCompile >= 1) && (envPtr->procPtr == NULL)) {
- fprintf(stdout, " Compiling: ");
- TclPrintSource(stdout, parsePtr->commandStart,
- TclMin(commandLength, 55));
- fprintf(stdout, "\n");
- }
-#endif
+ /*
+ * Throw out any line information generated by the failed compile attempt.
+ */
- /*
- * Check whether expansion has been requested for any of the
- * words.
- */
+ while (mapPtr->nuloc - 1 > eclIndex) {
+ mapPtr->nuloc--;
+ ckfree(mapPtr->loc[mapPtr->nuloc].line);
+ mapPtr->loc[mapPtr->nuloc].line = NULL;
+ }
- for (wordIdx = 0, tokenPtr = parsePtr->tokenPtr;
- wordIdx < parsePtr->numWords;
- wordIdx++, tokenPtr += tokenPtr->numComponents + 1) {
- if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
- expand = 1;
- break;
- }
- }
+ /*
+ * Reset the index of next command. Toss out any from failed nested
+ * partial compiles.
+ */
- envPtr->numCommands++;
- currCmdIndex = envPtr->numCommands - 1;
- lastTopLevelCmdIndex = currCmdIndex;
- startCodeOffset = envPtr->codeNext - envPtr->codeStart;
- EnterCmdStartData(envPtr, currCmdIndex,
- parsePtr->commandStart - envPtr->source, startCodeOffset);
+ envPtr->numCommands = mapPtr->nuloc;
+ return TCL_ERROR;
+}
- /*
- * Should only start issuing instructions after the "command has
- * started" so that the command range is correct in the bytecode.
- */
+static int
+CompileCommandTokens(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ CompileEnv *envPtr)
+{
+ Interp *iPtr = (Interp *) interp;
+ Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+ ExtCmdLoc *eclPtr = envPtr->extCmdMapPtr;
+ Tcl_Obj *cmdObj = Tcl_NewObj();
+ Command *cmdPtr = NULL;
+ int code = TCL_ERROR;
+ int cmdKnown, expand = -1;
+ int *wlines, wlineat;
+ int cmdLine = envPtr->line;
+ int *clNext = envPtr->clNext;
+ int cmdIdx = envPtr->numCommands;
+ int startCodeOffset = envPtr->codeNext - envPtr->codeStart;
+ int depth = TclGetStackDepth(envPtr);
+
+ assert (parsePtr->numWords > 0);
+
+ /* Pre-Compile */
+
+ envPtr->numCommands++;
+ EnterCmdStartData(envPtr, cmdIdx,
+ parsePtr->commandStart - envPtr->source, startCodeOffset);
- if (expand) {
- TclEmitOpcode(INST_EXPAND_START, envPtr);
- }
+ /*
+ * TIP #280. Scan the words and compute the extended location information.
+ * The map first contain full per-word line information for use by the
+ * compiler. This is later replaced by a reduced form which signals
+ * non-literal words, stored in 'wlines'.
+ */
- /*
- * TIP #280. Scan the words and compute the extended location
- * information. The map first contain full per-word line
- * information for use by the compiler. This is later replaced by
- * a reduced form which signals non-literal words, stored in
- * 'wlines'.
- */
+ EnterCmdWordData(eclPtr, parsePtr->commandStart - envPtr->source,
+ parsePtr->tokenPtr, parsePtr->commandStart,
+ parsePtr->commandSize, parsePtr->numWords, cmdLine,
+ clNext, &wlines, envPtr);
+ wlineat = eclPtr->nuloc - 1;
- EnterCmdWordData(eclPtr, parsePtr->commandStart - envPtr->source,
- parsePtr->tokenPtr, parsePtr->commandStart,
- parsePtr->commandSize, parsePtr->numWords, cmdLine,
- clNext, &wlines, envPtr);
- wlineat = eclPtr->nuloc - 1;
+ envPtr->line = eclPtr->loc[wlineat].line[0];
+ envPtr->clNext = eclPtr->loc[wlineat].next[0];
+ /* Do we know the command word? */
+ Tcl_IncrRefCount(cmdObj);
+ tokenPtr = parsePtr->tokenPtr;
+ cmdKnown = TclWordKnownAtCompileTime(tokenPtr, cmdObj);
+
+ /* Is this a command we should (try to) compile with a compileProc ? */
+ if (cmdKnown && !(iPtr->flags & DONT_COMPILE_CMDS_INLINE)) {
+ cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, cmdObj);
+ if (cmdPtr) {
/*
- * Each iteration of the following loop compiles one word from the
- * command.
+ * Found a command. Test the ways we can be told not to attempt
+ * to compile it.
*/
+ if ((cmdPtr->compileProc == NULL)
+ || (cmdPtr->nsPtr->flags & NS_SUPPRESS_COMPILATION)
+ || (cmdPtr->flags & CMD_HAS_EXEC_TRACES)) {
+ cmdPtr = NULL;
+ }
+ }
+ if (cmdPtr && !(cmdPtr->flags & CMD_COMPILES_EXPANDED)) {
+ expand = ExpandRequested(parsePtr->tokenPtr, parsePtr->numWords);
+ if (expand) {
+ /* We need to expand, but compileProc cannot. */
+ cmdPtr = NULL;
+ }
+ }
+ }
- for (wordIdx = 0, tokenPtr = parsePtr->tokenPtr;
- wordIdx < parsePtr->numWords; wordIdx++,
- tokenPtr += tokenPtr->numComponents + 1) {
+ /* If cmdPtr != NULL, we will try to call cmdPtr->compileProc */
+ if (cmdPtr) {
+ code = CompileCmdCompileProc(interp, parsePtr, cmdPtr, envPtr);
+ }
- envPtr->line = eclPtr->loc[wlineat].line[wordIdx];
- envPtr->clNext = eclPtr->loc[wlineat].next[wordIdx];
- if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- /*
- * The word is not a simple string of characters.
- */
+ if (code == TCL_ERROR) {
+ if (expand < 0) {
+ expand = ExpandRequested(parsePtr->tokenPtr, parsePtr->numWords);
+ }
- TclCompileTokens(interp, tokenPtr+1,
- tokenPtr->numComponents, envPtr);
- if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
- TclEmitInstInt4(INST_EXPAND_STKTOP,
- envPtr->currStackDepth, envPtr);
- }
- continue;
- }
+ if (expand) {
+ CompileExpanded(interp, parsePtr->tokenPtr,
+ cmdKnown ? cmdObj : NULL, parsePtr->numWords, envPtr);
+ } else {
+ TclCompileInvocation(interp, parsePtr->tokenPtr,
+ cmdKnown ? cmdObj : NULL, parsePtr->numWords, envPtr);
+ }
+ }
- /*
- * This is a simple string of literal characters (i.e. we know
- * it absolutely and can use it directly). If this is the
- * first word and the command has a compile procedure, let it
- * compile the command.
- */
+ Tcl_DecrRefCount(cmdObj);
- if ((wordIdx == 0) && !expand) {
- /*
- * We copy the string before trying to find the command by
- * name. We used to modify the string in place, but this
- * is not safe because the name resolution handlers could
- * have side effects that rely on the unmodified string.
- */
+ TclEmitOpcode(INST_POP, envPtr);
+ EnterCmdExtentData(envPtr, cmdIdx,
+ parsePtr->term - parsePtr->commandStart,
+ (envPtr->codeNext-envPtr->codeStart) - startCodeOffset);
- Tcl_DStringSetLength(&ds, 0);
- Tcl_DStringAppend(&ds, tokenPtr[1].start,tokenPtr[1].size);
-
- cmdPtr = (Command *) Tcl_FindCommand(interp,
- Tcl_DStringValue(&ds),
- (Tcl_Namespace *) cmdNsPtr, /*flags*/ 0);
-
- if ((cmdPtr != NULL)
- && (cmdPtr->compileProc != NULL)
- && !(cmdPtr->nsPtr->flags&NS_SUPPRESS_COMPILATION)
- && !(cmdPtr->flags & CMD_HAS_EXEC_TRACES)
- && !(iPtr->flags & DONT_COMPILE_CMDS_INLINE)) {
- int savedNumCmds = envPtr->numCommands;
- unsigned savedCodeNext =
- envPtr->codeNext - envPtr->codeStart;
- int update = 0, code;
-
- /*
- * Mark the start of the command; the proper bytecode
- * length will be updated later. There is no need to
- * do this for the first bytecode in the compile env,
- * as the check is done before calling
- * TclNRExecuteByteCode(). Do emit an INST_START_CMD in
- * special cases where the first bytecode is in a
- * loop, to insure that the corresponding command is
- * counted properly. Compilers for commands able to
- * produce such a beast (currently 'while 1' only) set
- * envPtr->atCmdStart to 0 in order to signal this
- * case. [Bug 1752146]
- *
- * Note that the environment is initialised with
- * atCmdStart=1 to avoid emitting ISC for the first
- * command.
- */
-
- if (envPtr->atCmdStart) {
- if (savedCodeNext != 0) {
- /*
- * Increase the number of commands being
- * started at the current point. Note that
- * this depends on the exact layout of the
- * INST_START_CMD's operands, so be careful!
- */
-
- unsigned char *fixPtr = envPtr->codeNext - 4;
-
- TclStoreInt4AtPtr(TclGetUInt4AtPtr(fixPtr)+1,
- fixPtr);
- }
- } else {
- TclEmitInstInt4(INST_START_CMD, 0, envPtr);
- TclEmitInt4(1, envPtr);
- update = 1;
- }
-
- code = cmdPtr->compileProc(interp, parsePtr, cmdPtr,
- envPtr);
-
- if (code == TCL_OK) {
- if (update) {
- /*
- * Fix the bytecode length.
- */
-
- unsigned char *fixPtr = envPtr->codeStart
- + savedCodeNext + 1;
- unsigned fixLen = envPtr->codeNext
- - envPtr->codeStart - savedCodeNext;
-
- TclStoreInt4AtPtr(fixLen, fixPtr);
- }
- goto finishCommand;
- }
-
- if (envPtr->atCmdStart && savedCodeNext != 0) {
- /*
- * Decrease the number of commands being started
- * at the current point. Note that this depends on
- * the exact layout of the INST_START_CMD's
- * operands, so be careful!
- */
-
- unsigned char *fixPtr = envPtr->codeNext - 4;
-
- TclStoreInt4AtPtr(TclGetUInt4AtPtr(fixPtr)-1,
- fixPtr);
- }
-
- /*
- * Restore numCommands and codeNext to their correct
- * values, removing any commands compiled before the
- * failure to produce bytecode got reported. [Bugs
- * 705406 and 735055]
- */
-
- envPtr->numCommands = savedNumCmds;
- envPtr->codeNext = envPtr->codeStart + savedCodeNext;
- }
+ /*
+ * TIP #280: Free full form of per-word line data and insert the reduced
+ * form now
+ */
- /*
- * No compile procedure so push the word. If the command
- * was found, push a CmdName object to reduce runtime
- * lookups. Mark this as a command name literal to reduce
- * shimmering.
- */
+ envPtr->line = cmdLine;
+ envPtr->clNext = clNext;
+ ckfree(eclPtr->loc[wlineat].line);
+ ckfree(eclPtr->loc[wlineat].next);
+ eclPtr->loc[wlineat].line = wlines;
+ eclPtr->loc[wlineat].next = NULL;
- objIndex = TclRegisterNewCmdLiteral(envPtr,
- tokenPtr[1].start, tokenPtr[1].size);
- if (cmdPtr != NULL) {
- TclSetCmdNameObj(interp,
- envPtr->literalArrayPtr[objIndex].objPtr,
- cmdPtr);
- }
- } else {
- /*
- * Simple argument word of a command. We reach this if and
- * only if the command word was not compiled for whatever
- * reason. Register the literal's location for use by
- * uplevel, etc. commands, should they encounter it
- * unmodified. We care only if the we are in a context
- * which already allows absolute counting.
- */
+ TclCheckStackDepth(depth, envPtr);
+ return cmdIdx;
+}
- objIndex = TclRegisterNewLiteral(envPtr,
- tokenPtr[1].start, tokenPtr[1].size);
+void
+TclCompileScript(
+ Tcl_Interp *interp, /* Used for error and status reporting. Also
+ * serves as context for finding and compiling
+ * commands. May not be NULL. */
+ const char *script, /* The source script to compile. */
+ int numBytes, /* Number of bytes in script. If < 0, the
+ * script consists of all bytes up to the
+ * first null character. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ int lastCmdIdx = -1; /* Index into envPtr->cmdMapPtr of the last
+ * command this routine compiles into bytecode.
+ * Initial value of -1 indicates this routine
+ * has not yet generated any bytecode. */
+ const char *p = script; /* Where we are in our compile. */
+ int depth = TclGetStackDepth(envPtr);
+
+ if (envPtr->iPtr == NULL) {
+ Tcl_Panic("TclCompileScript() called on uninitialized CompileEnv");
+ }
- if (envPtr->clNext) {
- TclContinuationsEnterDerived(
- envPtr->literalArrayPtr[objIndex].objPtr,
- tokenPtr[1].start - envPtr->source,
- eclPtr->loc[wlineat].next[wordIdx]);
- }
- }
- TclEmitPush(objIndex, envPtr);
- } /* for loop */
+ /* Each iteration compiles one command from the script. */
+
+ while (numBytes > 0) {
+ Tcl_Parse parse;
+ const char *next;
+ if (TCL_OK != Tcl_ParseCommand(interp, p, numBytes, 0, &parse)) {
/*
- * Emit an invoke instruction for the command. We skip this if a
- * compile procedure was found for the command.
+ * Compile bytecodes to report the parse error at runtime.
*/
- if (expand) {
- /*
- * The stack depth during argument expansion can only be
- * managed at runtime, as the number of elements in the
- * expanded lists is not known at compile time. We adjust here
- * the stack depth estimate so that it is correct after the
- * command with expanded arguments returns.
- *
- * The end effect of this command's invocation is that all the
- * words of the command are popped from the stack, and the
- * result is pushed: the stack top changes by (1-wordIdx).
- *
- * Note that the estimates are not correct while the command
- * is being prepared and run, INST_EXPAND_STKTOP is not
- * stack-neutral in general.
- */
+ Tcl_LogCommandInfo(interp, script, parse.commandStart,
+ parse.term + 1 - parse.commandStart);
+ TclCompileSyntaxError(interp, envPtr);
+ return;
+ }
- TclEmitOpcode(INST_INVOKE_EXPANDED, envPtr);
- TclAdjustStackDepth((1-wordIdx), envPtr);
- } else if (wordIdx > 0) {
- /*
- * Save PC -> command map for the TclArgumentBC* functions.
- */
+#ifdef TCL_COMPILE_DEBUG
+ /*
+ * If tracing, print a line for each top level command compiled.
+ * TODO: Suppress when numWords == 0 ?
+ */
- int isnew;
- Tcl_HashEntry *hePtr = Tcl_CreateHashEntry(&eclPtr->litInfo,
- INT2PTR(envPtr->codeNext - envPtr->codeStart),
- &isnew);
+ if ((tclTraceCompile >= 1) && (envPtr->procPtr == NULL)) {
+ int commandLength = parse.term - parse.commandStart;
+ fprintf(stdout, " Compiling: ");
+ TclPrintSource(stdout, parse.commandStart,
+ TclMin(commandLength, 55));
+ fprintf(stdout, "\n");
+ }
+#endif
- Tcl_SetHashValue(hePtr, INT2PTR(wlineat));
- if (wordIdx <= 255) {
- TclEmitInstInt1(INST_INVOKE_STK1, wordIdx, envPtr);
- } else {
- TclEmitInstInt4(INST_INVOKE_STK4, wordIdx, envPtr);
- }
- }
+ /*
+ * TIP #280: Count newlines before the command start.
+ * (See test info-30.33).
+ */
- /*
- * Update the compilation environment structure and record the
- * offsets of the source and code for the command.
- */
+ TclAdvanceLines(&envPtr->line, p, parse.commandStart);
+ TclAdvanceContinuations(&envPtr->line, &envPtr->clNext,
+ parse.commandStart - envPtr->source);
- finishCommand:
- EnterCmdExtentData(envPtr, currCmdIndex, commandLength,
- (envPtr->codeNext-envPtr->codeStart) - startCodeOffset);
- isFirstCmd = 0;
+ /*
+ * Advance parser to the next command in the script.
+ */
+
+ next = parse.commandStart + parse.commandSize;
+ numBytes -= next - p;
+ p = next;
+ if (parse.numWords == 0) {
/*
- * TIP #280: Free full form of per-word line data and insert the
- * reduced form now
+ * The "command" parsed has no words. In this case we can skip
+ * the rest of the loop body. With no words, clearly
+ * CompileCommandTokens() has nothing to do. Since the parser
+ * aggressively sucks up leading comment and white space,
+ * including newlines, parse.commandStart must be pointing at
+ * either the end of script, or a command-terminating semi-colon.
+ * In either case, the TclAdvance*() calls have nothing to do.
+ * Finally, when no words are parsed, no tokens have been
+ * allocated at parse.tokenPtr so there's also nothing for
+ * Tcl_FreeParse() to do.
+ *
+ * The advantage of this shortcut is that CompileCommandTokens()
+ * can be written with an assumption that parse.numWords > 0, with
+ * the implication the CCT() always generates bytecode.
*/
+ continue;
+ }
- ckfree(eclPtr->loc[wlineat].line);
- ckfree(eclPtr->loc[wlineat].next);
- eclPtr->loc[wlineat].line = wlines;
- eclPtr->loc[wlineat].next = NULL;
- } /* end if parsePtr->numWords > 0 */
+ lastCmdIdx = CompileCommandTokens(interp, &parse, envPtr);
/*
- * Advance to the next command in the script.
+ * TIP #280: Track lines in the just compiled command.
*/
- next = parsePtr->commandStart + parsePtr->commandSize;
- bytesLeft -= next - p;
- p = next;
+ TclAdvanceLines(&envPtr->line, parse.commandStart, p);
+ TclAdvanceContinuations(&envPtr->line, &envPtr->clNext,
+ p - envPtr->source);
+ Tcl_FreeParse(&parse);
+ }
+ if (lastCmdIdx == -1) {
/*
- * TIP #280: Track lines in the just compiled command.
+ * Compiling the script yielded no bytecode. The script must be all
+ * whitespace, comments, and empty commands. Such scripts are defined
+ * to successfully produce the empty string result, so we emit the
+ * simple bytecode that makes that happen.
*/
- TclAdvanceLines(&cmdLine, parsePtr->commandStart, p);
- TclAdvanceContinuations(&cmdLine, &clNext, p - envPtr->source);
- Tcl_FreeParse(parsePtr);
- } while (bytesLeft > 0);
-
- /*
- * TIP #280: Bring the line counts in the CompEnv up to date.
- * See tests info-30.33,34,35 .
- */
-
- envPtr->line = cmdLine;
- envPtr->clNext = clNext;
-
- /*
- * If the source script yielded no instructions (e.g., if it was empty),
- * push an empty string as the command's result.
- */
+ PushStringLiteral(envPtr, "");
+ } else {
+ /*
+ * We compiled at least one command to bytecode. The routine
+ * CompileCommandTokens() follows the bytecode of each compiled
+ * command with an INST_POP, so that stack balance is maintained when
+ * several commands are in sequence. (The result of each command is
+ * thrown away before moving on to the next command). For the last
+ * command compiled, we need to undo that INST_POP so that the result
+ * of the last command becomes the result of the script. The code
+ * here removes that trailing INST_POP.
+ */
- if (envPtr->codeNext == entryCodeNext) {
- TclEmitPush(TclRegisterNewLiteral(envPtr, "", 0), envPtr);
+ envPtr->cmdMapPtr[lastCmdIdx].numCodeBytes--;
+ envPtr->codeNext--;
+ envPtr->currStackDepth++;
}
-
- envPtr->numSrcBytes = p - script;
- TclStackFree(interp, parsePtr);
- Tcl_DStringFree(&ds);
+ TclCheckStackDepth(depth+1, envPtr);
}
/*
@@ -1946,7 +2300,7 @@ TclCompileVarSubst(
localVar = TclFindCompiledLocal(name, nameBytes, localVarName, envPtr);
}
if (localVar < 0) {
- TclEmitPush(TclRegisterNewLiteral(envPtr, name, nameBytes), envPtr);
+ PushLiteral(envPtr, name, nameBytes);
}
/*
@@ -1958,7 +2312,7 @@ TclCompileVarSubst(
if (tokenPtr->numComponents == 1) {
if (localVar < 0) {
- TclEmitOpcode(INST_LOAD_SCALAR_STK, envPtr);
+ TclEmitOpcode(INST_LOAD_STK, envPtr);
} else if (localVar <= 255) {
TclEmitInstInt1(INST_LOAD_SCALAR1, localVar, envPtr);
} else {
@@ -1988,11 +2342,12 @@ TclCompileTokens(
Tcl_DString textBuffer; /* Holds concatenated chars from adjacent
* TCL_TOKEN_TEXT, TCL_TOKEN_BS tokens. */
char buffer[TCL_UTF_MAX];
- int i, numObjsToConcat, length;
+ int i, numObjsToConcat, length, adjust;
unsigned char *entryCodeNext = envPtr->codeNext;
#define NUM_STATIC_POS 20
int isLiteral, maxNumCL, numCL;
int *clPosition = NULL;
+ int depth = TclGetStackDepth(envPtr);
/*
* For the handling of continuation lines in literals we first check if
@@ -2025,12 +2380,13 @@ TclCompileTokens(
clPosition = ckalloc(maxNumCL * sizeof(int));
}
+ adjust = 0;
Tcl_DStringInit(&textBuffer);
numObjsToConcat = 0;
for ( ; count > 0; count--, tokenPtr++) {
switch (tokenPtr->type) {
case TCL_TOKEN_TEXT:
- Tcl_DStringAppend(&textBuffer, tokenPtr->start, tokenPtr->size);
+ TclDStringAppendToken(&textBuffer, tokenPtr);
TclAdvanceLines(&envPtr->line, tokenPtr->start,
tokenPtr->start + tokenPtr->size);
break;
@@ -2068,6 +2424,7 @@ TclCompileTokens(
clPosition[numCL] = clPos;
numCL ++;
}
+ adjust++;
}
break;
@@ -2077,24 +2434,23 @@ TclCompileTokens(
*/
if (Tcl_DStringLength(&textBuffer) > 0) {
- int literal = TclRegisterNewLiteral(envPtr,
- Tcl_DStringValue(&textBuffer),
- Tcl_DStringLength(&textBuffer));
+ int literal = TclRegisterDStringLiteral(envPtr, &textBuffer);
TclEmitPush(literal, envPtr);
numObjsToConcat++;
Tcl_DStringFree(&textBuffer);
if (numCL) {
- TclContinuationsEnter(
- envPtr->literalArrayPtr[literal].objPtr, numCL,
- clPosition);
+ TclContinuationsEnter(TclFetchLiteral(envPtr, literal),
+ numCL, clPosition);
}
numCL = 0;
}
+ envPtr->line += adjust;
TclCompileScript(interp, tokenPtr->start+1,
tokenPtr->size-2, envPtr);
+ envPtr->line -= adjust;
numObjsToConcat++;
break;
@@ -2106,9 +2462,7 @@ TclCompileTokens(
if (Tcl_DStringLength(&textBuffer) > 0) {
int literal;
- literal = TclRegisterNewLiteral(envPtr,
- Tcl_DStringValue(&textBuffer),
- Tcl_DStringLength(&textBuffer));
+ literal = TclRegisterDStringLiteral(envPtr, &textBuffer);
TclEmitPush(literal, envPtr);
numObjsToConcat++;
Tcl_DStringFree(&textBuffer);
@@ -2131,15 +2485,12 @@ TclCompileTokens(
*/
if (Tcl_DStringLength(&textBuffer) > 0) {
- int literal;
+ int literal = TclRegisterDStringLiteral(envPtr, &textBuffer);
- literal = TclRegisterNewLiteral(envPtr, Tcl_DStringValue(&textBuffer),
- Tcl_DStringLength(&textBuffer));
TclEmitPush(literal, envPtr);
numObjsToConcat++;
-
if (numCL) {
- TclContinuationsEnter(envPtr->literalArrayPtr[literal].objPtr,
+ TclContinuationsEnter(TclFetchLiteral(envPtr, literal),
numCL, clPosition);
}
numCL = 0;
@@ -2150,11 +2501,11 @@ TclCompileTokens(
*/
while (numObjsToConcat > 255) {
- TclEmitInstInt1(INST_CONCAT1, 255, envPtr);
+ TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr);
numObjsToConcat -= 254; /* concat pushes 1 obj, the result */
}
if (numObjsToConcat > 1) {
- TclEmitInstInt1(INST_CONCAT1, numObjsToConcat, envPtr);
+ TclEmitInstInt1(INST_STR_CONCAT1, numObjsToConcat, envPtr);
}
/*
@@ -2162,7 +2513,7 @@ TclCompileTokens(
*/
if (envPtr->codeNext == entryCodeNext) {
- TclEmitPush(TclRegisterNewLiteral(envPtr, "", 0), envPtr);
+ PushStringLiteral(envPtr, "");
}
Tcl_DStringFree(&textBuffer);
@@ -2174,6 +2525,7 @@ TclCompileTokens(
if (maxNumCL) {
ckfree(clPosition);
}
+ TclCheckStackDepth(depth+1, envPtr);
}
/*
@@ -2221,7 +2573,7 @@ TclCompileCmdWord(
*/
TclCompileTokens(interp, tokenPtr, count, envPtr);
- TclEmitOpcode(INST_EVAL_STK, envPtr);
+ TclEmitInvoke(envPtr, INST_EVAL_STK);
}
}
@@ -2277,19 +2629,19 @@ TclCompileExprWords(
wordPtr = tokenPtr;
for (i = 0; i < numWords; i++) {
- TclCompileTokens(interp, wordPtr+1, wordPtr->numComponents, envPtr);
+ CompileTokens(envPtr, wordPtr, interp);
if (i < (numWords - 1)) {
- TclEmitPush(TclRegisterNewLiteral(envPtr, " ", 1), envPtr);
+ PushStringLiteral(envPtr, " ");
}
wordPtr += wordPtr->numComponents + 1;
}
concatItems = 2*numWords - 1;
while (concatItems > 255) {
- TclEmitInstInt1(INST_CONCAT1, 255, envPtr);
+ TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr);
concatItems -= 254;
}
if (concatItems > 1) {
- TclEmitInstInt1(INST_CONCAT1, concatItems, envPtr);
+ TclEmitInstInt1(INST_STR_CONCAT1, concatItems, envPtr);
}
TclEmitOpcode(INST_EXPR_STK, envPtr);
}
@@ -2323,21 +2675,17 @@ TclCompileNoOp(
{
Tcl_Token *tokenPtr;
int i;
- int savedStackDepth = envPtr->currStackDepth;
tokenPtr = parsePtr->tokenPtr;
for (i = 1; i < parsePtr->numWords; i++) {
tokenPtr = tokenPtr + tokenPtr->numComponents + 1;
- envPtr->currStackDepth = savedStackDepth;
if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- TclCompileTokens(interp, tokenPtr+1, tokenPtr->numComponents,
- envPtr);
+ CompileTokens(envPtr, tokenPtr, interp);
TclEmitOpcode(INST_POP, envPtr);
}
}
- envPtr->currStackDepth = savedStackDepth;
- TclEmitPush(TclRegisterNewLiteral(envPtr, "", 0), envPtr);
+ PushStringLiteral(envPtr, "");
return TCL_OK;
}
@@ -2386,6 +2734,10 @@ TclInitByteCodeObj(
int i, isNew;
Interp *iPtr;
+ if (envPtr->iPtr == NULL) {
+ Tcl_Panic("TclInitByteCodeObj() called on uninitialized CompileEnv");
+ }
+
iPtr = envPtr->iPtr;
codeBytes = envPtr->codeNext - envPtr->codeStart;
@@ -2443,18 +2795,28 @@ TclInitByteCodeObj(
p += TCL_ALIGN(codeBytes); /* align object array */
codePtr->objArrayPtr = (Tcl_Obj **) p;
for (i = 0; i < numLitObjects; i++) {
- if (objPtr == envPtr->literalArrayPtr[i].objPtr) {
+ Tcl_Obj *fetched = TclFetchLiteral(envPtr, i);
+
+ if (objPtr == fetched) {
/*
* Prevent circular reference where the bytecode intrep of
* a value contains a literal which is that same value.
* If this is allowed to happen, refcount decrements may not
* reach zero, and memory may leak. Bugs 467523, 3357771
+ *
+ * NOTE: [Bugs 3392070, 3389764] We make a copy based completely
+ * on the string value, and do not call Tcl_DuplicateObj() so we
+ * can be sure we do not have any lingering cycles hiding in
+ * the intrep.
*/
- codePtr->objArrayPtr[i] = Tcl_DuplicateObj(objPtr);
+ int numBytes;
+ const char *bytes = Tcl_GetStringFromObj(objPtr, &numBytes);
+
+ codePtr->objArrayPtr[i] = Tcl_NewStringObj(bytes, numBytes);
Tcl_IncrRefCount(codePtr->objArrayPtr[i]);
- Tcl_DecrRefCount(objPtr);
+ TclReleaseLiteral((Tcl_Interp *)iPtr, objPtr);
} else {
- codePtr->objArrayPtr[i] = envPtr->literalArrayPtr[i].objPtr;
+ codePtr->objArrayPtr[i] = fetched;
}
}
@@ -2503,7 +2865,7 @@ TclInitByteCodeObj(
*/
TclFreeIntRep(objPtr);
- objPtr->internalRep.otherValuePtr = codePtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = codePtr;
objPtr->typePtr = &tclByteCodeType;
/*
@@ -2515,6 +2877,9 @@ TclInitByteCodeObj(
&isNew), envPtr->extCmdMapPtr);
envPtr->extCmdMapPtr = NULL;
+ /* We've used up the CompileEnv. Mark as uninitialized. */
+ envPtr->iPtr = NULL;
+
codePtr->localCachePtr = NULL;
}
@@ -2929,6 +3294,7 @@ TclCreateExceptRange(
* new ExceptionRange structure. */
{
register ExceptionRange *rangePtr;
+ register ExceptionAux *auxPtr;
int index = envPtr->exceptArrayNext;
if (index >= envPtr->exceptArrayEnd) {
@@ -2940,12 +3306,16 @@ TclCreateExceptRange(
size_t currBytes =
envPtr->exceptArrayNext * sizeof(ExceptionRange);
+ size_t currBytes2 = envPtr->exceptArrayNext * sizeof(ExceptionAux);
int newElems = 2*envPtr->exceptArrayEnd;
size_t newBytes = newElems * sizeof(ExceptionRange);
+ size_t newBytes2 = newElems * sizeof(ExceptionAux);
if (envPtr->mallocedExceptArray) {
envPtr->exceptArrayPtr =
ckrealloc(envPtr->exceptArrayPtr, newBytes);
+ envPtr->exceptAuxArrayPtr =
+ ckrealloc(envPtr->exceptAuxArrayPtr, newBytes2);
} else {
/*
* envPtr->exceptArrayPtr isn't a ckalloc'd pointer, so we must
@@ -2953,9 +3323,12 @@ TclCreateExceptRange(
*/
ExceptionRange *newPtr = ckalloc(newBytes);
+ ExceptionAux *newPtr2 = ckalloc(newBytes2);
memcpy(newPtr, envPtr->exceptArrayPtr, currBytes);
+ memcpy(newPtr2, envPtr->exceptAuxArrayPtr, currBytes2);
envPtr->exceptArrayPtr = newPtr;
+ envPtr->exceptAuxArrayPtr = newPtr2;
envPtr->mallocedExceptArray = 1;
}
envPtr->exceptArrayEnd = newElems;
@@ -2970,10 +3343,294 @@ TclCreateExceptRange(
rangePtr->breakOffset = -1;
rangePtr->continueOffset = -1;
rangePtr->catchOffset = -1;
+ auxPtr = &envPtr->exceptAuxArrayPtr[index];
+ auxPtr->supportsContinue = 1;
+ auxPtr->stackDepth = envPtr->currStackDepth;
+ auxPtr->expandTarget = envPtr->expandCount;
+ auxPtr->expandTargetDepth = -1;
+ auxPtr->numBreakTargets = 0;
+ auxPtr->breakTargets = NULL;
+ auxPtr->allocBreakTargets = 0;
+ auxPtr->numContinueTargets = 0;
+ auxPtr->continueTargets = NULL;
+ auxPtr->allocContinueTargets = 0;
return index;
}
/*
+ * ---------------------------------------------------------------------
+ *
+ * TclGetInnermostExceptionRange --
+ *
+ * Returns the innermost exception range that covers the current code
+ * creation point, and (optionally) the stack depth that is expected at
+ * that point. Relies on the fact that the range has a numCodeBytes = -1
+ * when it is being populated and that inner ranges come after outer
+ * ranges.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+ExceptionRange *
+TclGetInnermostExceptionRange(
+ CompileEnv *envPtr,
+ int returnCode,
+ ExceptionAux **auxPtrPtr)
+{
+ int exnIdx = -1, i;
+
+ for (i=0 ; i<envPtr->exceptArrayNext ; i++) {
+ ExceptionRange *rangePtr = &envPtr->exceptArrayPtr[i];
+
+ if (CurrentOffset(envPtr) >= rangePtr->codeOffset &&
+ (rangePtr->numCodeBytes == -1 || CurrentOffset(envPtr) <
+ rangePtr->codeOffset+rangePtr->numCodeBytes) &&
+ (returnCode != TCL_CONTINUE ||
+ envPtr->exceptAuxArrayPtr[i].supportsContinue)) {
+ exnIdx = i;
+ }
+ }
+ if (exnIdx == -1) {
+ return NULL;
+ }
+ if (auxPtrPtr) {
+ *auxPtrPtr = &envPtr->exceptAuxArrayPtr[exnIdx];
+ }
+ return &envPtr->exceptArrayPtr[exnIdx];
+}
+
+/*
+ * ---------------------------------------------------------------------
+ *
+ * TclAddLoopBreakFixup, TclAddLoopContinueFixup --
+ *
+ * Adds a place that wants to break/continue to the loop exception range
+ * tracking that will be fixed up once the loop can be finalized. These
+ * functions will generate an INST_JUMP4 that will be fixed up during the
+ * loop finalization.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+void
+TclAddLoopBreakFixup(
+ CompileEnv *envPtr,
+ ExceptionAux *auxPtr)
+{
+ int range = auxPtr - envPtr->exceptAuxArrayPtr;
+
+ if (envPtr->exceptArrayPtr[range].type != LOOP_EXCEPTION_RANGE) {
+ Tcl_Panic("trying to add 'break' fixup to full exception range");
+ }
+
+ if (++auxPtr->numBreakTargets > auxPtr->allocBreakTargets) {
+ auxPtr->allocBreakTargets *= 2;
+ auxPtr->allocBreakTargets += 2;
+ if (auxPtr->breakTargets) {
+ auxPtr->breakTargets = ckrealloc(auxPtr->breakTargets,
+ sizeof(int) * auxPtr->allocBreakTargets);
+ } else {
+ auxPtr->breakTargets =
+ ckalloc(sizeof(int) * auxPtr->allocBreakTargets);
+ }
+ }
+ auxPtr->breakTargets[auxPtr->numBreakTargets - 1] = CurrentOffset(envPtr);
+ TclEmitInstInt4(INST_JUMP4, 0, envPtr);
+}
+
+void
+TclAddLoopContinueFixup(
+ CompileEnv *envPtr,
+ ExceptionAux *auxPtr)
+{
+ int range = auxPtr - envPtr->exceptAuxArrayPtr;
+
+ if (envPtr->exceptArrayPtr[range].type != LOOP_EXCEPTION_RANGE) {
+ Tcl_Panic("trying to add 'continue' fixup to full exception range");
+ }
+
+ if (++auxPtr->numContinueTargets > auxPtr->allocContinueTargets) {
+ auxPtr->allocContinueTargets *= 2;
+ auxPtr->allocContinueTargets += 2;
+ if (auxPtr->continueTargets) {
+ auxPtr->continueTargets = ckrealloc(auxPtr->continueTargets,
+ sizeof(int) * auxPtr->allocContinueTargets);
+ } else {
+ auxPtr->continueTargets =
+ ckalloc(sizeof(int) * auxPtr->allocContinueTargets);
+ }
+ }
+ auxPtr->continueTargets[auxPtr->numContinueTargets - 1] =
+ CurrentOffset(envPtr);
+ TclEmitInstInt4(INST_JUMP4, 0, envPtr);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ *
+ * TclCleanupStackForBreakContinue --
+ *
+ * Ditch the extra elements from the auxiliary stack and the main stack.
+ * How to do this exactly depends on whether there are any elements on
+ * the auxiliary stack to pop.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+void
+TclCleanupStackForBreakContinue(
+ CompileEnv *envPtr,
+ ExceptionAux *auxPtr)
+{
+ int savedStackDepth = envPtr->currStackDepth;
+ int toPop = envPtr->expandCount - auxPtr->expandTarget;
+
+ if (toPop > 0) {
+ while (toPop --> 0) {
+ TclEmitOpcode(INST_EXPAND_DROP, envPtr);
+ }
+ TclAdjustStackDepth(auxPtr->expandTargetDepth - envPtr->currStackDepth,
+ envPtr);
+ envPtr->currStackDepth = auxPtr->expandTargetDepth;
+ }
+ toPop = envPtr->currStackDepth - auxPtr->stackDepth;
+ while (toPop --> 0) {
+ TclEmitOpcode(INST_POP, envPtr);
+ }
+ envPtr->currStackDepth = savedStackDepth;
+}
+
+/*
+ * ---------------------------------------------------------------------
+ *
+ * StartExpanding --
+ *
+ * Pushes an INST_EXPAND_START and does some additional housekeeping so
+ * that the [break] and [continue] compilers can use an exception-free
+ * issue to discard it.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+static void
+StartExpanding(
+ CompileEnv *envPtr)
+{
+ int i;
+
+ TclEmitOpcode(INST_EXPAND_START, envPtr);
+
+ /*
+ * Update inner exception ranges with information about the environment
+ * where this expansion started.
+ */
+
+ for (i=0 ; i<envPtr->exceptArrayNext ; i++) {
+ ExceptionRange *rangePtr = &envPtr->exceptArrayPtr[i];
+ ExceptionAux *auxPtr = &envPtr->exceptAuxArrayPtr[i];
+
+ /*
+ * Ignore loops unless they're still being built.
+ */
+
+ if (rangePtr->codeOffset > CurrentOffset(envPtr)) {
+ continue;
+ }
+ if (rangePtr->numCodeBytes != -1) {
+ continue;
+ }
+
+ /*
+ * Adequate condition: further out loops and further in exceptions
+ * don't actually need this information.
+ */
+
+ if (auxPtr->expandTarget == envPtr->expandCount) {
+ auxPtr->expandTargetDepth = envPtr->currStackDepth;
+ }
+ }
+
+ /*
+ * There's now one more expansion being processed on the auxiliary stack.
+ */
+
+ envPtr->expandCount++;
+}
+
+/*
+ * ---------------------------------------------------------------------
+ *
+ * TclFinalizeLoopExceptionRange --
+ *
+ * Finalizes a loop exception range, binding the registered [break] and
+ * [continue] implementations so that they jump to the correct place.
+ * Note that this must only be called after *all* the exception range
+ * target offsets have been set.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+void
+TclFinalizeLoopExceptionRange(
+ CompileEnv *envPtr,
+ int range)
+{
+ ExceptionRange *rangePtr = &envPtr->exceptArrayPtr[range];
+ ExceptionAux *auxPtr = &envPtr->exceptAuxArrayPtr[range];
+ int i, offset;
+ unsigned char *site;
+
+ if (rangePtr->type != LOOP_EXCEPTION_RANGE) {
+ Tcl_Panic("trying to finalize a loop exception range");
+ }
+
+ /*
+ * Do the jump fixups. Note that these are always issued as INST_JUMP4 so
+ * there is no need to fuss around with updating code offsets.
+ */
+
+ for (i=0 ; i<auxPtr->numBreakTargets ; i++) {
+ site = envPtr->codeStart + auxPtr->breakTargets[i];
+ offset = rangePtr->breakOffset - auxPtr->breakTargets[i];
+ TclUpdateInstInt4AtPc(INST_JUMP4, offset, site);
+ }
+ for (i=0 ; i<auxPtr->numContinueTargets ; i++) {
+ site = envPtr->codeStart + auxPtr->continueTargets[i];
+ if (rangePtr->continueOffset == -1) {
+ int j;
+
+ /*
+ * WTF? Can't bind, so revert to an INST_CONTINUE. Not enough
+ * space to do anything else.
+ */
+
+ *site = INST_CONTINUE;
+ for (j=0 ; j<4 ; j++) {
+ *++site = INST_NOP;
+ }
+ } else {
+ offset = rangePtr->continueOffset - auxPtr->continueTargets[i];
+ TclUpdateInstInt4AtPc(INST_JUMP4, offset, site);
+ }
+ }
+
+ /*
+ * Drop the arrays we were holding the only reference to.
+ */
+
+ if (auxPtr->breakTargets) {
+ ckfree(auxPtr->breakTargets);
+ auxPtr->breakTargets = NULL;
+ auxPtr->numBreakTargets = 0;
+ }
+ if (auxPtr->continueTargets) {
+ ckfree(auxPtr->continueTargets);
+ auxPtr->continueTargets = NULL;
+ auxPtr->numContinueTargets = 0;
+ }
+}
+
+/*
*----------------------------------------------------------------------
*
* TclCreateAuxData --
@@ -3333,70 +3990,215 @@ TclFixupForwardJump(
}
}
+ for (k = 0 ; k < envPtr->exceptArrayNext ; k++) {
+ ExceptionAux *auxPtr = &envPtr->exceptAuxArrayPtr[k];
+ int i;
+
+ for (i=0 ; i<auxPtr->numBreakTargets ; i++) {
+ if (jumpFixupPtr->codeOffset < auxPtr->breakTargets[i]) {
+ auxPtr->breakTargets[i] += 3;
+ }
+ }
+ for (i=0 ; i<auxPtr->numContinueTargets ; i++) {
+ if (jumpFixupPtr->codeOffset < auxPtr->continueTargets[i]) {
+ auxPtr->continueTargets[i] += 3;
+ }
+ }
+ }
+
+ return 1; /* the jump was grown */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclEmitInvoke --
+ *
+ * Emit one of the invoke-related instructions, wrapping it if necessary
+ * in code that ensures that any break or continue operation passing
+ * through it gets the stack unwinding correct, converting it into an
+ * internal jump if in an appropriate context.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Issues the jump with all correct stack management. May create another
+ * loop exception range; pointers to ExceptionRange and ExceptionAux
+ * structures should not be held across this call.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclEmitInvoke(
+ CompileEnv *envPtr,
+ int opcode,
+ ...)
+{
+ va_list argList;
+ ExceptionRange *rangePtr;
+ ExceptionAux *auxBreakPtr, *auxContinuePtr;
+ int arg1, arg2, wordCount = 0, expandCount = 0;
+ int loopRange = 0, breakRange = 0, continueRange = 0;
+ int cleanup, depth = TclGetStackDepth(envPtr);
+
+ /*
+ * Parse the arguments.
+ */
+
+ va_start(argList, opcode);
+ switch (opcode) {
+ case INST_INVOKE_STK1:
+ wordCount = arg1 = cleanup = va_arg(argList, int);
+ arg2 = 0;
+ break;
+ case INST_INVOKE_STK4:
+ wordCount = arg1 = cleanup = va_arg(argList, int);
+ arg2 = 0;
+ break;
+ case INST_INVOKE_REPLACE:
+ arg1 = va_arg(argList, int);
+ arg2 = va_arg(argList, int);
+ wordCount = arg1 + arg2 - 1;
+ cleanup = arg1 + 1;
+ break;
+ default:
+ Tcl_Panic("unexpected opcode");
+ case INST_EVAL_STK:
+ wordCount = cleanup = 1;
+ arg1 = arg2 = 0;
+ break;
+ case INST_RETURN_STK:
+ wordCount = cleanup = 2;
+ arg1 = arg2 = 0;
+ break;
+ case INST_INVOKE_EXPANDED:
+ wordCount = arg1 = cleanup = va_arg(argList, int);
+ arg2 = 0;
+ expandCount = 1;
+ break;
+ }
+ va_end(argList);
+
/*
- * TIP #280: Adjust the mapping from PC values to the per-command
- * information about arguments and their line numbers.
+ * Determine if we need to handle break and continue exceptions with a
+ * special handling exception range (so that we can correctly unwind the
+ * stack).
*
- * Note: We cannot simply remove an out-of-date entry and then reinsert
- * with the proper PC, because then we might overwrite another entry which
- * was at that location. Therefore we pull (copy + delete) all effected
- * entries (beyond the fixed PC) into an array, update them there, and at
- * last reinsert them all.
+ * These must be done separately; they can be different (especially for
+ * calls from inside a [for] increment clause).
*/
- {
- ExtCmdLoc* eclPtr = envPtr->extCmdMapPtr;
+ rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_BREAK, &auxBreakPtr);
+ if (rangePtr == NULL || rangePtr->type != LOOP_EXCEPTION_RANGE) {
+ auxBreakPtr = NULL;
+ } else if (auxBreakPtr->stackDepth == envPtr->currStackDepth-wordCount
+ && auxBreakPtr->expandTarget == envPtr->expandCount-expandCount) {
+ auxBreakPtr = NULL;
+ } else {
+ breakRange = auxBreakPtr - envPtr->exceptAuxArrayPtr;
+ }
- /* A helper structure */
+ rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_CONTINUE,
+ &auxContinuePtr);
+ if (rangePtr == NULL || rangePtr->type != LOOP_EXCEPTION_RANGE) {
+ auxContinuePtr = NULL;
+ } else if (auxContinuePtr->stackDepth == envPtr->currStackDepth-wordCount
+ && auxContinuePtr->expandTarget == envPtr->expandCount-expandCount) {
+ auxContinuePtr = NULL;
+ } else {
+ continueRange = auxBreakPtr - envPtr->exceptAuxArrayPtr;
+ }
- typedef struct {
- int pc;
- int cmd;
- } MAP;
+ if (auxBreakPtr != NULL || auxContinuePtr != NULL) {
+ loopRange = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
+ ExceptionRangeStarts(envPtr, loopRange);
+ }
- /*
- * And the helper array. At most the whole hashtable is placed into
- * this.
- */
+ /*
+ * Issue the invoke itself.
+ */
+
+ switch (opcode) {
+ case INST_INVOKE_STK1:
+ TclEmitInstInt1(INST_INVOKE_STK1, arg1, envPtr);
+ break;
+ case INST_INVOKE_STK4:
+ TclEmitInstInt4(INST_INVOKE_STK4, arg1, envPtr);
+ break;
+ case INST_INVOKE_EXPANDED:
+ TclEmitOpcode(INST_INVOKE_EXPANDED, envPtr);
+ envPtr->expandCount--;
+ TclAdjustStackDepth(1 - arg1, envPtr);
+ break;
+ case INST_EVAL_STK:
+ TclEmitOpcode(INST_EVAL_STK, envPtr);
+ break;
+ case INST_RETURN_STK:
+ TclEmitOpcode(INST_RETURN_STK, envPtr);
+ break;
+ case INST_INVOKE_REPLACE:
+ TclEmitInstInt4(INST_INVOKE_REPLACE, arg1, envPtr);
+ TclEmitInt1(arg2, envPtr);
+ TclAdjustStackDepth(-1, envPtr); /* Correction to stack depth calcs */
+ break;
+ }
+
+ /*
+ * If we're generating a special wrapper exception range, we need to
+ * finish that up now.
+ */
+
+ if (auxBreakPtr != NULL || auxContinuePtr != NULL) {
+ int savedStackDepth = envPtr->currStackDepth;
+ int savedExpandCount = envPtr->expandCount;
+ JumpFixup nonTrapFixup;
- MAP *map = (MAP*) ckalloc (sizeof(MAP) * eclPtr->litInfo.numEntries);
+ if (auxBreakPtr != NULL) {
+ auxBreakPtr = envPtr->exceptAuxArrayPtr + breakRange;
+ }
+ if (auxContinuePtr != NULL) {
+ auxContinuePtr = envPtr->exceptAuxArrayPtr + continueRange;
+ }
- Tcl_HashSearch hSearch;
- Tcl_HashEntry* hPtr;
- int n, k, isnew;
+ ExceptionRangeEnds(envPtr, loopRange);
+ TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &nonTrapFixup);
/*
- * Phase I: Locate the affected entries, and save them in adjusted
- * form to the array. This removes them from the hash.
+ * Careful! When generating these stack unwinding sequences, the depth
+ * of stack in the cases where they are taken is not the same as if
+ * the exception is not taken.
*/
- for (n = 0, hPtr = Tcl_FirstHashEntry(&eclPtr->litInfo, &hSearch);
- hPtr != NULL;
- hPtr = Tcl_NextHashEntry(&hSearch)) {
+ if (auxBreakPtr != NULL) {
+ TclAdjustStackDepth(-1, envPtr);
- map [n].cmd = PTR2INT(Tcl_GetHashValue(hPtr));
- map [n].pc = PTR2INT(Tcl_GetHashKey (&eclPtr->litInfo,hPtr));
+ ExceptionRangeTarget(envPtr, loopRange, breakOffset);
+ TclCleanupStackForBreakContinue(envPtr, auxBreakPtr);
+ TclAddLoopBreakFixup(envPtr, auxBreakPtr);
+ TclAdjustStackDepth(1, envPtr);
- if (map[n].pc >= (jumpFixupPtr->codeOffset + 2)) {
- Tcl_DeleteHashEntry(hPtr);
- map [n].pc += 3;
- n++;
- }
+ envPtr->currStackDepth = savedStackDepth;
+ envPtr->expandCount = savedExpandCount;
}
- /*
- * Phase II: Re-insert the modified entries into the hash.
- */
+ if (auxContinuePtr != NULL) {
+ TclAdjustStackDepth(-1, envPtr);
- for (k=0;k<n;k++) {
- hPtr = Tcl_CreateHashEntry(&eclPtr->litInfo, INT2PTR(map[k].pc), &isnew);
- Tcl_SetHashValue(hPtr, INT2PTR(map[k].cmd));
+ ExceptionRangeTarget(envPtr, loopRange, continueOffset);
+ TclCleanupStackForBreakContinue(envPtr, auxContinuePtr);
+ TclAddLoopContinueFixup(envPtr, auxContinuePtr);
+ TclAdjustStackDepth(1, envPtr);
+
+ envPtr->currStackDepth = savedStackDepth;
+ envPtr->expandCount = savedExpandCount;
}
- ckfree (map);
+ TclFinalizeLoopExceptionRange(envPtr, loopRange);
+ TclFixupForwardJumpToHere(envPtr, &nonTrapFixup, 127);
}
-
- return 1; /* the jump was grown */
+ TclCheckStackDepth(depth+1-cleanup, envPtr);
}
/*
@@ -3427,7 +4229,7 @@ TclGetInstructionTable(void)
/*
*--------------------------------------------------------------
*
- * TclRegisterAuxDataType --
+ * RegisterAuxDataType --
*
* This procedure is called to register a new AuxData type in the table
* of all AuxData types supported by Tcl.
@@ -3443,8 +4245,8 @@ TclGetInstructionTable(void)
*--------------------------------------------------------------
*/
-void
-TclRegisterAuxDataType(
+static void
+RegisterAuxDataType(
const AuxDataType *typePtr) /* Information about object type; storage must
* be statically allocated (must live forever;
* will not be deallocated). */
@@ -3545,11 +4347,12 @@ TclInitAuxDataTypeTable(void)
Tcl_InitHashTable(&auxDataTypeTable, TCL_STRING_KEYS);
/*
- * There are only two AuxData type at this time, so register them here.
+ * There are only three AuxData types at this time, so register them here.
*/
- TclRegisterAuxDataType(&tclForeachInfoType);
- TclRegisterAuxDataType(&tclJumptableInfoType);
+ RegisterAuxDataType(&tclForeachInfoType);
+ RegisterAuxDataType(&tclJumptableInfoType);
+ RegisterAuxDataType(&tclDictUpdateInfoType);
}
/*
@@ -3921,7 +4724,7 @@ Tcl_Obj *
TclDisassembleByteCodeObj(
Tcl_Obj *objPtr) /* The bytecode object to disassemble. */
{
- ByteCode *codePtr = objPtr->internalRep.otherValuePtr;
+ ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
unsigned char *codeStart, *codeLimit, *pc;
unsigned char *codeDeltaNext, *codeLengthNext;
unsigned char *srcDeltaNext, *srcLengthNext;
@@ -4294,6 +5097,11 @@ FormatInstruction(
}
Tcl_AppendPrintfToObj(bufferObj, "%%v%u ", (unsigned) opnd);
break;
+ case OPERAND_SCLS1:
+ opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++;
+ Tcl_AppendPrintfToObj(bufferObj, "%s ",
+ tclStringClassTable[opnd].name);
+ break;
case OPERAND_NONE:
default:
break;
@@ -4426,7 +5234,11 @@ TclGetInnerContext(
if (!objPtr) {
Tcl_Panic("InnerContext: bad tos -- appending null object");
}
- if (objPtr->refCount<=0 || objPtr->refCount==0x61616161) {
+ if ((objPtr->refCount<=0)
+#ifdef TCL_MEM_DEBUG
+ || (objPtr->refCount==0x61616161)
+#endif
+ ) {
Tcl_Panic("InnerContext: bad tos -- appending freed object %p",
objPtr);
}
@@ -4506,7 +5318,7 @@ PrintSourceToObj(
int maxChars) /* Maximum number of chars to print. */
{
register const char *p;
- register int i = 0;
+ register int i = 0, len;
if (stringPtr == NULL) {
Tcl_AppendToObj(appendObj, "\"\"", -1);
@@ -4515,32 +5327,50 @@ PrintSourceToObj(
Tcl_AppendToObj(appendObj, "\"", -1);
p = stringPtr;
- for (; (*p != '\0') && (i < maxChars); p++, i++) {
- switch (*p) {
+ for (; (*p != '\0') && (i < maxChars); p+=len) {
+ Tcl_UniChar ch;
+
+ len = TclUtfToUniChar(p, &ch);
+ switch (ch) {
case '"':
Tcl_AppendToObj(appendObj, "\\\"", -1);
+ i += 2;
continue;
case '\f':
Tcl_AppendToObj(appendObj, "\\f", -1);
+ i += 2;
continue;
case '\n':
Tcl_AppendToObj(appendObj, "\\n", -1);
+ i += 2;
continue;
case '\r':
Tcl_AppendToObj(appendObj, "\\r", -1);
+ i += 2;
continue;
case '\t':
Tcl_AppendToObj(appendObj, "\\t", -1);
+ i += 2;
continue;
case '\v':
Tcl_AppendToObj(appendObj, "\\v", -1);
+ i += 2;
continue;
default:
- Tcl_AppendPrintfToObj(appendObj, "%c", *p);
+ if (ch < 0x20 || ch >= 0x7f) {
+ Tcl_AppendPrintfToObj(appendObj, "\\u%04x", ch);
+ i += 6;
+ } else {
+ Tcl_AppendPrintfToObj(appendObj, "%c", ch);
+ i++;
+ }
continue;
}
}
Tcl_AppendToObj(appendObj, "\"", -1);
+ if (*p != '\0') {
+ Tcl_AppendToObj(appendObj, "...", -1);
+ }
}
#ifdef TCL_COMPILE_STATS
@@ -4570,12 +5400,13 @@ RecordByteCodeStats(
* to add to accumulated statistics. */
{
Interp *iPtr = (Interp *) *codePtr->interpHandle;
- register ByteCodeStats *statsPtr = &iPtr->stats;
+ register ByteCodeStats *statsPtr;
if (iPtr == NULL) {
/* Avoid segfaulting in case we're called in a deleted interp */
return;
}
+ statsPtr = &(iPtr->stats);
statsPtr->numCompilations++;
statsPtr->totalSrcBytes += (double) codePtr->numSrcBytes;
@@ -4603,6 +5434,5 @@ RecordByteCodeStats(
* c-basic-offset: 4
* fill-column: 78
* tab-width: 8
- * indent-tabs-mode: nil
* End:
*/
diff --git a/generic/tclCompile.h b/generic/tclCompile.h
index 45d50ea..5665ca9 100644
--- a/generic/tclCompile.h
+++ b/generic/tclCompile.h
@@ -100,6 +100,54 @@ typedef struct ExceptionRange {
} ExceptionRange;
/*
+ * Auxiliary data used when issuing (currently just loop) exception ranges,
+ * but which is not required during execution.
+ */
+
+typedef struct ExceptionAux {
+ int supportsContinue; /* Whether this exception range will have a
+ * continueOffset created for it; if it is a
+ * loop exception range that *doesn't* have
+ * one (see [for] next-clause) then we must
+ * not pick up the range when scanning for a
+ * target to continue to. */
+ int stackDepth; /* The stack depth at the point where the
+ * exception range was created. This is used
+ * to calculate the number of POPs required to
+ * restore the stack to its prior state. */
+ int expandTarget; /* The number of expansions expected on the
+ * auxData stack at the time the loop starts;
+ * we can't currently discard them except by
+ * doing INST_INVOKE_EXPANDED; this is a known
+ * problem. */
+ int expandTargetDepth; /* The stack depth expected at the outermost
+ * expansion within the loop. Not meaningful
+ * if there are no open expansions between the
+ * looping level and the point of jump
+ * issue. */
+ int numBreakTargets; /* The number of [break]s that want to be
+ * targeted to the place where this loop
+ * exception will be bound to. */
+ int *breakTargets; /* The offsets of the INST_JUMP4 instructions
+ * issued by the [break]s that we must
+ * update. Note that resizing a jump (via
+ * TclFixupForwardJump) can cause the contents
+ * of this array to be updated. When
+ * numBreakTargets==0, this is NULL. */
+ int allocBreakTargets; /* The size of the breakTargets array. */
+ int numContinueTargets; /* The number of [continue]s that want to be
+ * targeted to the place where this loop
+ * exception will be bound to. */
+ int *continueTargets; /* The offsets of the INST_JUMP4 instructions
+ * issued by the [continue]s that we must
+ * update. Note that resizing a jump (via
+ * TclFixupForwardJump) can cause the contents
+ * of this array to be updated. When
+ * numContinueTargets==0, this is NULL. */
+ int allocContinueTargets; /* The size of the continueTargets array. */
+} ExceptionAux;
+
+/*
* Structure used to map between instruction pc and source locations. It
* defines for each compiled Tcl command its code's starting offset and its
* source's starting offset and length. Note that the code offset increases
@@ -145,13 +193,6 @@ typedef struct ExtCmdLoc {
ECL *loc; /* Command word locations (lines). */
int nloc; /* Number of allocated entries in 'loc'. */
int nuloc; /* Number of used entries in 'loc'. */
- Tcl_HashTable litInfo; /* Indexed by bytecode 'PC', to have the
- * information accessible per command and
- * argument, not per whole bytecode. Value is
- * index of command in 'loc', giving us the
- * literals to associate with line information
- * as command argument, see
- * TclArgumentBCEnter() */
} ExtCmdLoc;
/*
@@ -275,6 +316,11 @@ typedef struct CompileEnv {
* entry. */
int mallocedExceptArray; /* 1 if ExceptionRange array was expanded and
* exceptArrayPtr points in heap, else 0. */
+ ExceptionAux *exceptAuxArrayPtr;
+ /* Array of information used to restore the
+ * state when processing BREAK/CONTINUE
+ * exceptions. Must be the same size as the
+ * exceptArrayPtr. */
CmdLocation *cmdMapPtr; /* Points to start of CmdLocation array.
* numCommands is the index of the next entry
* to use; (numCommands-1) is the entry index
@@ -296,6 +342,9 @@ typedef struct CompileEnv {
/* Initial storage of LiteralEntry array. */
ExceptionRange staticExceptArraySpace[COMPILEENV_INIT_EXCEPT_RANGES];
/* Initial ExceptionRange array storage. */
+ ExceptionAux staticExAuxArraySpace[COMPILEENV_INIT_EXCEPT_RANGES];
+ /* Initial static except auxiliary info array
+ * storage. */
CmdLocation staticCmdMapSpace[COMPILEENV_INIT_CMD_MAP_SIZE];
/* Initial storage for cmd location map. */
AuxData staticAuxDataArraySpace[COMPILEENV_INIT_AUX_DATA_SIZE];
@@ -309,11 +358,13 @@ typedef struct CompileEnv {
int atCmdStart; /* Flag to say whether an INST_START_CMD
* should be issued; they should never be
* issued repeatedly, as that is significantly
- * inefficient. */
- ContLineLoc *clLoc; /* If not NULL, the table holding the
- * locations of the invisible continuation
- * lines in the input script, to adjust the
- * line counter. */
+ * inefficient. If set to 2, that instruction
+ * should not be issued at all (by the generic
+ * part of the command compiler). */
+ int expandCount; /* Number of INST_EXPAND_START instructions
+ * encountered that have not yet been paired
+ * with a corresponding
+ * INST_INVOKE_EXPANDED. */
int *clNext; /* If not NULL, it refers to the next slot in
* clLoc to check for an invisible
* continuation line. */
@@ -461,7 +512,7 @@ typedef struct ByteCode {
#define INST_PUSH4 2
#define INST_POP 3
#define INST_DUP 4
-#define INST_CONCAT1 5
+#define INST_STR_CONCAT1 5
#define INST_INVOKE_STK1 6
#define INST_INVOKE_STK4 7
#define INST_EVAL_STK 8
@@ -535,8 +586,8 @@ typedef struct ByteCode {
#define INST_CONTINUE 66
/* Opcodes 67 to 68 */
-#define INST_FOREACH_START4 67
-#define INST_FOREACH_STEP4 68
+#define INST_FOREACH_START4 67 /* DEPRECATED */
+#define INST_FOREACH_STEP4 68 /* DEPRECATED */
/* Opcodes 69 to 72 */
#define INST_BEGIN_CATCH4 69
@@ -676,8 +727,80 @@ typedef struct ByteCode {
#define INST_UNSET_ARRAY_STK 136
#define INST_UNSET_STK 137
+/* For [dict with], [dict exists], [dict create] and [dict merge] */
+#define INST_DICT_EXPAND 138
+#define INST_DICT_RECOMBINE_STK 139
+#define INST_DICT_RECOMBINE_IMM 140
+#define INST_DICT_EXISTS 141
+#define INST_DICT_VERIFY 142
+
+/* For [string map] and [regsub] compilation */
+#define INST_STR_MAP 143
+#define INST_STR_FIND 144
+#define INST_STR_FIND_LAST 145
+#define INST_STR_RANGE_IMM 146
+#define INST_STR_RANGE 147
+
+/* For operations to do with coroutines and other NRE-manipulators */
+#define INST_YIELD 148
+#define INST_COROUTINE_NAME 149
+#define INST_TAILCALL 150
+
+/* For compilation of basic information operations */
+#define INST_NS_CURRENT 151
+#define INST_INFO_LEVEL_NUM 152
+#define INST_INFO_LEVEL_ARGS 153
+#define INST_RESOLVE_COMMAND 154
+
+/* For compilation relating to TclOO */
+#define INST_TCLOO_SELF 155
+#define INST_TCLOO_CLASS 156
+#define INST_TCLOO_NS 157
+#define INST_TCLOO_IS_OBJECT 158
+
+/* For compilation of [array] subcommands */
+#define INST_ARRAY_EXISTS_STK 159
+#define INST_ARRAY_EXISTS_IMM 160
+#define INST_ARRAY_MAKE_STK 161
+#define INST_ARRAY_MAKE_IMM 162
+
+#define INST_INVOKE_REPLACE 163
+
+#define INST_LIST_CONCAT 164
+
+#define INST_EXPAND_DROP 165
+
+/* New foreach implementation */
+#define INST_FOREACH_START 166
+#define INST_FOREACH_STEP 167
+#define INST_FOREACH_END 168
+#define INST_LMAP_COLLECT 169
+
+/* For compilation of [string trim] and related */
+#define INST_STR_TRIM 170
+#define INST_STR_TRIM_LEFT 171
+#define INST_STR_TRIM_RIGHT 172
+
+#define INST_CONCAT_STK 173
+
+#define INST_STR_UPPER 174
+#define INST_STR_LOWER 175
+#define INST_STR_TITLE 176
+#define INST_STR_REPLACE 177
+
+#define INST_ORIGIN_COMMAND 178
+
+#define INST_TCLOO_NEXT 179
+#define INST_TCLOO_NEXT_CLASS 180
+
+#define INST_YIELD_TO_INVOKE 181
+
+#define INST_NUM_TYPE 182
+#define INST_TRY_CVT_TO_BOOLEAN 183
+#define INST_STR_CLASS 184
+
/* The last opcode */
-#define LAST_INST_OPCODE 137
+#define LAST_INST_OPCODE 184
/*
* Table describing the Tcl bytecode instructions: their name (for displaying
@@ -702,8 +825,9 @@ typedef enum InstOperandType {
* variable table. */
OPERAND_LVT4, /* Four byte unsigned index into the local
* variable table. */
- OPERAND_AUX4 /* Four byte unsigned index into the aux data
+ OPERAND_AUX4, /* Four byte unsigned index into the aux data
* table. */
+ OPERAND_SCLS1 /* Index into tclStringClassTable. */
} InstOperandType;
typedef struct InstructionDesc {
@@ -722,6 +846,40 @@ typedef struct InstructionDesc {
MODULE_SCOPE InstructionDesc const tclInstructionTable[];
/*
+ * Constants used by INST_STRING_CLASS to indicate character classes. These
+ * correspond closely by name with what [string is] can support, but there is
+ * no requirement to keep the values the same.
+ */
+
+typedef enum InstStringClassType {
+ STR_CLASS_ALNUM, /* Unicode alphabet or digit characters. */
+ STR_CLASS_ALPHA, /* Unicode alphabet characters. */
+ STR_CLASS_ASCII, /* Characters in range U+000000..U+00007F. */
+ STR_CLASS_CONTROL, /* Unicode control characters. */
+ STR_CLASS_DIGIT, /* Unicode digit characters. */
+ STR_CLASS_GRAPH, /* Unicode printing characters, excluding
+ * space. */
+ STR_CLASS_LOWER, /* Unicode lower-case alphabet characters. */
+ STR_CLASS_PRINT, /* Unicode printing characters, including
+ * spaces. */
+ STR_CLASS_PUNCT, /* Unicode punctuation characters. */
+ STR_CLASS_SPACE, /* Unicode space characters. */
+ STR_CLASS_UPPER, /* Unicode upper-case alphabet characters. */
+ STR_CLASS_WORD, /* Unicode word (alphabetic, digit, connector
+ * punctuation) characters. */
+ STR_CLASS_XDIGIT /* Characters that can be used as digits in
+ * hexadecimal numbers ([0-9A-Fa-f]). */
+} InstStringClassType;
+
+typedef struct StringClassDesc {
+ const char *name; /* Name of the class. */
+ int (*comparator)(int); /* Function to test if a single unicode
+ * character is a member of the class. */
+} StringClassDesc;
+
+MODULE_SCOPE StringClassDesc const tclStringClassTable[];
+
+/*
* Compilation of some Tcl constructs such as if commands and the logical or
* (||) and logical and (&&) operators in expressions requires the generation
* of forward jumps. Since the PC target of these jumps isn't known when the
@@ -810,6 +968,10 @@ typedef struct ForeachInfo {
} ForeachInfo;
MODULE_SCOPE const AuxDataType tclForeachInfoType;
+MODULE_SCOPE const AuxDataType tclNewForeachInfoType;
+
+#define FOREACHINFO(envPtr, index) \
+ ((ForeachInfo*)((envPtr)->auxDataArrayPtr[TclGetUInt4AtPtr(index)].clientData))
/*
* Structure used to hold information about a switch command that is needed
@@ -824,6 +986,9 @@ typedef struct JumptableInfo {
MODULE_SCOPE const AuxDataType tclJumptableInfoType;
+#define JUMPTABLEINFO(envPtr, index) \
+ ((JumptableInfo*)((envPtr)->auxDataArrayPtr[TclGetUInt4AtPtr(index)].clientData))
+
/*
* Structure used to hold information about a [dict update] command that is
* needed during program execution. These structures are stored in CompileEnv
@@ -842,6 +1007,9 @@ typedef struct {
MODULE_SCOPE const AuxDataType tclDictUpdateInfoType;
+#define DICTUPDATEINFO(envPtr, index) \
+ ((DictUpdateInfo*)((envPtr)->auxDataArrayPtr[TclGetUInt4AtPtr(index)].clientData))
+
/*
* ClientData type used by the math operator commands.
*/
@@ -861,8 +1029,7 @@ typedef struct {
*----------------------------------------------------------------
*/
-MODULE_SCOPE Tcl_NRPostProc NRCommand;
-MODULE_SCOPE Tcl_ObjCmdProc NRInterpCoroutine;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRInterpCoroutine;
/*
*----------------------------------------------------------------
@@ -880,7 +1047,12 @@ MODULE_SCOPE ByteCode * TclCompileObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
*----------------------------------------------------------------
*/
+MODULE_SCOPE int TclAttemptCompileProc(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, int depth, Command *cmdPtr,
+ CompileEnv *envPtr);
MODULE_SCOPE void TclCleanupByteCode(ByteCode *codePtr);
+MODULE_SCOPE void TclCleanupStackForBreakContinue(CompileEnv *envPtr,
+ ExceptionAux *auxPtr);
MODULE_SCOPE void TclCompileCmdWord(Tcl_Interp *interp,
Tcl_Token *tokenPtr, int count,
CompileEnv *envPtr);
@@ -889,6 +1061,9 @@ MODULE_SCOPE void TclCompileExpr(Tcl_Interp *interp, const char *script,
MODULE_SCOPE void TclCompileExprWords(Tcl_Interp *interp,
Tcl_Token *tokenPtr, int numWords,
CompileEnv *envPtr);
+MODULE_SCOPE void TclCompileInvocation(Tcl_Interp *interp,
+ Tcl_Token *tokenPtr, Tcl_Obj *cmdObj, int numWords,
+ CompileEnv *envPtr);
MODULE_SCOPE void TclCompileScript(Tcl_Interp *interp,
const char *script, int numBytes,
CompileEnv *envPtr);
@@ -913,16 +1088,16 @@ MODULE_SCOPE void TclDeleteLiteralTable(Tcl_Interp *interp,
LiteralTable *tablePtr);
MODULE_SCOPE void TclEmitForwardJump(CompileEnv *envPtr,
TclJumpType jumpType, JumpFixup *jumpFixupPtr);
+MODULE_SCOPE void TclEmitInvoke(CompileEnv *envPtr, int opcode, ...);
MODULE_SCOPE ExceptionRange * TclGetExceptionRangeForPc(unsigned char *pc,
int catchOnly, ByteCode *codePtr);
MODULE_SCOPE void TclExpandJumpFixupArray(JumpFixupArray *fixupArrayPtr);
MODULE_SCOPE int TclNRExecuteByteCode(Tcl_Interp *interp,
ByteCode *codePtr);
+MODULE_SCOPE Tcl_Obj * TclFetchLiteral(CompileEnv *envPtr, unsigned int index);
MODULE_SCOPE void TclFinalizeAuxDataTypeTable(void);
MODULE_SCOPE int TclFindCompiledLocal(const char *name, int nameChars,
int create, CompileEnv *envPtr);
-MODULE_SCOPE LiteralEntry * TclLookupLiteralEntry(Tcl_Interp *interp,
- Tcl_Obj *objPtr);
MODULE_SCOPE int TclFixupForwardJump(CompileEnv *envPtr,
JumpFixup *jumpFixupPtr, int jumpDist,
int distThreshold);
@@ -931,16 +1106,24 @@ MODULE_SCOPE void TclFreeJumpFixupArray(JumpFixupArray *fixupArrayPtr);
MODULE_SCOPE void TclInitAuxDataTypeTable(void);
MODULE_SCOPE void TclInitByteCodeObj(Tcl_Obj *objPtr,
CompileEnv *envPtr);
-MODULE_SCOPE void TclInitCompilation(void);
MODULE_SCOPE void TclInitCompileEnv(Tcl_Interp *interp,
CompileEnv *envPtr, const char *string,
int numBytes, const CmdFrame *invoker, int word);
MODULE_SCOPE void TclInitJumpFixupArray(JumpFixupArray *fixupArrayPtr);
MODULE_SCOPE void TclInitLiteralTable(LiteralTable *tablePtr);
+MODULE_SCOPE ExceptionRange *TclGetInnermostExceptionRange(CompileEnv *envPtr,
+ int returnCode, ExceptionAux **auxPtrPtr);
+MODULE_SCOPE void TclAddLoopBreakFixup(CompileEnv *envPtr,
+ ExceptionAux *auxPtr);
+MODULE_SCOPE void TclAddLoopContinueFixup(CompileEnv *envPtr,
+ ExceptionAux *auxPtr);
+MODULE_SCOPE void TclFinalizeLoopExceptionRange(CompileEnv *envPtr,
+ int range);
#ifdef TCL_COMPILE_STATS
MODULE_SCOPE char * TclLiteralStats(LiteralTable *tablePtr);
MODULE_SCOPE int TclLog2(int value);
#endif
+MODULE_SCOPE void TclOptimizeBytecode(void *envPtr);
#ifdef TCL_COMPILE_DEBUG
MODULE_SCOPE void TclPrintByteCodeObj(Tcl_Interp *interp,
Tcl_Obj *objPtr);
@@ -951,10 +1134,13 @@ MODULE_SCOPE void TclPrintObject(FILE *outFile,
Tcl_Obj *objPtr, int maxChars);
MODULE_SCOPE void TclPrintSource(FILE *outFile,
const char *string, int maxChars);
-MODULE_SCOPE void TclRegisterAuxDataType(const AuxDataType *typePtr);
-MODULE_SCOPE int TclRegisterLiteral(CompileEnv *envPtr,
- char *bytes, int length, int flags);
+MODULE_SCOPE void TclPushVarName(Tcl_Interp *interp,
+ Tcl_Token *varTokenPtr, CompileEnv *envPtr,
+ int flags, int *localIndexPtr,
+ int *isScalarPtr);
MODULE_SCOPE void TclReleaseLiteral(Tcl_Interp *interp, Tcl_Obj *objPtr);
+MODULE_SCOPE void TclInvalidateCmdLiteral(Tcl_Interp *interp,
+ const char *name, Namespace *nsPtr);
MODULE_SCOPE int TclSingleOpCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
@@ -989,6 +1175,15 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
*----------------------------------------------------------------
*/
+/*
+ * Simplified form to access AuxData.
+ *
+ * ClientData TclFetchAuxData(CompileEng *envPtr, int index);
+ */
+
+#define TclFetchAuxData(envPtr, index) \
+ (envPtr)->auxDataArrayPtr[(index)].clientData
+
#define LITERAL_ON_HEAP 0x01
#define LITERAL_CMD_NAME 0x02
@@ -1033,6 +1228,21 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
(envPtr)->currStackDepth += (delta); \
} while (0)
+#define TclGetStackDepth(envPtr) \
+ ((envPtr)->currStackDepth)
+
+#define TclSetStackDepth(depth, envPtr) \
+ (envPtr)->currStackDepth = (depth)
+
+#define TclCheckStackDepth(depth, envPtr) \
+ do { \
+ int dd = (depth); \
+ if (dd != (envPtr)->currStackDepth) { \
+ Tcl_Panic("bad stack depth computations: is %i, should be %i", \
+ (envPtr)->currStackDepth, dd); \
+ } \
+ } while (0)
+
/*
* Macro used to update the stack requirements. It is called by the macros
* TclEmitOpCode, TclEmitInst1 and TclEmitInst4.
@@ -1055,6 +1265,18 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
} while (0)
/*
+ * Macros used to update the flag that indicates if we are at the start of a
+ * command, based on whether the opcode is INST_START_COMMAND.
+ *
+ * void TclUpdateAtCmdStart(unsigned char op, CompileEnv *envPtr);
+ */
+
+#define TclUpdateAtCmdStart(op, envPtr) \
+ if ((envPtr)->atCmdStart < 2) { \
+ (envPtr)->atCmdStart = ((op) == INST_START_CMD ? 1 : 0); \
+ }
+
+/*
* Macro to emit an opcode byte into a CompileEnv's code array. The ANSI C
* "prototype" for this macro is:
*
@@ -1067,7 +1289,7 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
TclExpandCodeArray(envPtr); \
} \
*(envPtr)->codeNext++ = (unsigned char) (op); \
- (envPtr)->atCmdStart = ((op) == INST_START_CMD); \
+ TclUpdateAtCmdStart(op, envPtr); \
TclUpdateStackReqs(op, 0, envPtr); \
} while (0)
@@ -1119,7 +1341,7 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
} \
*(envPtr)->codeNext++ = (unsigned char) (op); \
*(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i)); \
- (envPtr)->atCmdStart = ((op) == INST_START_CMD); \
+ TclUpdateAtCmdStart(op, envPtr); \
TclUpdateStackReqs(op, i, envPtr); \
} while (0)
@@ -1137,7 +1359,7 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
(unsigned char) ((unsigned int) (i) >> 8); \
*(envPtr)->codeNext++ = \
(unsigned char) ((unsigned int) (i) ); \
- (envPtr)->atCmdStart = ((op) == INST_START_CMD); \
+ TclUpdateAtCmdStart(op, envPtr); \
TclUpdateStackReqs(op, i, envPtr); \
} while (0)
@@ -1161,6 +1383,18 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
} while (0)
/*
+ * If the expr compiler finished with TRY_CONVERT, macro to remove it when the
+ * job is done by the following instruction.
+ */
+
+#define TclClearNumConversion(envPtr) \
+ do { \
+ if (*(envPtr->codeNext - 1) == INST_TRY_CVT_TO_NUMERIC) { \
+ envPtr->codeNext--; \
+ } \
+ } while (0)
+
+/*
* Macros to update a (signed or unsigned) integer starting at a pointer. The
* two variants depend on the number of bytes. The ANSI C "prototypes" for
* these macros are:
@@ -1270,16 +1504,16 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
#define TclMax(i, j) ((((int) i) > ((int) j))? (i) : (j))
/*
- * Convenience macro for use when compiling bodies of commands. The ANSI C
- * "prototype" for this macro is:
+ * Convenience macros for use when compiling bodies of commands. The ANSI C
+ * "prototype" for these macros are:
*
- * static void CompileBody(CompileEnv *envPtr, Tcl_Token *tokenPtr,
- * Tcl_Interp *interp);
+ * static void BODY(Tcl_Token *tokenPtr, int word);
*/
-#define CompileBody(envPtr, tokenPtr, interp) \
- TclCompileCmdWord((interp), (tokenPtr)+1, (tokenPtr)->numComponents, \
- (envPtr))
+#define BODY(tokenPtr, word) \
+ SetLineInformation((word)); \
+ TclCompileCmdWord(interp, (tokenPtr)+1, (tokenPtr)->numComponents, \
+ envPtr)
/*
* Convenience macro for use when compiling tokens to be pushed. The ANSI C
@@ -1293,15 +1527,19 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
TclCompileTokens((interp), (tokenPtr)+1, (tokenPtr)->numComponents, \
(envPtr));
/*
- * Convenience macro for use when pushing literals. The ANSI C "prototype" for
- * this macro is:
+ * Convenience macros for use when pushing literals. The ANSI C "prototype" for
+ * these macros are:
*
* static void PushLiteral(CompileEnv *envPtr,
* const char *string, int length);
+ * static void PushStringLiteral(CompileEnv *envPtr,
+ * const char *string);
*/
#define PushLiteral(envPtr, string, length) \
TclEmitPush(TclRegisterNewLiteral((envPtr), (string), (length)), (envPtr))
+#define PushStringLiteral(envPtr, string) \
+ PushLiteral((envPtr), (string), (int) (sizeof(string "") - 1))
/*
* Macro to advance to the next token; it is more mnemonic than the address
@@ -1330,14 +1568,11 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
* of LOOP ranges is an interesting datum for debugging purposes, and that is
* what we compute now.
*
- * static int DeclareExceptionRange(CompileEnv *envPtr, int type);
* static int ExceptionRangeStarts(CompileEnv *envPtr, int index);
* static void ExceptionRangeEnds(CompileEnv *envPtr, int index);
* static void ExceptionRangeTarget(CompileEnv *envPtr, int index, LABEL);
*/
-#define DeclareExceptionRange(envPtr, type) \
- (TclCreateExceptRange((type), (envPtr)))
#define ExceptionRangeStarts(envPtr, index) \
(((envPtr)->exceptDepth++), \
((envPtr)->maxExceptDepth = \
@@ -1358,6 +1593,86 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
(envPtr->procPtr || envPtr->iPtr->varFramePtr->localCachePtr)
/*
+ * Macros for making it easier to deal with tokens and DStrings.
+ */
+
+#define TclDStringAppendToken(dsPtr, tokenPtr) \
+ Tcl_DStringAppend((dsPtr), (tokenPtr)->start, (tokenPtr)->size)
+#define TclRegisterDStringLiteral(envPtr, dsPtr) \
+ TclRegisterLiteral(envPtr, Tcl_DStringValue(dsPtr), \
+ Tcl_DStringLength(dsPtr), /*flags*/ 0)
+
+/*
+ * Macro that encapsulates an efficiency trick that avoids a function call for
+ * the simplest of compiles. The ANSI C "prototype" for this macro is:
+ *
+ * static void CompileWord(CompileEnv *envPtr, Tcl_Token *tokenPtr,
+ * Tcl_Interp *interp, int word);
+ */
+
+#define CompileWord(envPtr, tokenPtr, interp, word) \
+ if ((tokenPtr)->type == TCL_TOKEN_SIMPLE_WORD) { \
+ PushLiteral((envPtr), (tokenPtr)[1].start, (tokenPtr)[1].size); \
+ } else { \
+ SetLineInformation((word)); \
+ CompileTokens((envPtr), (tokenPtr), (interp)); \
+ }
+
+/*
+ * TIP #280: Remember the per-word line information of the current command. An
+ * index is used instead of a pointer as recursive compilation may reallocate,
+ * i.e. move, the array. This is also the reason to save the nuloc now, it may
+ * change during the course of the function.
+ *
+ * Macro to encapsulate the variable definition and setup.
+ */
+
+#define DefineLineInformation \
+ ExtCmdLoc *mapPtr = envPtr->extCmdMapPtr; \
+ int eclIndex = mapPtr->nuloc - 1
+
+#define SetLineInformation(word) \
+ envPtr->line = mapPtr->loc[eclIndex].line[(word)]; \
+ envPtr->clNext = mapPtr->loc[eclIndex].next[(word)]
+
+#define PushVarNameWord(i,v,e,f,l,sc,word) \
+ SetLineInformation(word); \
+ TclPushVarName(i,v,e,f,l,sc)
+
+/*
+ * Often want to issue one of two versions of an instruction based on whether
+ * the argument will fit in a single byte or not. This makes it much clearer.
+ */
+
+#define Emit14Inst(nm,idx,envPtr) \
+ if (idx <= 255) { \
+ TclEmitInstInt1(nm##1,idx,envPtr); \
+ } else { \
+ TclEmitInstInt4(nm##4,idx,envPtr); \
+ }
+
+/*
+ * How to get an anonymous local variable (used for holding temporary values
+ * off the stack) or a local simple scalar.
+ */
+
+#define AnonymousLocal(envPtr) \
+ (TclFindCompiledLocal(NULL, /*nameChars*/ 0, /*create*/ 1, (envPtr)))
+#define LocalScalar(chars,len,envPtr) \
+ (!TclIsLocalScalar((chars), (len)) ? -1 : \
+ TclFindCompiledLocal((chars), (len), /*create*/ 1, (envPtr)))
+#define LocalScalarFromToken(tokenPtr,envPtr) \
+ ((tokenPtr)->type != TCL_TOKEN_SIMPLE_WORD ? -1 : \
+ LocalScalar((tokenPtr)[1].start, (tokenPtr)[1].size, (envPtr)))
+
+/*
+ * Flags bits used by TclPushVarName.
+ */
+
+#define TCL_NO_LARGE_INDEX 1 /* Do not return localIndex value > 255 */
+#define TCL_NO_ELEMENT 2 /* Do not push the array element. */
+
+/*
* DTrace probe macros (NOPs if DTrace support is not enabled).
*/
diff --git a/generic/tclConfig.c b/generic/tclConfig.c
index b4735e8..2fb3e92 100644
--- a/generic/tclConfig.c
+++ b/generic/tclConfig.c
@@ -26,14 +26,15 @@
#define ASSOC_KEY "tclPackageAboutDict"
/*
- * A ClientData struct for the QueryConfig command. Store the two bits
+ * A ClientData struct for the QueryConfig command. Store the three bits
* of data we need; the package name for which we store a config dict,
- * and the (Tcl_Interp *) in which it is stored.
+ * the (Tcl_Interp *) in which it is stored, and the encoding.
*/
typedef struct QCCD {
Tcl_Obj *pkg;
Tcl_Interp *interp;
+ char *encoding;
} QCCD;
/*
@@ -75,22 +76,28 @@ Tcl_RegisterConfig(
const char *valEncoding) /* Name of the encoding used to store the
* configuration values, ASCII, thus UTF-8. */
{
+ Tcl_Obj *pDB, *pkgDict;
Tcl_DString cmdName;
const Tcl_Config *cfg;
- Tcl_Encoding venc = Tcl_GetEncoding(NULL, valEncoding);
QCCD *cdPtr = ckalloc(sizeof(QCCD));
cdPtr->interp = interp;
+ if (valEncoding) {
+ cdPtr->encoding = ckalloc(strlen(valEncoding)+1);
+ strcpy(cdPtr->encoding, valEncoding);
+ } else {
+ cdPtr->encoding = NULL;
+ }
cdPtr->pkg = Tcl_NewStringObj(pkgName, -1);
/*
* Phase I: Adding the provided information to the internal database of
- * package meta data. Only if we have an ok encoding.
+ * package meta data.
*
* Phase II: Create a command for querying this database, specific to the
- * package registerting its configuration. This is the approved interface
+ * package registering its configuration. This is the approved interface
* in TIP 59. In the future a more general interface should be done, as
- * followup to TIP 59. Simply because our database is now general across
+ * follow-up to TIP 59. Simply because our database is now general across
* packages, and not a structure tied to one package.
*
* Note, the created command will have a reference through its clientdata.
@@ -103,51 +110,35 @@ Tcl_RegisterConfig(
* dictionaries visible at Tcl level. I.e. they are not filled
*/
- if (venc != NULL) {
- Tcl_Obj *pkgDict, *pDB = GetConfigDict(interp);
-
- /*
- * Retrieve package specific configuration...
- */
-
- if (Tcl_DictObjGet(interp, pDB, cdPtr->pkg, &pkgDict) != TCL_OK
- || (pkgDict == NULL)) {
- pkgDict = Tcl_NewDictObj();
- } else if (Tcl_IsShared(pkgDict)) {
- pkgDict = Tcl_DuplicateObj(pkgDict);
- }
-
- /*
- * Extend the package configuration...
- */
-
- for (cfg=configuration ; cfg->key!=NULL && cfg->key[0]!='\0' ; cfg++) {
- Tcl_DString conv;
- const char *convValue =
- Tcl_ExternalToUtfDString(venc, cfg->value, -1, &conv);
+ pDB = GetConfigDict(interp);
- /*
- * We know that the keys are in ASCII/UTF-8, so for them is no
- * conversion required.
- */
+ /*
+ * Retrieve package specific configuration...
+ */
- Tcl_DictObjPut(interp, pkgDict, Tcl_NewStringObj(cfg->key, -1),
- Tcl_NewStringObj(convValue, -1));
- Tcl_DStringFree(&conv);
- }
+ if (Tcl_DictObjGet(interp, pDB, cdPtr->pkg, &pkgDict) != TCL_OK
+ || (pkgDict == NULL)) {
+ pkgDict = Tcl_NewDictObj();
+ } else if (Tcl_IsShared(pkgDict)) {
+ pkgDict = Tcl_DuplicateObj(pkgDict);
+ }
- /*
- * We're now done with the encoding, so drop it.
- */
+ /*
+ * Extend the package configuration...
+ * We cannot assume that the encodings are initialized, therefore
+ * store the value as-is in a byte array. See Bug [9b2e636361].
+ */
- Tcl_FreeEncoding(venc);
+ for (cfg=configuration ; cfg->key!=NULL && cfg->key[0]!='\0' ; cfg++) {
+ Tcl_DictObjPut(interp, pkgDict, Tcl_NewStringObj(cfg->key, -1),
+ Tcl_NewByteArrayObj((unsigned char *)cfg->value, strlen(cfg->value)));
+ }
- /*
- * Write the changes back into the overall database.
- */
+ /*
+ * Write the changes back into the overall database.
+ */
- Tcl_DictObjPut(interp, pDB, cdPtr->pkg, pkgDict);
- }
+ Tcl_DictObjPut(interp, pDB, cdPtr->pkg, pkgDict);
/*
* Now create the interface command for retrieval of the package
@@ -155,7 +146,7 @@ Tcl_RegisterConfig(
*/
Tcl_DStringInit(&cmdName);
- Tcl_DStringAppend(&cmdName, "::", -1);
+ TclDStringAppendLiteral(&cmdName, "::");
Tcl_DStringAppend(&cmdName, pkgName, -1);
/*
@@ -173,7 +164,7 @@ Tcl_RegisterConfig(
}
}
- Tcl_DStringAppend(&cmdName, "::pkgconfig", -1);
+ TclDStringAppendLiteral(&cmdName, "::pkgconfig");
if (Tcl_CreateObjCommand(interp, Tcl_DStringValue(&cmdName),
QueryConfigObjCmd, cdPtr, QueryConfigDelete) == NULL) {
@@ -218,6 +209,9 @@ QueryConfigObjCmd(
enum subcmds {
CFG_GET, CFG_LIST
};
+ Tcl_DString conv;
+ Tcl_Encoding venc = NULL;
+ const char *value;
if ((objc < 2) || (objc > 3)) {
Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?arg?");
@@ -236,7 +230,7 @@ QueryConfigObjCmd(
* present.
*/
- Tcl_SetResult(interp, "package not known", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("package not known", -1));
Tcl_SetErrorCode(interp, "TCL", "FATAL", "PKGCFG_BASE",
Tcl_GetString(pkgName), NULL);
return TCL_ERROR;
@@ -251,13 +245,27 @@ QueryConfigObjCmd(
if (Tcl_DictObjGet(interp, pkgDict, objv[2], &val) != TCL_OK
|| val == NULL) {
- Tcl_SetResult(interp, "key not known", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("key not known", -1));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CONFIG",
Tcl_GetString(objv[2]), NULL);
return TCL_ERROR;
}
- Tcl_SetObjResult(interp, val);
+ if (cdPtr->encoding) {
+ venc = Tcl_GetEncoding(interp, cdPtr->encoding);
+ if (!venc) {
+ return TCL_ERROR;
+ }
+ }
+ /*
+ * Value is stored as-is in a byte array, see Bug [9b2e636361],
+ * so we have to decode it first.
+ */
+ value = (const char *) Tcl_GetByteArrayFromObj(val, &n);
+ value = Tcl_ExternalToUtfDString(venc, value, n, &conv);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(value,
+ Tcl_DStringLength(&conv)));
+ Tcl_DStringFree(&conv);
return TCL_OK;
case CFG_LIST:
@@ -270,8 +278,8 @@ QueryConfigObjCmd(
listPtr = Tcl_NewListObj(n, NULL);
if (!listPtr) {
- Tcl_SetResult(interp, "insufficient memory to create list",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "insufficient memory to create list", -1));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
return TCL_ERROR;
}
@@ -324,7 +332,10 @@ QueryConfigDelete(
Tcl_DictObjRemove(NULL, pDB, pkgName);
Tcl_DecrRefCount(pkgName);
- ckfree(cdPtr);
+ if (cdPtr->encoding) {
+ ckfree((char *)cdPtr->encoding);
+ }
+ ckfree((char *)cdPtr);
}
/*
@@ -366,7 +377,7 @@ GetConfigDict(
*
* This function is associated with the "Package About dict" assoc data
* for an interpreter; it is invoked when the interpreter is deleted in
- * order to free the information assoicated with any pending error
+ * order to free the information associated with any pending error
* reports.
*
* Results:
diff --git a/generic/tclDTrace.d b/generic/tclDTrace.d
index 0ee592f..360bdff 100644
--- a/generic/tclDTrace.d
+++ b/generic/tclDTrace.d
@@ -25,7 +25,7 @@ provider tcl {
* arg1: number of arguments (int)
* arg2: array of proc argument objects (Tcl_Obj**)
*/
- probe proc__entry(TclDTraceStr name, int objc, Tcl_Obj **objv);
+ probe proc__entry(TclDTraceStr name, int objc, struct Tcl_Obj **objv);
/*
* tcl*:::proc-return probe
* triggered immediately after proc bytecode execution
@@ -42,7 +42,7 @@ provider tcl {
* arg3: proc result object (Tcl_Obj*)
*/
probe proc__result(TclDTraceStr name, int code, TclDTraceStr result,
- Tcl_Obj *resultobj);
+ struct Tcl_Obj *resultobj);
/*
* tcl*:::proc-args probe
* triggered before proc-entry probe, gives access to string
@@ -79,7 +79,7 @@ provider tcl {
* arg1: number of arguments (int)
* arg2: array of command argument objects (Tcl_Obj**)
*/
- probe cmd__entry(TclDTraceStr name, int objc, Tcl_Obj **objv);
+ probe cmd__entry(TclDTraceStr name, int objc, struct Tcl_Obj **objv);
/*
* tcl*:::cmd-return probe
* triggered immediately after commmand execution
@@ -96,7 +96,7 @@ provider tcl {
* arg3: command result object (Tcl_Obj*)
*/
probe cmd__result(TclDTraceStr name, int code, TclDTraceStr result,
- Tcl_Obj *resultobj);
+ struct Tcl_Obj *resultobj);
/*
* tcl*:::cmd-args probe
* triggered before cmd-entry probe, gives access to string
@@ -133,7 +133,7 @@ provider tcl {
* arg1: depth of stack (int)
* arg2: top of stack (Tcl_Obj**)
*/
- probe inst__start(TclDTraceStr name, int depth, Tcl_Obj **stack);
+ probe inst__start(TclDTraceStr name, int depth, struct Tcl_Obj **stack);
/*
* tcl*:::inst-done probe
* triggered immediately after execution of a bytecode
@@ -141,7 +141,7 @@ provider tcl {
* arg1: depth of stack (int)
* arg2: top of stack (Tcl_Obj**)
*/
- probe inst__done(TclDTraceStr name, int depth, Tcl_Obj **stack);
+ probe inst__done(TclDTraceStr name, int depth, struct Tcl_Obj **stack);
/***************************** obj probes ******************************/
/*
@@ -149,13 +149,13 @@ provider tcl {
* triggered immediately after a new Tcl_Obj has been created
* arg0: object created (Tcl_Obj*)
*/
- probe obj__create(Tcl_Obj* obj);
+ probe obj__create(struct Tcl_Obj* obj);
/*
* tcl*:::obj-free probe
* triggered immediately before a Tcl_Obj is freed
* arg0: object to be freed (Tcl_Obj*)
*/
- probe obj__free(Tcl_Obj* obj);
+ probe obj__free(struct Tcl_Obj* obj);
/***************************** tcl probes ******************************/
/*
diff --git a/generic/tclDate.c b/generic/tclDate.c
index 14bac51..6222a8a 100644
--- a/generic/tclDate.c
+++ b/generic/tclDate.c
@@ -2686,7 +2686,7 @@ TclDatelex(
location->first_column = yyInput - info->dateStart;
for ( ; ; ) {
- while (isspace(UCHAR(*yyInput))) {
+ while (TclIsSpaceProc(*yyInput)) {
yyInput++;
}
diff --git a/generic/tclDecls.h b/generic/tclDecls.h
index 1df7e14..91c0add 100644
--- a/generic/tclDecls.h
+++ b/generic/tclDecls.h
@@ -31,6 +31,10 @@
/* !BEGIN!: Do not edit below this line. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Exported function declarations:
*/
@@ -59,7 +63,7 @@ EXTERN void Tcl_DbCkfree(char *ptr, const char *file, int line);
/* 8 */
EXTERN char * Tcl_DbCkrealloc(char *ptr, unsigned int size,
const char *file, int line);
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
/* 9 */
EXTERN void Tcl_CreateFileHandler(int fd, int mask,
Tcl_FileProc *proc, ClientData clientData);
@@ -69,7 +73,7 @@ EXTERN void Tcl_CreateFileHandler(int fd, int mask,
EXTERN void Tcl_CreateFileHandler(int fd, int mask,
Tcl_FileProc *proc, ClientData clientData);
#endif /* MACOSX */
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
/* 10 */
EXTERN void Tcl_DeleteFileHandler(int fd);
#endif /* UNIX */
@@ -507,7 +511,7 @@ EXTERN Tcl_Interp * Tcl_GetMaster(Tcl_Interp *interp);
EXTERN const char * Tcl_GetNameOfExecutable(void);
/* 166 */
EXTERN Tcl_Obj * Tcl_GetObjResult(Tcl_Interp *interp);
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
/* 167 */
EXTERN int Tcl_GetOpenFile(Tcl_Interp *interp,
const char *chanID, int forWriting,
@@ -1802,13 +1806,17 @@ EXTERN int Tcl_LoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr,
const char *const symv[], int flags,
void *procPtrs, Tcl_LoadHandle *handlePtr);
/* 628 */
-EXTERN void* Tcl_FindSymbol(Tcl_Interp *interp,
+EXTERN void * Tcl_FindSymbol(Tcl_Interp *interp,
Tcl_LoadHandle handle, const char *symbol);
/* 629 */
EXTERN int Tcl_FSUnloadFile(Tcl_Interp *interp,
Tcl_LoadHandle handlePtr);
+/* 630 */
+EXTERN void Tcl_ZlibStreamSetCompressionDictionary(
+ Tcl_ZlibStream zhandle,
+ Tcl_Obj *compressionDictionaryObj);
-typedef struct TclStubHooks {
+typedef struct {
const struct TclPlatStubs *tclPlatStubs;
const struct TclIntStubs *tclIntStubs;
const struct TclIntPlatStubs *tclIntPlatStubs;
@@ -1816,7 +1824,7 @@ typedef struct TclStubHooks {
typedef struct TclStubs {
int magic;
- const struct TclStubHooks *hooks;
+ const TclStubHooks *hooks;
int (*tcl_PkgProvideEx) (Tcl_Interp *interp, const char *name, const char *version, const void *clientData); /* 0 */
CONST84_RETURN char * (*tcl_PkgRequireEx) (Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 1 */
@@ -1827,19 +1835,19 @@ typedef struct TclStubs {
char * (*tcl_DbCkalloc) (unsigned int size, const char *file, int line); /* 6 */
void (*tcl_DbCkfree) (char *ptr, const char *file, int line); /* 7 */
char * (*tcl_DbCkrealloc) (char *ptr, unsigned int size, const char *file, int line); /* 8 */
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
void (*tcl_CreateFileHandler) (int fd, int mask, Tcl_FileProc *proc, ClientData clientData); /* 9 */
#endif /* UNIX */
-#ifdef __WIN32__ /* WIN */
+#if defined(_WIN32) /* WIN */
void (*reserved9)(void);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
void (*tcl_CreateFileHandler) (int fd, int mask, Tcl_FileProc *proc, ClientData clientData); /* 9 */
#endif /* MACOSX */
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
void (*tcl_DeleteFileHandler) (int fd); /* 10 */
#endif /* UNIX */
-#ifdef __WIN32__ /* WIN */
+#if defined(_WIN32) /* WIN */
void (*reserved10)(void);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
@@ -2001,10 +2009,10 @@ typedef struct TclStubs {
Tcl_Interp * (*tcl_GetMaster) (Tcl_Interp *interp); /* 164 */
const char * (*tcl_GetNameOfExecutable) (void); /* 165 */
Tcl_Obj * (*tcl_GetObjResult) (Tcl_Interp *interp); /* 166 */
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
int (*tcl_GetOpenFile) (Tcl_Interp *interp, const char *chanID, int forWriting, int checkUsage, ClientData *filePtr); /* 167 */
#endif /* UNIX */
-#ifdef __WIN32__ /* WIN */
+#if defined(_WIN32) /* WIN */
void (*reserved167)(void);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
@@ -2470,14 +2478,13 @@ typedef struct TclStubs {
int (*tcl_NRExprObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj *resultPtr); /* 625 */
int (*tcl_NRSubstObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 626 */
int (*tcl_LoadFile) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *const symv[], int flags, void *procPtrs, Tcl_LoadHandle *handlePtr); /* 627 */
- void* (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */
+ void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */
int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */
+ void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */
} TclStubs;
-#ifdef __cplusplus
-extern "C" {
-#endif
extern const TclStubs *tclStubsPtr;
+
#ifdef __cplusplus
}
#endif
@@ -2506,7 +2513,7 @@ extern const TclStubs *tclStubsPtr;
(tclStubsPtr->tcl_DbCkfree) /* 7 */
#define Tcl_DbCkrealloc \
(tclStubsPtr->tcl_DbCkrealloc) /* 8 */
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
#define Tcl_CreateFileHandler \
(tclStubsPtr->tcl_CreateFileHandler) /* 9 */
#endif /* UNIX */
@@ -2514,7 +2521,7 @@ extern const TclStubs *tclStubsPtr;
#define Tcl_CreateFileHandler \
(tclStubsPtr->tcl_CreateFileHandler) /* 9 */
#endif /* MACOSX */
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
#define Tcl_DeleteFileHandler \
(tclStubsPtr->tcl_DeleteFileHandler) /* 10 */
#endif /* UNIX */
@@ -2834,7 +2841,7 @@ extern const TclStubs *tclStubsPtr;
(tclStubsPtr->tcl_GetNameOfExecutable) /* 165 */
#define Tcl_GetObjResult \
(tclStubsPtr->tcl_GetObjResult) /* 166 */
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
#define Tcl_GetOpenFile \
(tclStubsPtr->tcl_GetOpenFile) /* 167 */
#endif /* UNIX */
@@ -3764,6 +3771,8 @@ extern const TclStubs *tclStubsPtr;
(tclStubsPtr->tcl_FindSymbol) /* 628 */
#define Tcl_FSUnloadFile \
(tclStubsPtr->tcl_FSUnloadFile) /* 629 */
+#define Tcl_ZlibStreamSetCompressionDictionary \
+ (tclStubsPtr->tcl_ZlibStreamSetCompressionDictionary) /* 630 */
#endif /* defined(USE_TCL_STUBS) */
@@ -3776,6 +3785,7 @@ extern const TclStubs *tclStubsPtr;
# undef Tcl_Init
# undef Tcl_SetPanicProc
# undef Tcl_SetVar
+# undef Tcl_ObjSetVar2
# undef Tcl_StaticPackage
# undef TclFSGetNativePath
# define Tcl_CreateInterp() (tclStubsPtr->tcl_CreateInterp())
@@ -3784,6 +3794,8 @@ extern const TclStubs *tclStubsPtr;
# define Tcl_SetPanicProc(proc) (tclStubsPtr->tcl_SetPanicProc(proc))
# define Tcl_SetVar(interp, varName, newValue, flags) \
(tclStubsPtr->tcl_SetVar(interp, varName, newValue, flags))
+# define Tcl_ObjSetVar2(interp, part1, part2, newValue, flags) \
+ (tclStubsPtr->tcl_ObjSetVar2(interp, part1, part2, newValue, flags))
#endif
#if defined(_WIN32) && defined(UNICODE)
@@ -3791,11 +3803,115 @@ extern const TclStubs *tclStubsPtr;
# define Tcl_MainEx Tcl_MainExW
EXTERN void Tcl_MainExW(int argc, wchar_t **argv,
Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
-# define Tcl_Main(argc, argv, proc) Tcl_MainExW(argc, argv, proc, \
- (Tcl_FindExecutable(argv[0]), (Tcl_CreateInterp)()))
#endif
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
+#undef Tcl_SeekOld
+#undef Tcl_TellOld
+
+#undef Tcl_PkgPresent
+#define Tcl_PkgPresent(interp, name, version, exact) \
+ Tcl_PkgPresentEx(interp, name, version, exact, NULL)
+#undef Tcl_PkgProvide
+#define Tcl_PkgProvide(interp, name, version) \
+ Tcl_PkgProvideEx(interp, name, version, NULL)
+#undef Tcl_PkgRequire
+#define Tcl_PkgRequire(interp, name, version, exact) \
+ Tcl_PkgRequireEx(interp, name, version, exact, NULL)
+#undef Tcl_GetIndexFromObj
+#define Tcl_GetIndexFromObj(interp, objPtr, tablePtr, msg, flags, indexPtr) \
+ Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, \
+ sizeof(char *), msg, flags, indexPtr)
+#undef Tcl_NewBooleanObj
+#define Tcl_NewBooleanObj(boolValue) \
+ Tcl_NewIntObj((boolValue)!=0)
+#undef Tcl_DbNewBooleanObj
+#define Tcl_DbNewBooleanObj(boolValue, file, line) \
+ Tcl_DbNewLongObj((boolValue)!=0, file, line)
+#undef Tcl_SetBooleanObj
+#define Tcl_SetBooleanObj(objPtr, boolValue) \
+ Tcl_SetIntObj((objPtr), (boolValue)!=0)
+#undef Tcl_SetVar
+#define Tcl_SetVar(interp, varName, newValue, flags) \
+ Tcl_SetVar2(interp, varName, NULL, newValue, flags)
+#undef Tcl_UnsetVar
+#define Tcl_UnsetVar(interp, varName, flags) \
+ Tcl_UnsetVar2(interp, varName, NULL, flags)
+#undef Tcl_GetVar
+#define Tcl_GetVar(interp, varName, flags) \
+ Tcl_GetVar2(interp, varName, NULL, flags)
+#undef Tcl_TraceVar
+#define Tcl_TraceVar(interp, varName, flags, proc, clientData) \
+ Tcl_TraceVar2(interp, varName, NULL, flags, proc, clientData)
+#undef Tcl_UntraceVar
+#define Tcl_UntraceVar(interp, varName, flags, proc, clientData) \
+ Tcl_UntraceVar2(interp, varName, NULL, flags, proc, clientData)
+#undef Tcl_VarTraceInfo
+#define Tcl_VarTraceInfo(interp, varName, flags, proc, prevClientData) \
+ Tcl_VarTraceInfo2(interp, varName, NULL, flags, proc, prevClientData)
+#undef Tcl_UpVar
+#define Tcl_UpVar(interp, frameName, varName, localName, flags) \
+ Tcl_UpVar2(interp, frameName, varName, NULL, localName, flags)
+
+#if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS)
+# if defined(__CYGWIN__) && defined(TCL_WIDE_INT_IS_LONG)
+/* On Cygwin64, long is 64-bit while on Win64 long is 32-bit. Therefore
+ * we have to make sure that all stub entries on Cygwin64 follow the
+ * Win64 signature. Cygwin64 stubbed extensions cannot use those stub
+ * entries any more, they should use the 64-bit alternatives where
+ * possible. Tcl 9 must find a better solution, but that cannot be done
+ * without introducing a binary incompatibility.
+ */
+# undef Tcl_DbNewLongObj
+# undef Tcl_GetLongFromObj
+# undef Tcl_NewLongObj
+# undef Tcl_SetLongObj
+# undef Tcl_ExprLong
+# undef Tcl_ExprLongObj
+# undef Tcl_UniCharNcmp
+# undef Tcl_UtfNcmp
+# undef Tcl_UtfNcasecmp
+# undef Tcl_UniCharNcasecmp
+# define Tcl_DbNewLongObj ((Tcl_Obj*(*)(long,const char*,int))Tcl_DbNewWideIntObj)
+# define Tcl_GetLongFromObj ((int(*)(Tcl_Interp*,Tcl_Obj*,long*))Tcl_GetWideIntFromObj)
+# define Tcl_NewLongObj ((Tcl_Obj*(*)(long))Tcl_NewWideIntObj)
+# define Tcl_SetLongObj ((void(*)(Tcl_Obj*,long))Tcl_SetWideIntObj)
+# define Tcl_ExprLong TclExprLong
+ static inline int TclExprLong(Tcl_Interp *interp, const char *string, long *ptr){
+ int intValue;
+ int result = tclStubsPtr->tcl_ExprLong(interp, string, (long *)&intValue);
+ if (result == TCL_OK) *ptr = (long)intValue;
+ return result;
+ }
+# define Tcl_ExprLongObj TclExprLongObj
+ static inline int TclExprLongObj(Tcl_Interp *interp, Tcl_Obj *obj, long *ptr){
+ int intValue;
+ int result = tclStubsPtr->tcl_ExprLongObj(interp, obj, (long *)&intValue);
+ if (result == TCL_OK) *ptr = (long)intValue;
+ return result;
+ }
+# define Tcl_UniCharNcmp(ucs,uct,n) \
+ ((int(*)(const Tcl_UniChar*,const Tcl_UniChar*,unsigned int))tclStubsPtr->tcl_UniCharNcmp)(ucs,uct,(unsigned int)(n))
+# define Tcl_UtfNcmp(s1,s2,n) \
+ ((int(*)(const char*,const char*,unsigned int))tclStubsPtr->tcl_UtfNcmp)(s1,s2,(unsigned int)(n))
+# define Tcl_UtfNcasecmp(s1,s2,n) \
+ ((int(*)(const char*,const char*,unsigned int))tclStubsPtr->tcl_UtfNcasecmp)(s1,s2,(unsigned int)(n))
+# define Tcl_UniCharNcasecmp(ucs,uct,n) \
+ ((int(*)(const Tcl_UniChar*,const Tcl_UniChar*,unsigned int))tclStubsPtr->tcl_UniCharNcasecmp)(ucs,uct,(unsigned int)(n))
+# endif
+#endif
+
+/*
+ * Deprecated Tcl procedures:
+ */
+
+#undef Tcl_EvalObj
+#define Tcl_EvalObj(interp,objPtr) \
+ Tcl_EvalObjEx((interp),(objPtr),0)
+#undef Tcl_GlobalEvalObj
+#define Tcl_GlobalEvalObj(interp,objPtr) \
+ Tcl_EvalObjEx((interp),(objPtr),TCL_EVAL_GLOBAL)
+
#endif /* _TCLDECLS */
diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c
index 83fc3a6..e31d708 100644
--- a/generic/tclDictObj.c
+++ b/generic/tclDictObj.c
@@ -76,9 +76,12 @@ static int FinalizeDictWith(ClientData data[],
Tcl_Interp *interp, int result);
static int DictForNRCmd(ClientData dummy, Tcl_Interp *interp,
int objc, Tcl_Obj *const *objv);
+static int DictMapNRCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const *objv);
static int DictForLoopCallback(ClientData data[],
Tcl_Interp *interp, int result);
-
+static int DictMapLoopCallback(ClientData data[],
+ Tcl_Interp *interp, int result);
/*
* Table of dict subcommand names and implementations.
@@ -86,24 +89,25 @@ static int DictForLoopCallback(ClientData data[],
static const EnsembleImplMap implementationMap[] = {
{"append", DictAppendCmd, TclCompileDictAppendCmd, NULL, NULL, 0 },
- {"create", DictCreateCmd, NULL, NULL, NULL, 0 },
- {"exists", DictExistsCmd, NULL, NULL, NULL, 0 },
- {"filter", DictFilterCmd, NULL, NULL, NULL, 0 },
+ {"create", DictCreateCmd, TclCompileDictCreateCmd, NULL, NULL, 0 },
+ {"exists", DictExistsCmd, TclCompileDictExistsCmd, NULL, NULL, 0 },
+ {"filter", DictFilterCmd, NULL, NULL, NULL, 0 },
{"for", NULL, TclCompileDictForCmd, DictForNRCmd, NULL, 0 },
{"get", DictGetCmd, TclCompileDictGetCmd, NULL, NULL, 0 },
{"incr", DictIncrCmd, TclCompileDictIncrCmd, NULL, NULL, 0 },
- {"info", DictInfoCmd, NULL, NULL, NULL, 0 },
- {"keys", DictKeysCmd, NULL, NULL, NULL, 0 },
+ {"info", DictInfoCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0 },
+ {"keys", DictKeysCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
{"lappend", DictLappendCmd, TclCompileDictLappendCmd, NULL, NULL, 0 },
- {"merge", DictMergeCmd, NULL, NULL, NULL, 0 },
- {"remove", DictRemoveCmd, NULL, NULL, NULL, 0 },
+ {"map", NULL, TclCompileDictMapCmd, DictMapNRCmd, NULL, 0 },
+ {"merge", DictMergeCmd, TclCompileDictMergeCmd, NULL, NULL, 0 },
+ {"remove", DictRemoveCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0 },
{"replace", DictReplaceCmd, NULL, NULL, NULL, 0 },
{"set", DictSetCmd, TclCompileDictSetCmd, NULL, NULL, 0 },
- {"size", DictSizeCmd, NULL, NULL, NULL, 0 },
- {"unset", DictUnsetCmd, NULL, NULL, NULL, 0 },
+ {"size", DictSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0 },
+ {"unset", DictUnsetCmd, TclCompileDictUnsetCmd, NULL, NULL, 0 },
{"update", DictUpdateCmd, TclCompileDictUpdateCmd, NULL, NULL, 0 },
- {"values", DictValuesCmd, NULL, NULL, NULL, 0 },
- {"with", DictWithCmd, NULL, NULL, NULL, 0 },
+ {"values", DictValuesCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
+ {"with", DictWithCmd, TclCompileDictWithCmd, NULL, NULL, 0 },
{NULL, NULL, NULL, NULL, NULL, 0}
};
@@ -181,6 +185,23 @@ static const Tcl_HashKeyType chainHashType = {
AllocChainEntry,
TclFreeObjEntry
};
+
+/*
+ * Structure used in implementation of 'dict map' to hold the state that gets
+ * passed between parts of the implementation.
+ */
+
+typedef struct {
+ Tcl_Obj *keyVarObj; /* The name of the variable that will have
+ * keys assigned to it. */
+ Tcl_Obj *valueVarObj; /* The name of the variable that will have
+ * values assigned to it. */
+ Tcl_DictSearch search; /* The dictionary search structure. */
+ Tcl_Obj *scriptObj; /* The script to evaluate each time through
+ * the loop. */
+ Tcl_Obj *accumulatorObj; /* The dictionary used to accumulate the
+ * results. */
+} DictMapStorage;
/***** START OF FUNCTIONS IMPLEMENTING DICT CORE API *****/
@@ -340,7 +361,7 @@ DupDictInternalRep(
Tcl_Obj *srcPtr,
Tcl_Obj *copyPtr)
{
- Dict *oldDict = srcPtr->internalRep.otherValuePtr;
+ Dict *oldDict = srcPtr->internalRep.twoPtrValue.ptr1;
Dict *newDict = ckalloc(sizeof(Dict));
ChainEntry *cPtr;
@@ -375,7 +396,7 @@ DupDictInternalRep(
* Store in the object.
*/
- copyPtr->internalRep.otherValuePtr = newDict;
+ copyPtr->internalRep.twoPtrValue.ptr1 = newDict;
copyPtr->typePtr = &tclDictType;
}
@@ -401,14 +422,12 @@ static void
FreeDictInternalRep(
Tcl_Obj *dictPtr)
{
- Dict *dict = dictPtr->internalRep.otherValuePtr;
+ Dict *dict = dictPtr->internalRep.twoPtrValue.ptr1;
dict->refcount--;
if (dict->refcount <= 0) {
DeleteDict(dict);
}
-
- dictPtr->internalRep.otherValuePtr = NULL; /* Belt and braces! */
dictPtr->typePtr = NULL;
}
@@ -468,7 +487,7 @@ UpdateStringOfDict(
{
#define LOCAL_SIZE 20
int localFlags[LOCAL_SIZE], *flagPtr = NULL;
- Dict *dict = dictPtr->internalRep.otherValuePtr;
+ Dict *dict = dictPtr->internalRep.twoPtrValue.ptr1;
ChainEntry *cPtr;
Tcl_Obj *keyPtr, *valuePtr;
int i, length, bytesNeeded = 0;
@@ -694,13 +713,14 @@ SetDictFromAny(
dict->epoch = 0;
dict->chain = NULL;
dict->refcount = 1;
- objPtr->internalRep.otherValuePtr = dict;
+ objPtr->internalRep.twoPtrValue.ptr1 = dict;
objPtr->typePtr = &tclDictType;
return TCL_OK;
missingValue:
if (interp != NULL) {
- Tcl_SetResult(interp, "missing value to go with key", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "missing value to go with key", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL);
}
result = TCL_ERROR;
@@ -762,7 +782,7 @@ TclTraceDictPath(
return NULL;
}
}
- dict = dictPtr->internalRep.otherValuePtr;
+ dict = dictPtr->internalRep.twoPtrValue.ptr1;
if (flags & DICT_PATH_UPDATE) {
dict->chain = NULL;
}
@@ -779,9 +799,9 @@ TclTraceDictPath(
}
if ((flags & DICT_PATH_CREATE) != DICT_PATH_CREATE) {
if (interp != NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "key \"", TclGetString(keyv[i]),
- "\" not known in dictionary", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "key \"%s\" not known in dictionary",
+ TclGetString(keyv[i])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT",
TclGetString(keyv[i]), NULL);
}
@@ -805,7 +825,7 @@ TclTraceDictPath(
}
}
- newDict = tmpObj->internalRep.otherValuePtr;
+ newDict = tmpObj->internalRep.twoPtrValue.ptr1;
if (flags & DICT_PATH_UPDATE) {
if (Tcl_IsShared(tmpObj)) {
TclDecrRefCount(tmpObj);
@@ -813,7 +833,7 @@ TclTraceDictPath(
Tcl_IncrRefCount(tmpObj);
Tcl_SetHashValue(hPtr, tmpObj);
dict->epoch++;
- newDict = tmpObj->internalRep.otherValuePtr;
+ newDict = tmpObj->internalRep.twoPtrValue.ptr1;
}
newDict->chain = dictPtr;
@@ -848,17 +868,17 @@ static void
InvalidateDictChain(
Tcl_Obj *dictObj)
{
- Dict *dict = dictObj->internalRep.otherValuePtr;
+ Dict *dict = dictObj->internalRep.twoPtrValue.ptr1;
do {
- Tcl_InvalidateStringRep(dictObj);
+ TclInvalidateStringRep(dictObj);
dict->epoch++;
dictObj = dict->chain;
if (dictObj == NULL) {
break;
}
dict->chain = NULL;
- dict = dictObj->internalRep.otherValuePtr;
+ dict = dictObj->internalRep.twoPtrValue.ptr1;
} while (dict != NULL);
}
@@ -905,9 +925,9 @@ Tcl_DictObjPut(
}
if (dictPtr->bytes != NULL) {
- Tcl_InvalidateStringRep(dictPtr);
+ TclInvalidateStringRep(dictPtr);
}
- dict = dictPtr->internalRep.otherValuePtr;
+ dict = dictPtr->internalRep.twoPtrValue.ptr1;
hPtr = CreateChainEntry(dict, keyPtr, &isNew);
Tcl_IncrRefCount(valuePtr);
if (!isNew) {
@@ -953,11 +973,12 @@ Tcl_DictObjGet(
if (dictPtr->typePtr != &tclDictType) {
int result = SetDictFromAny(interp, dictPtr);
if (result != TCL_OK) {
+ *valuePtrPtr = NULL;
return result;
}
}
- dict = dictPtr->internalRep.otherValuePtr;
+ dict = dictPtr->internalRep.twoPtrValue.ptr1;
hPtr = Tcl_FindHashEntry(&dict->table, keyPtr);
if (hPtr == NULL) {
*valuePtrPtr = NULL;
@@ -1006,9 +1027,9 @@ Tcl_DictObjRemove(
}
if (dictPtr->bytes != NULL) {
- Tcl_InvalidateStringRep(dictPtr);
+ TclInvalidateStringRep(dictPtr);
}
- dict = dictPtr->internalRep.otherValuePtr;
+ dict = dictPtr->internalRep.twoPtrValue.ptr1;
if (DeleteChainEntry(dict, keyPtr)) {
dict->epoch++;
}
@@ -1048,7 +1069,7 @@ Tcl_DictObjSize(
}
}
- dict = dictPtr->internalRep.otherValuePtr;
+ dict = dictPtr->internalRep.twoPtrValue.ptr1;
*sizePtr = dict->table.numEntries;
return TCL_OK;
}
@@ -1103,7 +1124,7 @@ Tcl_DictObjFirst(
}
}
- dict = dictPtr->internalRep.otherValuePtr;
+ dict = dictPtr->internalRep.twoPtrValue.ptr1;
cPtr = dict->entryChainHead;
if (cPtr == NULL) {
searchPtr->epoch = -1;
@@ -1278,7 +1299,7 @@ Tcl_DictObjPutKeyList(
return TCL_ERROR;
}
- dict = dictPtr->internalRep.otherValuePtr;
+ dict = dictPtr->internalRep.twoPtrValue.ptr1;
hPtr = CreateChainEntry(dict, keyv[keyc-1], &isNew);
Tcl_IncrRefCount(valuePtr);
if (!isNew) {
@@ -1334,7 +1355,7 @@ Tcl_DictObjRemoveKeyList(
return TCL_ERROR;
}
- dict = dictPtr->internalRep.otherValuePtr;
+ dict = dictPtr->internalRep.twoPtrValue.ptr1;
DeleteChainEntry(dict, keyv[keyc-1]);
InvalidateDictChain(dictPtr);
return TCL_OK;
@@ -1374,13 +1395,13 @@ Tcl_NewDictObj(void)
Dict *dict;
TclNewObj(dictPtr);
- Tcl_InvalidateStringRep(dictPtr);
+ TclInvalidateStringRep(dictPtr);
dict = ckalloc(sizeof(Dict));
InitChainTable(dict);
dict->epoch = 0;
dict->chain = NULL;
dict->refcount = 1;
- dictPtr->internalRep.otherValuePtr = dict;
+ dictPtr->internalRep.twoPtrValue.ptr1 = dict;
dictPtr->typePtr = &tclDictType;
return dictPtr;
#endif
@@ -1423,13 +1444,13 @@ Tcl_DbNewDictObj(
Dict *dict;
TclDbNewObj(dictPtr, file, line);
- Tcl_InvalidateStringRep(dictPtr);
+ TclInvalidateStringRep(dictPtr);
dict = ckalloc(sizeof(Dict));
InitChainTable(dict);
dict->epoch = 0;
dict->chain = NULL;
dict->refcount = 1;
- dictPtr->internalRep.otherValuePtr = dict;
+ dictPtr->internalRep.twoPtrValue.ptr1 = dict;
dictPtr->typePtr = &tclDictType;
return dictPtr;
#else /* !TCL_MEM_DEBUG */
@@ -1571,9 +1592,9 @@ DictGetCmd(
return result;
}
if (valuePtr == NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "key \"", TclGetString(objv[objc-1]),
- "\" not known in dictionary", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "key \"%s\" not known in dictionary",
+ TclGetString(objv[objc-1])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT",
TclGetString(objv[objc-1]), NULL);
return TCL_ERROR;
@@ -1982,7 +2003,6 @@ DictExistsCmd(
Tcl_Obj *const *objv)
{
Tcl_Obj *dictPtr, *valuePtr;
- int result;
if (objc < 3) {
Tcl_WrongNumArgs(interp, 1, objv, "dictionary key ?key ...?");
@@ -1991,18 +2011,13 @@ DictExistsCmd(
dictPtr = TclTraceDictPath(interp, objv[1], objc-3, objv+2,
DICT_PATH_EXISTS);
- if (dictPtr == NULL) {
- return TCL_ERROR;
- }
- if (dictPtr == DICT_PATH_NON_EXISTENT) {
+ if (dictPtr == NULL || dictPtr == DICT_PATH_NON_EXISTENT
+ || Tcl_DictObjGet(interp, dictPtr, objv[objc-1],
+ &valuePtr) != TCL_OK) {
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- return TCL_OK;
- }
- result = Tcl_DictObjGet(interp, dictPtr, objv[objc-1], &valuePtr);
- if (result != TCL_OK) {
- return result;
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(valuePtr != NULL));
}
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(valuePtr != NULL));
return TCL_OK;
}
@@ -2033,6 +2048,7 @@ DictInfoCmd(
{
Tcl_Obj *dictPtr;
Dict *dict;
+ char *statsStr;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "dictionary");
@@ -2046,9 +2062,11 @@ DictInfoCmd(
return result;
}
}
- dict = dictPtr->internalRep.otherValuePtr;
+ dict = dictPtr->internalRep.twoPtrValue.ptr1;
- Tcl_SetResult(interp, Tcl_HashStats(&dict->table), TCL_DYNAMIC);
+ statsStr = Tcl_HashStats(&dict->table);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(statsStr, -1));
+ ckfree(statsStr);
return TCL_OK;
}
@@ -2159,7 +2177,7 @@ DictIncrCmd(
}
}
if (code == TCL_OK) {
- Tcl_InvalidateStringRep(dictPtr);
+ TclInvalidateStringRep(dictPtr);
valuePtr = Tcl_ObjSetVar2(interp, objv[1], NULL,
dictPtr, TCL_LEAVE_ERR_MSG);
if (valuePtr == NULL) {
@@ -2248,7 +2266,7 @@ DictLappendCmd(
if (allocatedValue) {
Tcl_DictObjPut(interp, dictPtr, objv[2], valuePtr);
} else if (dictPtr->bytes != NULL) {
- Tcl_InvalidateStringRep(dictPtr);
+ TclInvalidateStringRep(dictPtr);
}
resultPtr = Tcl_ObjSetVar2(interp, objv[1], NULL, dictPtr,
@@ -2337,7 +2355,7 @@ DictAppendCmd(
*
* DictForNRCmd --
*
- * This function implements the "dict for" Tcl command. See the user
+ * These functions implement the "dict for" Tcl command. See the user
* documentation for details on what it does, and TIP#111 for the formal
* specification.
*
@@ -2377,8 +2395,8 @@ DictForNRCmd(
return TCL_ERROR;
}
if (varc != 2) {
- Tcl_SetResult(interp, "must have exactly two variable names",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "must have exactly two variable names", -1));
return TCL_ERROR;
}
searchPtr = TclStackAlloc(interp, sizeof(Tcl_DictSearch));
@@ -2490,13 +2508,15 @@ DictForLoopCallback(
*/
Tcl_IncrRefCount(valueObj);
- if (Tcl_ObjSetVar2(interp, keyVarObj, NULL, keyObj, TCL_LEAVE_ERR_MSG) == NULL) {
+ if (Tcl_ObjSetVar2(interp, keyVarObj, NULL, keyObj,
+ TCL_LEAVE_ERR_MSG) == NULL) {
TclDecrRefCount(valueObj);
result = TCL_ERROR;
goto done;
}
TclDecrRefCount(valueObj);
- if (Tcl_ObjSetVar2(interp, valueVarObj, NULL, valueObj, TCL_LEAVE_ERR_MSG) == NULL) {
+ if (Tcl_ObjSetVar2(interp, valueVarObj, NULL, valueObj,
+ TCL_LEAVE_ERR_MSG) == NULL) {
result = TCL_ERROR;
goto done;
}
@@ -2525,6 +2545,217 @@ DictForLoopCallback(
/*
*----------------------------------------------------------------------
*
+ * DictMapNRCmd --
+ *
+ * These functions implement the "dict map" Tcl command. See the user
+ * documentation for details on what it does, and TIP#405 for the formal
+ * specification.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictMapNRCmd(
+ ClientData dummy,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ Interp *iPtr = (Interp *) interp;
+ Tcl_Obj **varv, *keyObj, *valueObj;
+ DictMapStorage *storagePtr;
+ int varc, done;
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "{keyVar valueVar} dictionary script");
+ return TCL_ERROR;
+ }
+
+ /*
+ * Parse arguments.
+ */
+
+ if (TclListObjGetElements(interp, objv[1], &varc, &varv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (varc != 2) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "must have exactly two variable names", -1));
+ return TCL_ERROR;
+ }
+ storagePtr = TclStackAlloc(interp, sizeof(DictMapStorage));
+ if (Tcl_DictObjFirst(interp, objv[2], &storagePtr->search, &keyObj,
+ &valueObj, &done) != TCL_OK) {
+ TclStackFree(interp, storagePtr);
+ return TCL_ERROR;
+ }
+ if (done) {
+ /*
+ * Note that this exit leaves an empty value in the result (due to
+ * command calling conventions) but that is OK since an empty value is
+ * an empty dictionary.
+ */
+
+ TclStackFree(interp, storagePtr);
+ return TCL_OK;
+ }
+ TclNewObj(storagePtr->accumulatorObj);
+ TclListObjGetElements(NULL, objv[1], &varc, &varv);
+ storagePtr->keyVarObj = varv[0];
+ storagePtr->valueVarObj = varv[1];
+ storagePtr->scriptObj = objv[3];
+
+ /*
+ * Make sure that these objects (which we need throughout the body of the
+ * loop) don't vanish. Note that the dictionary internal rep is locked
+ * internally so that updates, shimmering, etc are not a problem.
+ */
+
+ Tcl_IncrRefCount(storagePtr->accumulatorObj);
+ Tcl_IncrRefCount(storagePtr->keyVarObj);
+ Tcl_IncrRefCount(storagePtr->valueVarObj);
+ Tcl_IncrRefCount(storagePtr->scriptObj);
+
+ /*
+ * Stop the value from getting hit in any way by any traces on the key
+ * variable.
+ */
+
+ Tcl_IncrRefCount(valueObj);
+ if (Tcl_ObjSetVar2(interp, storagePtr->keyVarObj, NULL, keyObj,
+ TCL_LEAVE_ERR_MSG) == NULL) {
+ TclDecrRefCount(valueObj);
+ goto error;
+ }
+ if (Tcl_ObjSetVar2(interp, storagePtr->valueVarObj, NULL, valueObj,
+ TCL_LEAVE_ERR_MSG) == NULL) {
+ TclDecrRefCount(valueObj);
+ goto error;
+ }
+ TclDecrRefCount(valueObj);
+
+ /*
+ * Run the script.
+ */
+
+ TclNRAddCallback(interp, DictMapLoopCallback, storagePtr, NULL,NULL,NULL);
+ return TclNREvalObjEx(interp, storagePtr->scriptObj, 0,
+ iPtr->cmdFramePtr, 3);
+
+ /*
+ * For unwinding everything on error.
+ */
+
+ error:
+ TclDecrRefCount(storagePtr->keyVarObj);
+ TclDecrRefCount(storagePtr->valueVarObj);
+ TclDecrRefCount(storagePtr->scriptObj);
+ TclDecrRefCount(storagePtr->accumulatorObj);
+ Tcl_DictObjDone(&storagePtr->search);
+ TclStackFree(interp, storagePtr);
+ return TCL_ERROR;
+}
+
+static int
+DictMapLoopCallback(
+ ClientData data[],
+ Tcl_Interp *interp,
+ int result)
+{
+ Interp *iPtr = (Interp *) interp;
+ DictMapStorage *storagePtr = data[0];
+ Tcl_Obj *keyObj, *valueObj;
+ int done;
+
+ /*
+ * Process the result from the previous execution of the script body.
+ */
+
+ if (result == TCL_CONTINUE) {
+ result = TCL_OK;
+ } else if (result != TCL_OK) {
+ if (result == TCL_BREAK) {
+ Tcl_ResetResult(interp);
+ result = TCL_OK;
+ } else if (result == TCL_ERROR) {
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (\"dict map\" body line %d)",
+ Tcl_GetErrorLine(interp)));
+ }
+ goto done;
+ } else {
+ keyObj = Tcl_ObjGetVar2(interp, storagePtr->keyVarObj, NULL,
+ TCL_LEAVE_ERR_MSG);
+ if (keyObj == NULL) {
+ result = TCL_ERROR;
+ goto done;
+ }
+ Tcl_DictObjPut(NULL, storagePtr->accumulatorObj, keyObj,
+ Tcl_GetObjResult(interp));
+ }
+
+ /*
+ * Get the next mapping from the dictionary.
+ */
+
+ Tcl_DictObjNext(&storagePtr->search, &keyObj, &valueObj, &done);
+ if (done) {
+ Tcl_SetObjResult(interp, storagePtr->accumulatorObj);
+ goto done;
+ }
+
+ /*
+ * Stop the value from getting hit in any way by any traces on the key
+ * variable.
+ */
+
+ Tcl_IncrRefCount(valueObj);
+ if (Tcl_ObjSetVar2(interp, storagePtr->keyVarObj, NULL, keyObj,
+ TCL_LEAVE_ERR_MSG) == NULL) {
+ TclDecrRefCount(valueObj);
+ result = TCL_ERROR;
+ goto done;
+ }
+ if (Tcl_ObjSetVar2(interp, storagePtr->valueVarObj, NULL, valueObj,
+ TCL_LEAVE_ERR_MSG) == NULL) {
+ TclDecrRefCount(valueObj);
+ result = TCL_ERROR;
+ goto done;
+ }
+ TclDecrRefCount(valueObj);
+
+ /*
+ * Run the script.
+ */
+
+ TclNRAddCallback(interp, DictMapLoopCallback, storagePtr, NULL,NULL,NULL);
+ return TclNREvalObjEx(interp, storagePtr->scriptObj, 0,
+ iPtr->cmdFramePtr, 3);
+
+ /*
+ * For unwinding everything once the iterating is done.
+ */
+
+ done:
+ TclDecrRefCount(storagePtr->keyVarObj);
+ TclDecrRefCount(storagePtr->valueVarObj);
+ TclDecrRefCount(storagePtr->scriptObj);
+ TclDecrRefCount(storagePtr->accumulatorObj);
+ Tcl_DictObjDone(&storagePtr->search);
+ TclStackFree(interp, storagePtr);
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* DictSetCmd --
*
* This function implements the "dict set" Tcl command. See the user
@@ -2793,8 +3024,8 @@ DictFilterCmd(
return TCL_ERROR;
}
if (varc != 2) {
- Tcl_SetResult(interp, "must have exactly two variable names",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "must have exactly two variable names", -1));
return TCL_ERROR;
}
keyVarObj = varv[0];
@@ -2834,16 +3065,19 @@ DictFilterCmd(
if (Tcl_ObjSetVar2(interp, keyVarObj, NULL, keyObj,
TCL_LEAVE_ERR_MSG) == NULL) {
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "couldn't set key variable: \"",
- TclGetString(keyVarObj), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't set key variable: \"%s\"",
+ TclGetString(keyVarObj)));
result = TCL_ERROR;
goto abnormalResult;
}
if (Tcl_ObjSetVar2(interp, valueVarObj, NULL, valueObj,
TCL_LEAVE_ERR_MSG) == NULL) {
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "couldn't set value variable: \"",
- TclGetString(valueVarObj), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't set value variable: \"%s\"",
+ TclGetString(valueVarObj)));
+ result = TCL_ERROR;
goto abnormalResult;
}
@@ -3110,9 +3344,7 @@ DictWithCmd(
Tcl_Obj *const *objv)
{
Interp *iPtr = (Interp *) interp;
- Tcl_Obj *dictPtr, *keysPtr, *keyPtr = NULL, *valPtr = NULL, *pathPtr;
- Tcl_DictSearch s;
- int done;
+ Tcl_Obj *dictPtr, *keysPtr, *pathPtr;
if (objc < 3) {
Tcl_WrongNumArgs(interp, 1, objv, "dictVar ?key ...? script");
@@ -3127,39 +3359,13 @@ DictWithCmd(
if (dictPtr == NULL) {
return TCL_ERROR;
}
- if (objc > 3) {
- dictPtr = TclTraceDictPath(interp, dictPtr, objc-3, objv+2,
- DICT_PATH_READ);
- if (dictPtr == NULL) {
- return TCL_ERROR;
- }
- }
- /*
- * Go over the list of keys and write each corresponding value to a
- * variable in the current context with the same name. Also keep a copy of
- * the keys so we can write back properly later on even if the dictionary
- * has been structurally modified.
- */
-
- if (Tcl_DictObjFirst(interp, dictPtr, &s, &keyPtr, &valPtr,
- &done) != TCL_OK) {
+ keysPtr = TclDictWithInit(interp, dictPtr, objc-3, objv+2);
+ if (keysPtr == NULL) {
return TCL_ERROR;
}
-
- TclNewObj(keysPtr);
Tcl_IncrRefCount(keysPtr);
- for (; !done ; Tcl_DictObjNext(&s, &keyPtr, &valPtr, &done)) {
- Tcl_ListObjAppendElement(NULL, keysPtr, keyPtr);
- if (Tcl_ObjSetVar2(interp, keyPtr, NULL, valPtr,
- TCL_LEAVE_ERR_MSG) == NULL) {
- TclDecrRefCount(keysPtr);
- Tcl_DictObjDone(&s);
- return TCL_ERROR;
- }
- }
-
/*
* Execute the body, while making the invoking context available to the
* loop body (TIP#280) and postponing the cleanup until later (NRE).
@@ -3183,55 +3389,200 @@ FinalizeDictWith(
Tcl_Interp *interp,
int result)
{
- Tcl_Obj **keyv, *leafPtr, *dictPtr, *valPtr;
- int keyc, i, allocdict = 0;
+ Tcl_Obj **pathv;
+ int pathc;
Tcl_InterpState state;
Tcl_Obj *varName = data[0];
Tcl_Obj *keysPtr = data[1];
Tcl_Obj *pathPtr = data[2];
+ Var *varPtr, *arrayPtr;
if (result == TCL_ERROR) {
Tcl_AddErrorInfo(interp, "\n (body of \"dict with\")");
}
/*
+ * Save the result state; TDWF doesn't guarantee to not modify that on
+ * TCL_OK result.
+ */
+
+ state = Tcl_SaveInterpState(interp, result);
+ if (pathPtr != NULL) {
+ Tcl_ListObjGetElements(NULL, pathPtr, &pathc, &pathv);
+ } else {
+ pathc = 0;
+ pathv = NULL;
+ }
+
+ /*
+ * Pack from local variables back into the dictionary.
+ */
+
+ varPtr = TclObjLookupVarEx(interp, varName, NULL, TCL_LEAVE_ERR_MSG, "set",
+ /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
+ if (varPtr == NULL) {
+ result = TCL_ERROR;
+ } else {
+ result = TclDictWithFinish(interp, varPtr, arrayPtr, varName, NULL, -1,
+ pathc, pathv, keysPtr);
+ }
+
+ /*
+ * Tidy up and return the real result (unless we had an error).
+ */
+
+ TclDecrRefCount(varName);
+ TclDecrRefCount(keysPtr);
+ if (pathPtr != NULL) {
+ TclDecrRefCount(pathPtr);
+ }
+ if (result != TCL_OK) {
+ Tcl_DiscardInterpState(state);
+ return TCL_ERROR;
+ }
+ return Tcl_RestoreInterpState(interp, state);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDictWithInit --
+ *
+ * Part of the core of [dict with]. Pokes into a dictionary and converts
+ * the mappings there into assignments to (presumably) local variables.
+ * Returns a list of all the names that were mapped so that removal of
+ * either the variable or the dictionary entry won't surprise us when we
+ * come to stuffing everything back.
+ *
+ * Result:
+ * List of mapped names, or NULL if there was an error.
+ *
+ * Side effects:
+ * Assigns to variables, so potentially legion due to traces.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclDictWithInit(
+ Tcl_Interp *interp,
+ Tcl_Obj *dictPtr,
+ int pathc,
+ Tcl_Obj *const pathv[])
+{
+ Tcl_DictSearch s;
+ Tcl_Obj *keyPtr, *valPtr, *keysPtr;
+ int done;
+
+ if (pathc > 0) {
+ dictPtr = TclTraceDictPath(interp, dictPtr, pathc, pathv,
+ DICT_PATH_READ);
+ if (dictPtr == NULL) {
+ return NULL;
+ }
+ }
+
+ /*
+ * Go over the list of keys and write each corresponding value to a
+ * variable in the current context with the same name. Also keep a copy of
+ * the keys so we can write back properly later on even if the dictionary
+ * has been structurally modified.
+ */
+
+ if (Tcl_DictObjFirst(interp, dictPtr, &s, &keyPtr, &valPtr,
+ &done) != TCL_OK) {
+ return NULL;
+ }
+
+ TclNewObj(keysPtr);
+
+ for (; !done ; Tcl_DictObjNext(&s, &keyPtr, &valPtr, &done)) {
+ Tcl_ListObjAppendElement(NULL, keysPtr, keyPtr);
+ if (Tcl_ObjSetVar2(interp, keyPtr, NULL, valPtr,
+ TCL_LEAVE_ERR_MSG) == NULL) {
+ TclDecrRefCount(keysPtr);
+ Tcl_DictObjDone(&s);
+ return NULL;
+ }
+ }
+
+ return keysPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDictWithFinish --
+ *
+ * Part of the core of [dict with]. Reassembles the piece of the dict (in
+ * varName, location given by pathc/pathv) from the variables named in
+ * the keysPtr argument. NB, does not try to preserve errors or manage
+ * argument lifetimes.
+ *
+ * Result:
+ * TCL_OK if we succeeded, or TCL_ERROR if we failed.
+ *
+ * Side effects:
+ * Assigns to a variable, so potentially legion due to traces. Updates
+ * the dictionary in the named variable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclDictWithFinish(
+ Tcl_Interp *interp, /* Command interpreter in which variable
+ * exists. Used for state management, traces
+ * and error reporting. */
+ Var *varPtr, /* Reference to the variable holding the
+ * dictionary. */
+ Var *arrayPtr, /* Reference to the array containing the
+ * variable, or NULL if the variable is a
+ * scalar. */
+ Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or
+ * the name of a variable. NULL if the 'index'
+ * parameter is >= 0 */
+ Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element
+ * in the array part1. */
+ int index, /* Index into the local variable table of the
+ * variable, or -1. Only used when part1Ptr is
+ * NULL. */
+ int pathc, /* The number of elements in the path into the
+ * dictionary. */
+ Tcl_Obj *const pathv[], /* The elements of the path to the subdict. */
+ Tcl_Obj *keysPtr) /* List of keys to be synchronized. This is
+ * the result value from TclDictWithInit. */
+{
+ Tcl_Obj *dictPtr, *leafPtr, *valPtr;
+ int i, allocdict, keyc;
+ Tcl_Obj **keyv;
+
+ /*
* If the dictionary variable doesn't exist, drop everything silently.
*/
- dictPtr = Tcl_ObjGetVar2(interp, varName, NULL, 0);
+ dictPtr = TclPtrGetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
+ TCL_LEAVE_ERR_MSG, index);
if (dictPtr == NULL) {
- TclDecrRefCount(varName);
- TclDecrRefCount(keysPtr);
- if (pathPtr) {
- TclDecrRefCount(pathPtr);
- }
- return result;
+ return TCL_OK;
}
/*
* Double-check that it is still a dictionary.
*/
- state = Tcl_SaveInterpState(interp, result);
if (Tcl_DictObjSize(interp, dictPtr, &i) != TCL_OK) {
- TclDecrRefCount(varName);
- TclDecrRefCount(keysPtr);
- if (pathPtr) {
- TclDecrRefCount(pathPtr);
- }
- Tcl_DiscardInterpState(state);
return TCL_ERROR;
}
if (Tcl_IsShared(dictPtr)) {
dictPtr = Tcl_DuplicateObj(dictPtr);
allocdict = 1;
+ } else {
+ allocdict = 0;
}
- if (pathPtr != NULL) {
- Tcl_Obj **pathv;
- int pathc;
-
+ if (pathc > 0) {
/*
* Want to get to the dictionary which we will update; need to do
* prepare-for-update de-sharing along the path *but* avoid generating
@@ -3241,26 +3592,19 @@ FinalizeDictWith(
* perfectly efficient (but no memory should be leaked).
*/
- Tcl_ListObjGetElements(NULL, pathPtr, &pathc, &pathv);
leafPtr = TclTraceDictPath(interp, dictPtr, pathc, pathv,
DICT_PATH_EXISTS | DICT_PATH_UPDATE);
- TclDecrRefCount(pathPtr);
if (leafPtr == NULL) {
- TclDecrRefCount(varName);
- TclDecrRefCount(keysPtr);
if (allocdict) {
TclDecrRefCount(dictPtr);
}
- Tcl_DiscardInterpState(state);
return TCL_ERROR;
}
if (leafPtr == DICT_PATH_NON_EXISTENT) {
- TclDecrRefCount(varName);
- TclDecrRefCount(keysPtr);
if (allocdict) {
TclDecrRefCount(dictPtr);
}
- return Tcl_RestoreInterpState(interp, state);
+ return TCL_OK;
}
} else {
leafPtr = dictPtr;
@@ -3286,14 +3630,13 @@ FinalizeDictWith(
Tcl_DictObjPut(NULL, leafPtr, keyv[i], valPtr);
}
}
- TclDecrRefCount(keysPtr);
/*
* Ensure that none of the dictionaries in the chain still have a string
* rep.
*/
- if (pathPtr != NULL) {
+ if (pathc > 0) {
InvalidateDictChain(leafPtr);
}
@@ -3301,13 +3644,14 @@ FinalizeDictWith(
* Write back the outermost dictionary to the variable.
*/
- if (Tcl_ObjSetVar2(interp, varName, NULL, dictPtr,
- TCL_LEAVE_ERR_MSG) == NULL) {
- Tcl_DiscardInterpState(state);
+ if (TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr, dictPtr,
+ TCL_LEAVE_ERR_MSG, index) == NULL) {
+ if (allocdict) {
+ TclDecrRefCount(dictPtr);
+ }
return TCL_ERROR;
}
- TclDecrRefCount(varName);
- return Tcl_RestoreInterpState(interp, state);
+ return TCL_OK;
}
/*
@@ -3334,7 +3678,7 @@ TclInitDictCmd(
{
return TclMakeEnsemble(interp, "dict", implementationMap);
}
-
+
/*
* Local Variables:
* mode: c
diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c
index 15411d8..d246cb2 100644
--- a/generic/tclEncoding.c
+++ b/generic/tclEncoding.c
@@ -182,6 +182,7 @@ TCL_DECLARE_MUTEX(encodingMutex)
static Tcl_Encoding defaultEncoding;
static Tcl_Encoding systemEncoding;
+Tcl_Encoding tclIdentityEncoding;
/*
* The following variable is used in the sparse matrix code for a
@@ -270,7 +271,7 @@ static int Iso88591ToUtfProc(ClientData clientData,
int *dstCharsPtr);
/*
- * A Tcl_ObjType for holding a cached Tcl_Encoding in the otherValuePtr field
+ * A Tcl_ObjType for holding a cached Tcl_Encoding in the twoPtrValue.ptr1 field
* of the intrep. This should help the lifetime of encodings be more useful.
* See concerns raised in [Bug 1077262].
*/
@@ -313,7 +314,7 @@ Tcl_GetEncodingFromObj(
return TCL_ERROR;
}
TclFreeIntRep(objPtr);
- objPtr->internalRep.otherValuePtr = encoding;
+ objPtr->internalRep.twoPtrValue.ptr1 = encoding;
objPtr->typePtr = &encodingType;
}
*encodingPtr = Tcl_GetEncoding(NULL, name);
@@ -334,7 +335,7 @@ static void
FreeEncodingIntRep(
Tcl_Obj *objPtr)
{
- Tcl_FreeEncoding(objPtr->internalRep.otherValuePtr);
+ Tcl_FreeEncoding(objPtr->internalRep.twoPtrValue.ptr1);
objPtr->typePtr = NULL;
}
@@ -353,7 +354,7 @@ DupEncodingIntRep(
Tcl_Obj *srcPtr,
Tcl_Obj *dupPtr)
{
- dupPtr->internalRep.otherValuePtr = Tcl_GetEncoding(NULL, srcPtr->bytes);
+ dupPtr->internalRep.twoPtrValue.ptr1 = Tcl_GetEncoding(NULL, srcPtr->bytes);
}
/*
@@ -567,7 +568,7 @@ TclInitEncodingSubsystem(void)
type.freeProc = NULL;
type.nullSize = 1;
type.clientData = NULL;
- Tcl_CreateEncoding(&type);
+ tclIdentityEncoding = Tcl_CreateEncoding(&type);
type.encodingName = "utf-8";
type.toUtfProc = UtfExtToUtfIntProc;
@@ -651,6 +652,7 @@ TclFinalizeEncodingSubsystem(void)
Tcl_MutexLock(&encodingMutex);
encodingsInitialized = 0;
FreeEncoding(systemEncoding);
+ FreeEncoding(tclIdentityEncoding);
hPtr = Tcl_FirstHashEntry(&encodingTable, &search);
while (hPtr != NULL) {
@@ -979,13 +981,13 @@ Tcl_GetEncodingNames(
int
Tcl_SetSystemEncoding(
Tcl_Interp *interp, /* Interp for error reporting, if not NULL. */
- const char *name) /* The name of the desired encoding, or NULL
+ const char *name) /* The name of the desired encoding, or NULL/""
* to reset to default encoding. */
{
Tcl_Encoding encoding;
Encoding *encodingPtr;
- if (name == NULL) {
+ if (!name || !*name) {
Tcl_MutexLock(&encodingMutex);
encoding = defaultEncoding;
encodingPtr = (Encoding *) encoding;
@@ -1542,7 +1544,8 @@ OpenEncodingFileChannel(
}
if ((NULL == chan) && (interp != NULL)) {
- Tcl_AppendResult(interp, "unknown encoding \"", name, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown encoding \"%s\"", name));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name, NULL);
}
Tcl_DecrRefCount(fileNameObj);
@@ -1616,7 +1619,8 @@ LoadEncodingFile(
break;
}
if ((encoding == NULL) && (interp != NULL)) {
- Tcl_AppendResult(interp, "invalid encoding file \"", name, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid encoding file \"%s\"", name));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name, NULL);
}
Tcl_Close(NULL, chan);
@@ -1872,9 +1876,9 @@ LoadTableEncoding(
* Read lines from the encoding until EOF.
*/
- for (Tcl_DStringSetLength(&lineString, 0);
+ for (TclDStringClear(&lineString);
(len = Tcl_Gets(chan, &lineString)) >= 0;
- Tcl_DStringSetLength(&lineString, 0)) {
+ TclDStringClear(&lineString)) {
const unsigned char *p;
int to, from;
diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c
index 1c7b41d..9bb7a0c 100644
--- a/generic/tclEnsemble.c
+++ b/generic/tclEnsemble.c
@@ -4,7 +4,7 @@
* Contains support for ensembles (see TIP#112), which provide simple
* mechanism for creating composite commands on top of namespaces.
*
- * Copyright (c) 2005-2010 Donal K. Fellows.
+ * Copyright (c) 2005-2013 Donal K. Fellows.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -17,6 +17,7 @@
* Declarations for functions local to this file:
*/
+static inline Tcl_Obj * NewNsObj(Tcl_Namespace *namespacePtr);
static inline int EnsembleUnknownCallback(Tcl_Interp *interp,
EnsembleConfig *ensemblePtr, int objc,
Tcl_Obj *const objv[], Tcl_Obj **prefixObjPtr);
@@ -34,6 +35,12 @@ static void MakeCachedEnsembleCommand(Tcl_Obj *objPtr,
static void FreeEnsembleCmdRep(Tcl_Obj *objPtr);
static void DupEnsembleCmdRep(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
static void StringOfEnsembleCmdRep(Tcl_Obj *objPtr);
+static void CompileToInvokedCommand(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Tcl_Obj *replacements,
+ Command *cmdPtr, CompileEnv *envPtr);
+static int CompileBasicNArgCommand(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ CompileEnv *envPtr);
/*
* The lists of subcommands and options for the [namespace ensemble] command.
@@ -77,6 +84,20 @@ const Tcl_ObjType tclEnsembleCmdType = {
StringOfEnsembleCmdRep, /* updateStringProc */
NULL /* setFromAnyProc */
};
+
+
+static inline Tcl_Obj *
+NewNsObj(
+ Tcl_Namespace *namespacePtr)
+{
+ register Namespace *nsPtr = (Namespace *) namespacePtr;
+
+ if (namespacePtr == TclGetGlobalNamespace(nsPtr->interp)) {
+ return Tcl_NewStringObj("::", 2);
+ } else {
+ return Tcl_NewStringObj(nsPtr->fullName, -1);
+ }
+}
/*
*----------------------------------------------------------------------
@@ -116,9 +137,10 @@ TclNamespaceEnsembleCmd(
if (nsPtr == NULL || nsPtr->flags & NS_DYING) {
if (!Tcl_InterpDeleted(interp)) {
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"tried to manipulate ensemble of deleted namespace",
- NULL);
+ -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "DEAD", NULL);
}
return TCL_ERROR;
}
@@ -235,9 +257,11 @@ TclNamespaceEnsembleCmd(
return TCL_ERROR;
}
if (len < 1) {
- Tcl_SetResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"ensemble subcommand implementations "
- "must be non-empty lists", TCL_STATIC);
+ "must be non-empty lists", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE",
+ "EMPTY_TARGET", NULL);
Tcl_DictObjDone(&search);
if (patchedDict) {
Tcl_DecrRefCount(patchedDict);
@@ -250,7 +274,7 @@ TclNamespaceEnsembleCmd(
cmd = TclGetString(listv[0]);
if (!(cmd[0] == ':' && cmd[1] == ':')) {
Tcl_Obj *newList = Tcl_NewListObj(len, listv);
- Tcl_Obj *newCmd = Tcl_NewStringObj(nsPtr->fullName,-1);
+ Tcl_Obj *newCmd = NewNsObj((Tcl_Namespace *) nsPtr);
if (nsPtr->parentPtr) {
Tcl_AppendStringsToObj(newCmd, "::", NULL);
@@ -370,8 +394,7 @@ TclNamespaceEnsembleCmd(
case CONF_NAMESPACE:
namespacePtr = NULL; /* silence gcc 4 warning */
Tcl_GetEnsembleNamespace(NULL, token, &namespacePtr);
- Tcl_SetResult(interp, ((Namespace *) namespacePtr)->fullName,
- TCL_VOLATILE);
+ Tcl_SetObjResult(interp, NewNsObj(namespacePtr));
break;
case CONF_PREFIX: {
int flags = 0; /* silence gcc 4 warning */
@@ -411,9 +434,7 @@ TclNamespaceEnsembleCmd(
-1));
namespacePtr = NULL; /* silence gcc 4 warning */
Tcl_GetEnsembleNamespace(NULL, token, &namespacePtr);
- Tcl_ListObjAppendElement(NULL, resultObj,
- Tcl_NewStringObj(((Namespace *) namespacePtr)->fullName,
- -1));
+ Tcl_ListObjAppendElement(NULL, resultObj, NewNsObj(namespacePtr));
/* -parameters option */
Tcl_ListObjAppendElement(NULL, resultObj,
@@ -515,9 +536,11 @@ TclNamespaceEnsembleCmd(
goto freeMapAndError;
}
if (len < 1) {
- Tcl_SetResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"ensemble subcommand implementations "
- "must be non-empty lists", TCL_STATIC);
+ "must be non-empty lists", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE",
+ "EMPTY_TARGET", NULL);
Tcl_DictObjDone(&search);
if (patchedDict) {
Tcl_DecrRefCount(patchedDict);
@@ -527,8 +550,7 @@ TclNamespaceEnsembleCmd(
cmd = TclGetString(listv[0]);
if (!(cmd[0] == ':' && cmd[1] == ':')) {
Tcl_Obj *newList = Tcl_DuplicateObj(listObj);
- Tcl_Obj *newCmd =
- Tcl_NewStringObj(nsPtr->fullName, -1);
+ Tcl_Obj *newCmd = NewNsObj((Tcl_Namespace*)nsPtr);
if (nsPtr->parentPtr) {
Tcl_AppendStringsToObj(newCmd, "::", NULL);
@@ -554,7 +576,9 @@ TclNamespaceEnsembleCmd(
continue;
}
case CONF_NAMESPACE:
- Tcl_AppendResult(interp, "option -namespace is read-only",
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "option -namespace is read-only", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "READ_ONLY",
NULL);
goto freeMapAndError;
case CONF_PREFIX:
@@ -629,7 +653,7 @@ Tcl_CreateEnsemble(
*/
if (!(name[0] == ':' && name[1] == ':')) {
- nameObj = Tcl_NewStringObj(nsPtr->fullName, -1);
+ nameObj = NewNsObj((Tcl_Namespace *) nsPtr);
if (nsPtr->parentPtr == NULL) {
Tcl_AppendStringsToObj(nameObj, name, NULL);
} else {
@@ -702,7 +726,9 @@ Tcl_SetEnsembleSubcommandList(
Tcl_Obj *oldList;
if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
- Tcl_AppendResult(interp, "command is not an ensemble", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "command is not an ensemble", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
return TCL_ERROR;
}
if (subcmdList != NULL) {
@@ -776,7 +802,9 @@ Tcl_SetEnsembleParameterList(
int length;
if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
- Tcl_AppendResult(interp, "command is not an ensemble", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "command is not an ensemble", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
return TCL_ERROR;
}
if (paramList == NULL) {
@@ -850,7 +878,9 @@ Tcl_SetEnsembleMappingDict(
Tcl_Obj *oldDict;
if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
- Tcl_AppendResult(interp, "command is not an ensemble", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "command is not an ensemble", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
return TCL_ERROR;
}
if (mapDict != NULL) {
@@ -873,9 +903,11 @@ Tcl_SetEnsembleMappingDict(
}
bytes = TclGetString(cmdObjPtr);
if (bytes[0] != ':' || bytes[1] != ':') {
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"ensemble target is not a fully-qualified command",
- NULL);
+ -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE",
+ "UNQUALIFIED_TARGET", NULL);
Tcl_DictObjDone(&search);
return TCL_ERROR;
}
@@ -945,7 +977,9 @@ Tcl_SetEnsembleUnknownHandler(
Tcl_Obj *oldList;
if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
- Tcl_AppendResult(interp, "command is not an ensemble", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "command is not an ensemble", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
return TCL_ERROR;
}
if (unknownList != NULL) {
@@ -1009,7 +1043,9 @@ Tcl_SetEnsembleFlags(
int wasCompiled;
if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
- Tcl_AppendResult(interp, "command is not an ensemble", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "command is not an ensemble", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
return TCL_ERROR;
}
@@ -1084,7 +1120,9 @@ Tcl_GetEnsembleSubcommandList(
if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "command is not an ensemble", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "command is not an ensemble", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
}
return TCL_ERROR;
}
@@ -1124,7 +1162,9 @@ Tcl_GetEnsembleParameterList(
if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "command is not an ensemble", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "command is not an ensemble", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
}
return TCL_ERROR;
}
@@ -1164,7 +1204,9 @@ Tcl_GetEnsembleMappingDict(
if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "command is not an ensemble", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "command is not an ensemble", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
}
return TCL_ERROR;
}
@@ -1203,7 +1245,9 @@ Tcl_GetEnsembleUnknownHandler(
if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "command is not an ensemble", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "command is not an ensemble", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
}
return TCL_ERROR;
}
@@ -1242,7 +1286,9 @@ Tcl_GetEnsembleFlags(
if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "command is not an ensemble", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "command is not an ensemble", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
}
return TCL_ERROR;
}
@@ -1281,7 +1327,9 @@ Tcl_GetEnsembleNamespace(
if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "command is not an ensemble", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "command is not an ensemble", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
}
return TCL_ERROR;
}
@@ -1337,8 +1385,9 @@ Tcl_FindEnsemble(
if (cmdPtr == NULL || cmdPtr->objProc != NsEnsembleImplementationCmd){
if (flags & TCL_LEAVE_ERR_MSG) {
- Tcl_AppendResult(interp, "\"", TclGetString(cmdNameObj),
- "\" is not an ensemble command", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" is not an ensemble command",
+ TclGetString(cmdNameObj)));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENSEMBLE",
TclGetString(cmdNameObj), NULL);
}
@@ -1425,9 +1474,9 @@ TclMakeEnsemble(
Tcl_DStringInit(&buf);
Tcl_DStringInit(&hiddenBuf);
- Tcl_DStringAppend(&hiddenBuf, "tcl:", -1);
+ TclDStringAppendLiteral(&hiddenBuf, "tcl:");
Tcl_DStringAppend(&hiddenBuf, name, -1);
- Tcl_DStringAppend(&hiddenBuf, ":", -1);
+ TclDStringAppendLiteral(&hiddenBuf, ":");
hiddenLen = Tcl_DStringLength(&hiddenBuf);
if (name[0] == ':' && name[1] == ':') {
/*
@@ -1443,14 +1492,14 @@ TclMakeEnsemble(
* multi-word list differently to a single word.
*/
- Tcl_DStringAppend(&buf, "::tcl", -1);
+ TclDStringAppendLiteral(&buf, "::tcl");
if (Tcl_SplitList(NULL, name, &nameCount, &nameParts) != TCL_OK) {
Tcl_Panic("invalid ensemble name '%s'", name);
}
for (i = 0; i < nameCount; ++i) {
- Tcl_DStringAppend(&buf, "::", 2);
+ TclDStringAppendLiteral(&buf, "::");
Tcl_DStringAppend(&buf, nameParts[i], -1);
}
}
@@ -1475,6 +1524,14 @@ TclMakeEnsemble(
cmdName = nameParts[nameCount - 1];
}
}
+
+ /*
+ * Switch on compilation always for core ensembles now that we can do
+ * nice bytecode things with them. Do it now. Waiting until later will
+ * just cause pointless epoch bumps.
+ */
+
+ ensembleFlags |= ENSEMBLE_COMPILE;
ensemble = Tcl_CreateEnsemble(interp, cmdName, ns, ensembleFlags);
/*
@@ -1485,7 +1542,7 @@ TclMakeEnsemble(
Tcl_Obj *mapDict, *fromObj, *toObj;
Command *cmdPtr;
- Tcl_DStringAppend(&buf, "::", 2);
+ TclDStringAppendLiteral(&buf, "::");
TclNewObj(mapDict);
for (i=0 ; map[i].name != NULL ; i++) {
fromObj = Tcl_NewStringObj(map[i].name, -1);
@@ -1523,21 +1580,15 @@ TclMakeEnsemble(
NULL);
}
cmdPtr->compileProc = map[i].compileProc;
- if (map[i].compileProc != NULL) {
- ensembleFlags |= ENSEMBLE_COMPILE;
- }
}
}
Tcl_SetEnsembleMappingDict(interp, ensemble, mapDict);
- if (ensembleFlags & ENSEMBLE_COMPILE) {
- Tcl_SetEnsembleFlags(interp, ensemble, ensembleFlags);
- }
}
Tcl_DStringFree(&buf);
Tcl_DStringFree(&hiddenBuf);
if (nameParts != NULL) {
- Tcl_Free((char *) nameParts);
+ ckfree((char *) nameParts);
}
return ensemble;
}
@@ -1591,6 +1642,7 @@ NsEnsembleImplementationCmdNR(
* specified but not yet cached command
* names. */
int reparseCount = 0; /* Number of reparses. */
+ Tcl_Obj *errorObj; /* Used for building error messages. */
/*
* Must recheck objc, since numParameters might have changed. Cf. test
@@ -1615,10 +1667,10 @@ NsEnsembleImplementationCmdNR(
Tcl_Panic("List of ensemble parameters is not a list");
}
for (; len>0; len--,elemPtrs++) {
- Tcl_DStringAppend(&buf, Tcl_GetString(*elemPtrs), -1);
- Tcl_DStringAppend(&buf, " ", -1);
+ TclDStringAppendObj(&buf, *elemPtrs);
+ TclDStringAppendLiteral(&buf, " ");
}
- Tcl_DStringAppend(&buf, "subcommand ?arg ...?", -1);
+ TclDStringAppendLiteral(&buf, "subcommand ?arg ...?");
Tcl_WrongNumArgs(interp, 1, objv, Tcl_DStringValue(&buf));
Tcl_DStringFree(&buf);
@@ -1631,8 +1683,9 @@ NsEnsembleImplementationCmdNR(
*/
if (!Tcl_InterpDeleted(interp)) {
- Tcl_AppendResult(interp,
- "ensemble activated for deleted namespace", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "ensemble activated for deleted namespace", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "DEAD", NULL);
}
return TCL_ERROR;
}
@@ -1652,7 +1705,7 @@ NsEnsembleImplementationCmdNR(
if (objv[1+ensemblePtr->numParameters]->typePtr==&tclEnsembleCmdType){
EnsembleCmdRep *ensembleCmd = objv[1+ensemblePtr->numParameters]
- ->internalRep.otherValuePtr;
+ ->internalRep.twoPtrValue.ptr1;
if (ensembleCmd->nsPtr == ensemblePtr->nsPtr &&
ensembleCmd->epoch == ensemblePtr->epoch &&
@@ -1823,11 +1876,6 @@ NsEnsembleImplementationCmdNR(
* count both as inserted and removed arguments.
*/
-#if 0
- if (TclInitRewriteEnsemble(interp, 2 + ensemblePtr->numParameters, prefixObjc + ensemblePtr->numParameters, objv)) {
- TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
- }
-#else
if (iPtr->ensembleRewrite.sourceObjs == NULL) {
iPtr->ensembleRewrite.sourceObjs = objv;
iPtr->ensembleRewrite.numRemovedObjs =
@@ -1848,14 +1896,13 @@ NsEnsembleImplementationCmdNR(
iPtr->ensembleRewrite.numInsertedObjs += prefixObjc-2;
}
}
-#endif
/*
* Hand off to the target command.
*/
- iPtr->evalFlags |= TCL_EVAL_REDIRECT;
- return Tcl_NREvalObj(interp, copyPtr, TCL_EVAL_INVOKE);
+ TclSkipTailcall(interp);
+ return TclNREvalObjEx(interp, copyPtr, TCL_EVAL_INVOKE, NULL,INT_MIN);
}
unknownOrAmbiguousSubcommand:
@@ -1886,35 +1933,34 @@ NsEnsembleImplementationCmdNR(
*/
Tcl_ResetResult(interp);
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENSEMBLE",
+ Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "SUBCOMMAND",
TclGetString(objv[1+ensemblePtr->numParameters]), NULL);
if (ensemblePtr->subcommandTable.numEntries == 0) {
- Tcl_AppendResult(interp, "unknown subcommand \"",
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown subcommand \"%s\": namespace %s does not"
+ " export any commands",
TclGetString(objv[1+ensemblePtr->numParameters]),
- "\": namespace ", ensemblePtr->nsPtr->fullName,
- " does not export any commands", NULL);
+ ensemblePtr->nsPtr->fullName));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "SUBCOMMAND",
TclGetString(objv[1+ensemblePtr->numParameters]), NULL);
return TCL_ERROR;
}
- Tcl_AppendResult(interp, "unknown ",
- (ensemblePtr->flags & TCL_ENSEMBLE_PREFIX ? "or ambiguous " : ""),
- "subcommand \"", TclGetString(objv[1+ensemblePtr->numParameters]),
- "\": must be ", NULL);
+ errorObj = Tcl_ObjPrintf("unknown%s subcommand \"%s\": must be ",
+ (ensemblePtr->flags & TCL_ENSEMBLE_PREFIX ? " or ambiguous" : ""),
+ TclGetString(objv[1+ensemblePtr->numParameters]));
if (ensemblePtr->subcommandTable.numEntries == 1) {
- Tcl_AppendResult(interp, ensemblePtr->subcommandArrayPtr[0], NULL);
+ Tcl_AppendToObj(errorObj, ensemblePtr->subcommandArrayPtr[0], -1);
} else {
int i;
for (i=0 ; i<ensemblePtr->subcommandTable.numEntries-1 ; i++) {
- Tcl_AppendResult(interp,
- ensemblePtr->subcommandArrayPtr[i], ", ", NULL);
+ Tcl_AppendToObj(errorObj, ensemblePtr->subcommandArrayPtr[i], -1);
+ Tcl_AppendToObj(errorObj, ", ", 2);
}
- Tcl_AppendResult(interp, "or ",
- ensemblePtr->subcommandArrayPtr[i], NULL);
+ Tcl_AppendPrintfToObj(errorObj, "or %s",
+ ensemblePtr->subcommandArrayPtr[i]);
}
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "SUBCOMMAND",
- TclGetString(objv[1+ensemblePtr->numParameters]), NULL);
+ Tcl_SetObjResult(interp, errorObj);
return TCL_ERROR;
}
@@ -2040,7 +2086,6 @@ EnsembleUnknownCallback(
{
int paramc, i, result, prefixObjc;
Tcl_Obj **paramv, *unknownCmd, *ensObj;
- char buf[TCL_INTEGER_SPACE];
/*
* Create the unknown command callback to determine what to do.
@@ -2064,12 +2109,15 @@ EnsembleUnknownCallback(
*/
Tcl_Preserve(ensemblePtr);
- ((Interp *) interp)->evalFlags |= TCL_EVAL_REDIRECT;
+ TclSkipTailcall(interp);
result = Tcl_EvalObjv(interp, paramc, paramv, 0);
if ((result == TCL_OK) && (ensemblePtr->flags & ENSEMBLE_DEAD)) {
- Tcl_SetResult(interp,
- "unknown subcommand handler deleted its ensemble",
- TCL_STATIC);
+ if (!Tcl_InterpDeleted(interp)) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "unknown subcommand handler deleted its ensemble", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "UNKNOWN_DELETED",
+ NULL);
+ }
result = TCL_ERROR;
}
Tcl_Release(ensemblePtr);
@@ -2118,26 +2166,26 @@ EnsembleUnknownCallback(
if (!Tcl_InterpDeleted(interp)) {
if (result != TCL_ERROR) {
Tcl_ResetResult(interp);
- Tcl_SetResult(interp,
- "unknown subcommand handler returned bad code: ",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "unknown subcommand handler returned bad code: ", -1));
switch (result) {
case TCL_RETURN:
- Tcl_AppendResult(interp, "return", NULL);
+ Tcl_AppendToObj(Tcl_GetObjResult(interp), "return", -1);
break;
case TCL_BREAK:
- Tcl_AppendResult(interp, "break", NULL);
+ Tcl_AppendToObj(Tcl_GetObjResult(interp), "break", -1);
break;
case TCL_CONTINUE:
- Tcl_AppendResult(interp, "continue", NULL);
+ Tcl_AppendToObj(Tcl_GetObjResult(interp), "continue", -1);
break;
default:
- sprintf(buf, "%d", result);
- Tcl_AppendResult(interp, buf, NULL);
+ Tcl_AppendPrintfToObj(Tcl_GetObjResult(interp), "%d", result);
}
Tcl_AddErrorInfo(interp, "\n result of "
"ensemble unknown subcommand handler: ");
- Tcl_AddErrorInfo(interp, TclGetString(unknownCmd));
+ Tcl_AppendObjToErrorInfo(interp, unknownCmd);
+ Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "UNKNOWN_RESULT",
+ NULL);
} else {
Tcl_AddErrorInfo(interp,
"\n (ensemble unknown subcommand handler)");
@@ -2177,7 +2225,7 @@ MakeCachedEnsembleCommand(
int length;
if (objPtr->typePtr == &tclEnsembleCmdType) {
- ensembleCmd = objPtr->internalRep.otherValuePtr;
+ ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
Tcl_DecrRefCount(ensembleCmd->realPrefixObj);
TclNsDecrRefCount(ensembleCmd->nsPtr);
ckfree(ensembleCmd->fullSubcmdName);
@@ -2189,7 +2237,7 @@ MakeCachedEnsembleCommand(
TclFreeIntRep(objPtr);
ensembleCmd = ckalloc(sizeof(EnsembleCmdRep));
- objPtr->internalRep.otherValuePtr = ensembleCmd;
+ objPtr->internalRep.twoPtrValue.ptr1 = ensembleCmd;
objPtr->typePtr = &tclEnsembleCmdType;
}
@@ -2398,7 +2446,7 @@ BuildEnsembleConfig(
* the programmer's responsibility (or [::unknown] of course).
*/
- cmdObj = Tcl_NewStringObj(ensemblePtr->nsPtr->fullName, -1);
+ cmdObj = NewNsObj((Tcl_Namespace *) ensemblePtr->nsPtr);
if (ensemblePtr->nsPtr->parentPtr != NULL) {
Tcl_AppendStringsToObj(cmdObj, "::", name, NULL);
} else {
@@ -2584,7 +2632,7 @@ static void
FreeEnsembleCmdRep(
Tcl_Obj *objPtr)
{
- EnsembleCmdRep *ensembleCmd = objPtr->internalRep.otherValuePtr;
+ EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
Tcl_DecrRefCount(ensembleCmd->realPrefixObj);
ckfree(ensembleCmd->fullSubcmdName);
@@ -2616,12 +2664,12 @@ DupEnsembleCmdRep(
Tcl_Obj *objPtr,
Tcl_Obj *copyPtr)
{
- EnsembleCmdRep *ensembleCmd = objPtr->internalRep.otherValuePtr;
+ EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
EnsembleCmdRep *ensembleCopy = ckalloc(sizeof(EnsembleCmdRep));
int length = strlen(ensembleCmd->fullSubcmdName);
copyPtr->typePtr = &tclEnsembleCmdType;
- copyPtr->internalRep.otherValuePtr = ensembleCopy;
+ copyPtr->internalRep.twoPtrValue.ptr1 = ensembleCopy;
ensembleCopy->nsPtr = ensembleCmd->nsPtr;
ensembleCopy->epoch = ensembleCmd->epoch;
ensembleCopy->token = ensembleCmd->token;
@@ -2654,7 +2702,7 @@ static void
StringOfEnsembleCmdRep(
Tcl_Obj *objPtr)
{
- EnsembleCmdRep *ensembleCmd = objPtr->internalRep.otherValuePtr;
+ EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
int length = strlen(ensembleCmd->fullSubcmdName);
objPtr->length = length;
@@ -2692,25 +2740,33 @@ TclCompileEnsemble(
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
- Tcl_Token *tokenPtr;
+ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
Tcl_Obj *mapObj, *subcmdObj, *targetCmdObj, *listObj, **elems;
+ Tcl_Obj *replaced = Tcl_NewObj(), *replacement;
Tcl_Command ensemble = (Tcl_Command) cmdPtr;
- Tcl_Parse synthetic;
- int len, result, flags = 0, i;
+ Command *oldCmdPtr = cmdPtr, *newCmdPtr;
+ int len, result, flags = 0, i, depth = 1, invokeAnyway = 0;
+ int ourResult = TCL_ERROR;
unsigned numBytes;
const char *word;
- if (parsePtr->numWords < 2) {
- return TCL_ERROR;
- }
+ Tcl_IncrRefCount(replaced);
+
+ /*
+ * This is where we return to if we are parsing multiple nested compiled
+ * ensembles. [info object] is such a beast.
+ */
- tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ checkNextWord:
+ if (parsePtr->numWords < depth + 1) {
+ goto failed;
+ }
if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
/*
* Too hard.
*/
- return TCL_ERROR;
+ goto failed;
}
word = tokenPtr[1].start;
@@ -2729,7 +2785,7 @@ TclCompileEnsemble(
* to proceed.
*/
- return TCL_ERROR;
+ goto failed;
}
/*
@@ -2743,7 +2799,7 @@ TclCompileEnsemble(
* Figuring out how to compile this has become too much. Bail out.
*/
- return TCL_ERROR;
+ goto failed;
}
/*
@@ -2766,7 +2822,7 @@ TclCompileEnsemble(
Tcl_Obj *matchObj = NULL;
if (Tcl_ListObjGetElements(NULL, listObj, &len, &elems) != TCL_OK) {
- return TCL_ERROR;
+ goto failed;
}
for (i=0 ; i<len ; i++) {
str = Tcl_GetStringFromObj(elems[i], &sclen);
@@ -2777,8 +2833,9 @@ TclCompileEnsemble(
result = Tcl_DictObjGet(NULL, mapObj,elems[i], &targetCmdObj);
if (result != TCL_OK || targetCmdObj == NULL) {
- return TCL_ERROR;
+ goto failed;
}
+ replacement = elems[i];
goto doneMapLookup;
}
@@ -2794,18 +2851,19 @@ TclCompileEnsemble(
if ((flags & TCL_ENSEMBLE_PREFIX)
&& strncmp(word, str, numBytes) == 0) {
if (matchObj != NULL) {
- return TCL_ERROR;
+ goto failed;
}
matchObj = elems[i];
}
}
if (matchObj == NULL) {
- return TCL_ERROR;
+ goto failed;
}
result = Tcl_DictObjGet(NULL, mapObj, matchObj, &targetCmdObj);
if (result != TCL_OK || targetCmdObj == NULL) {
- return TCL_ERROR;
+ goto failed;
}
+ replacement = matchObj;
} else {
Tcl_DictSearch s;
int done, matched;
@@ -2817,14 +2875,15 @@ TclCompileEnsemble(
TclNewStringObj(subcmdObj, word, (int) numBytes);
result = Tcl_DictObjGet(NULL, mapObj, subcmdObj, &targetCmdObj);
- TclDecrRefCount(subcmdObj);
if (result == TCL_OK && targetCmdObj != NULL) {
/*
* Got it. Skip the fiddling around with prefixes.
*/
+ replacement = subcmdObj;
goto doneMapLookup;
}
+ TclDecrRefCount(subcmdObj);
/*
* We've not literally got a valid subcommand. But maybe we have a
@@ -2832,7 +2891,7 @@ TclCompileEnsemble(
*/
if (!(flags & TCL_ENSEMBLE_PREFIX)) {
- return TCL_ERROR;
+ goto failed;
}
/*
@@ -2842,6 +2901,7 @@ TclCompileEnsemble(
Tcl_DictObjFirst(NULL, mapObj, &s, &subcmdObj, &tmpObj, &done);
matched = 0;
+ replacement = NULL; /* Silence, fool compiler! */
while (!done) {
if (strncmp(TclGetString(subcmdObj), word, numBytes) == 0) {
if (matched++) {
@@ -2852,6 +2912,7 @@ TclCompileEnsemble(
break;
}
+ replacement = subcmdObj;
targetCmdObj = tmpObj;
}
Tcl_DictObjNext(&s, &subcmdObj, &tmpObj, &done);
@@ -2864,7 +2925,8 @@ TclCompileEnsemble(
*/
if (matched != 1) {
- return TCL_ERROR;
+ invokeAnyway = 1;
+ goto failed;
}
}
@@ -2878,87 +2940,542 @@ TclCompileEnsemble(
*/
doneMapLookup:
+ Tcl_ListObjAppendElement(NULL, replaced, replacement);
if (Tcl_ListObjGetElements(NULL, targetCmdObj, &len, &elems) != TCL_OK) {
- return TCL_ERROR;
- }
- if (len > 1 && Tcl_IsSafe(interp)) {
- return TCL_ERROR;
+ goto failed;
+ } else if (len != 1) {
+ /*
+ * Note that at this point we know we can't issue any special
+ * instruction sequence as the mapping isn't one that we support at
+ * the compiled level.
+ */
+
+ goto cleanup;
}
targetCmdObj = elems[0];
+ oldCmdPtr = cmdPtr;
Tcl_IncrRefCount(targetCmdObj);
- cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, targetCmdObj);
+ newCmdPtr = (Command *) Tcl_GetCommandFromObj(interp, targetCmdObj);
TclDecrRefCount(targetCmdObj);
- if (cmdPtr == NULL || cmdPtr->compileProc == NULL) {
+ if (newCmdPtr == NULL || Tcl_IsSafe(interp)
+ || newCmdPtr->nsPtr->flags & NS_SUPPRESS_COMPILATION
+ || newCmdPtr->flags & CMD_HAS_EXEC_TRACES
+ || ((Interp *)interp)->flags & DONT_COMPILE_CMDS_INLINE) {
/*
* Maps to an undefined command or a command without a compiler.
* Cannot compile.
*/
- return TCL_ERROR;
+ goto cleanup;
}
+ cmdPtr = newCmdPtr;
+ depth++;
/*
- * Now we've done the mapping process, can now actually try to compile.
- * We do this by handing off to the subcommand's actual compiler. But to
- * do that, we have to perform some trickery to rewrite the arguments.
+ * See whether we have a nested ensemble. If we do, we can go round the
+ * mulberry bush again, consuming the next word.
*/
- TclParseInit(interp, NULL, 0, &synthetic);
- synthetic.numWords = parsePtr->numWords - 2 + len;
- TclGrowParseTokenArray(&synthetic, 2*len);
- synthetic.numTokens = 2*len;
+ if (cmdPtr->compileProc == TclCompileEnsemble) {
+ tokenPtr = TokenAfter(tokenPtr);
+ ensemble = (Tcl_Command) cmdPtr;
+ goto checkNextWord;
+ }
/*
- * Now we have the space to work in, install something rewritten. Note
- * that we are here praying for all our might that none of these words are
- * a script; the error detection code will crash if that happens and there
- * is nothing we can do to avoid it!
+ * Now we've done the mapping process, can now actually try to compile.
+ * If there is a subcommand compiler and that successfully produces code,
+ * we'll use that. Otherwise, we fall back to generating opcodes to do the
+ * invoke at runtime.
*/
- for (i=0 ; i<len ; i++) {
- int sclen;
- const char *str = Tcl_GetStringFromObj(elems[i], &sclen);
+ invokeAnyway = 1;
+ if (TCL_OK == TclAttemptCompileProc(interp, parsePtr, depth, cmdPtr,
+ envPtr)) {
+ ourResult = TCL_OK;
+ goto cleanup;
+ }
- synthetic.tokenPtr[2*i].type = TCL_TOKEN_SIMPLE_WORD;
- synthetic.tokenPtr[2*i].start = str;
- synthetic.tokenPtr[2*i].size = sclen;
- synthetic.tokenPtr[2*i].numComponents = 1;
+ /*
+ * Failed to do a full compile for some reason. Try to do a direct invoke
+ * instead of going through the ensemble lookup process again.
+ */
- synthetic.tokenPtr[2*i+1].type = TCL_TOKEN_TEXT;
- synthetic.tokenPtr[2*i+1].start = str;
- synthetic.tokenPtr[2*i+1].size = sclen;
- synthetic.tokenPtr[2*i+1].numComponents = 0;
+ failed:
+ if (depth < 250) {
+ if (depth > 1) {
+ if (!invokeAnyway) {
+ cmdPtr = oldCmdPtr;
+ depth--;
+ }
+ (void) Tcl_ListObjReplace(NULL, replaced, depth, 2, 0, NULL);
+ }
+ CompileToInvokedCommand(interp, parsePtr, replaced, cmdPtr, envPtr);
+ ourResult = TCL_OK;
}
/*
- * Copy over the real argument tokens.
+ * Release the memory we allocated. If we've got here, we've either done
+ * something useful or we're in a case that we can't compile at all and
+ * we're just giving up.
*/
- for (i=len; i<synthetic.numWords; i++) {
- int toCopy;
+ cleanup:
+ Tcl_DecrRefCount(replaced);
+ return ourResult;
+}
- tokenPtr = TokenAfter(tokenPtr);
- toCopy = tokenPtr->numComponents + 1;
- TclGrowParseTokenArray(&synthetic, toCopy);
- memcpy(synthetic.tokenPtr + synthetic.numTokens, tokenPtr,
- sizeof(Tcl_Token) * toCopy);
- synthetic.numTokens += toCopy;
+int
+TclAttemptCompileProc(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ int depth,
+ Command *cmdPtr,
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ int result, i;
+ Tcl_Token *saveTokenPtr = parsePtr->tokenPtr;
+ int savedStackDepth = envPtr->currStackDepth;
+ unsigned savedCodeNext = envPtr->codeNext - envPtr->codeStart;
+ DefineLineInformation;
+
+ if (cmdPtr->compileProc == NULL) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Advance parsePtr->tokenPtr so that it points at the last subcommand.
+ * This will be wrong, but it will not matter, and it will put the
+ * tokens for the arguments in the right place without the needed to
+ * allocate a synthetic Tcl_Parse struct, or copy tokens around.
+ */
+
+ for (i = 0; i < depth - 1; i++) {
+ parsePtr->tokenPtr = TokenAfter(parsePtr->tokenPtr);
}
+ parsePtr->numWords -= (depth - 1);
+
+ /*
+ * Shift the line information arrays to account for different word
+ * index values.
+ */
+
+ mapPtr->loc[eclIndex].line += (depth - 1);
+ mapPtr->loc[eclIndex].next += (depth - 1);
/*
* Hand off compilation to the subcommand compiler. At last!
*/
- result = cmdPtr->compileProc(interp, &synthetic, cmdPtr, envPtr);
+ result = cmdPtr->compileProc(interp, parsePtr, cmdPtr, envPtr);
+
+ /*
+ * Undo the shift.
+ */
+
+ mapPtr->loc[eclIndex].line -= (depth - 1);
+ mapPtr->loc[eclIndex].next -= (depth - 1);
+
+ parsePtr->numWords += (depth - 1);
+ parsePtr->tokenPtr = saveTokenPtr;
/*
- * Clean up if necessary.
+ * If our target failed to compile, revert any data from failed partial
+ * compiles. Note that envPtr->numCommands need not be checked because
+ * we avoid compiling subcommands that recursively call TclCompileScript().
*/
- Tcl_FreeParse(&synthetic);
+ if (result != TCL_OK) {
+ envPtr->currStackDepth = savedStackDepth;
+ envPtr->codeNext = envPtr->codeStart + savedCodeNext;
+#ifdef TCL_COMPILE_DEBUG
+ } else {
+ /*
+ * Confirm that the command compiler generated a single value on
+ * the stack as its result. This is only done in debugging mode,
+ * as it *should* be correct and normal users have no reasonable
+ * way to fix it anyway.
+ */
+
+ int diff = envPtr->currStackDepth - savedStackDepth;
+
+ if (diff != 1) {
+ Tcl_Panic("bad stack adjustment when compiling"
+ " %.*s (was %d instead of 1)", parsePtr->tokenPtr->size,
+ parsePtr->tokenPtr->start, diff);
+ }
+#endif
+ }
+
return result;
}
+
+/*
+ * How to compile a subcommand to a _replacing_ invoke of its implementation
+ * command.
+ */
+
+static void
+CompileToInvokedCommand(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Tcl_Obj *replacements,
+ Command *cmdPtr,
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Token *tokPtr;
+ Tcl_Obj *objPtr, **words;
+ char *bytes;
+ int length, i, numWords, cmdLit;
+ DefineLineInformation;
+
+ /*
+ * Push the words of the command. Take care; the command words may be
+ * scripts that have backslashes in them, and [info frame 0] can see the
+ * difference. Hence the call to TclContinuationsEnterDerived...
+ */
+
+ Tcl_ListObjGetElements(NULL, replacements, &numWords, &words);
+ for (i = 0, tokPtr = parsePtr->tokenPtr; i < parsePtr->numWords;
+ i++, tokPtr = TokenAfter(tokPtr)) {
+ if (i > 0 && i < numWords+1) {
+ bytes = Tcl_GetStringFromObj(words[i-1], &length);
+ PushLiteral(envPtr, bytes, length);
+ continue;
+ }
+
+ SetLineInformation(i);
+ if (tokPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+ int literal = TclRegisterNewLiteral(envPtr,
+ tokPtr[1].start, tokPtr[1].size);
+
+ if (envPtr->clNext) {
+ TclContinuationsEnterDerived(
+ TclFetchLiteral(envPtr, literal),
+ tokPtr[1].start - envPtr->source,
+ envPtr->clNext);
+ }
+ TclEmitPush(literal, envPtr);
+ } else {
+ CompileTokens(envPtr, tokPtr, interp);
+ }
+ }
+
+ /*
+ * Push the name of the command we're actually dispatching to as part of
+ * the implementation.
+ */
+
+ objPtr = Tcl_NewObj();
+ Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, objPtr);
+ bytes = Tcl_GetStringFromObj(objPtr, &length);
+ cmdLit = TclRegisterNewCmdLiteral(envPtr, bytes, length);
+ TclSetCmdNameObj(interp, TclFetchLiteral(envPtr, cmdLit), cmdPtr);
+ TclEmitPush(cmdLit, envPtr);
+ TclDecrRefCount(objPtr);
+
+ /*
+ * Do the replacing dispatch.
+ */
+
+ TclEmitInvoke(envPtr, INST_INVOKE_REPLACE, parsePtr->numWords,numWords+1);
+}
+
+/*
+ * Helpers that do issuing of instructions for commands that "don't have
+ * compilers" (well, they do; these). They all work by just generating base
+ * code to invoke the command; they're intended for ensemble subcommands so
+ * that the costs of INST_INVOKE_REPLACE can be avoided where we can work out
+ * that they're not needed.
+ *
+ * Note that these are NOT suitable for commands where there's an argument
+ * that is a script, as an [info level] or [info frame] in the inner context
+ * can see the difference.
+ */
+
+static int
+CompileBasicNArgCommand(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ Tcl_Obj *objPtr = Tcl_NewObj();
+
+ Tcl_IncrRefCount(objPtr);
+ Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, objPtr);
+ TclCompileInvocation(interp, parsePtr->tokenPtr, objPtr,
+ parsePtr->numWords, envPtr);
+ Tcl_DecrRefCount(objPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileBasic0ArgCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Verify that the number of arguments is correct; that's the only case
+ * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+ * which is the only code that sees the shenanigans of ensemble dispatch.
+ */
+
+ if (parsePtr->numWords != 1) {
+ return TCL_ERROR;
+ }
+
+ return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic1ArgCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Verify that the number of arguments is correct; that's the only case
+ * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+ * which is the only code that sees the shenanigans of ensemble dispatch.
+ */
+
+ if (parsePtr->numWords != 2) {
+ return TCL_ERROR;
+ }
+
+ return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic2ArgCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Verify that the number of arguments is correct; that's the only case
+ * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+ * which is the only code that sees the shenanigans of ensemble dispatch.
+ */
+
+ if (parsePtr->numWords != 3) {
+ return TCL_ERROR;
+ }
+
+ return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic3ArgCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Verify that the number of arguments is correct; that's the only case
+ * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+ * which is the only code that sees the shenanigans of ensemble dispatch.
+ */
+
+ if (parsePtr->numWords != 4) {
+ return TCL_ERROR;
+ }
+
+ return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic0Or1ArgCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Verify that the number of arguments is correct; that's the only case
+ * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+ * which is the only code that sees the shenanigans of ensemble dispatch.
+ */
+
+ if (parsePtr->numWords != 1 && parsePtr->numWords != 2) {
+ return TCL_ERROR;
+ }
+
+ return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic1Or2ArgCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Verify that the number of arguments is correct; that's the only case
+ * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+ * which is the only code that sees the shenanigans of ensemble dispatch.
+ */
+
+ if (parsePtr->numWords != 2 && parsePtr->numWords != 3) {
+ return TCL_ERROR;
+ }
+
+ return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic2Or3ArgCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Verify that the number of arguments is correct; that's the only case
+ * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+ * which is the only code that sees the shenanigans of ensemble dispatch.
+ */
+
+ if (parsePtr->numWords != 3 && parsePtr->numWords != 4) {
+ return TCL_ERROR;
+ }
+
+ return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic0To2ArgCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Verify that the number of arguments is correct; that's the only case
+ * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+ * which is the only code that sees the shenanigans of ensemble dispatch.
+ */
+
+ if (parsePtr->numWords < 1 || parsePtr->numWords > 3) {
+ return TCL_ERROR;
+ }
+
+ return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic1To3ArgCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Verify that the number of arguments is correct; that's the only case
+ * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+ * which is the only code that sees the shenanigans of ensemble dispatch.
+ */
+
+ if (parsePtr->numWords < 2 || parsePtr->numWords > 4) {
+ return TCL_ERROR;
+ }
+
+ return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasicMin0ArgCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Verify that the number of arguments is correct; that's the only case
+ * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+ * which is the only code that sees the shenanigans of ensemble dispatch.
+ */
+
+ if (parsePtr->numWords < 1) {
+ return TCL_ERROR;
+ }
+
+ return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasicMin1ArgCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Verify that the number of arguments is correct; that's the only case
+ * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+ * which is the only code that sees the shenanigans of ensemble dispatch.
+ */
+
+ if (parsePtr->numWords < 2) {
+ return TCL_ERROR;
+ }
+
+ return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasicMin2ArgCmd(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Parse *parsePtr, /* Points to a parse structure for the command
+ * created by Tcl_ParseCommand. */
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr) /* Holds resulting instructions. */
+{
+ /*
+ * Verify that the number of arguments is correct; that's the only case
+ * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+ * which is the only code that sees the shenanigans of ensemble dispatch.
+ */
+
+ if (parsePtr->numWords < 3) {
+ return TCL_ERROR;
+ }
+
+ return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
/*
* Local Variables:
diff --git a/generic/tclEnv.c b/generic/tclEnv.c
index 980a785..cd1a954 100644
--- a/generic/tclEnv.c
+++ b/generic/tclEnv.c
@@ -45,11 +45,8 @@ MODULE_SCOPE void TclSetEnv(const char *name, const char *value);
MODULE_SCOPE void TclUnsetEnv(const char *name);
#if defined(__CYGWIN__)
-/* On Cygwin, the environment is imported from the Cygwin DLL. */
- DLLIMPORT extern int cygwin_posix_to_win32_path_list_buf_size(char *value);
- DLLIMPORT extern void cygwin_posix_to_win32_path_list(char *buf, char *value);
-# define putenv TclCygwinPutenv
-static void TclCygwinPutenv(char *string);
+ static void TclCygwinPutenv(char *string);
+# define putenv TclCygwinPutenv
#endif
/*
@@ -79,36 +76,56 @@ TclSetupEnv(
Tcl_Interp *interp) /* Interpreter whose "env" array is to be
* managed. */
{
+ Var *varPtr, *arrayPtr;
+ Tcl_Obj *varNamePtr;
Tcl_DString envString;
- char *p1, *p2;
- int i;
+ Tcl_HashTable namesHash;
+ Tcl_HashEntry *hPtr;
+ Tcl_HashSearch search;
/*
* Synchronize the values in the environ array with the contents of the
* Tcl "env" variable. To do this:
- * 1) Remove the trace that fires when the "env" var is unset.
- * 2) Unset the "env" variable.
- * 3) If there are no environ variables, create an empty "env" array.
- * Otherwise populate the array with current values.
- * 4) Add a trace that synchronizes the "env" array.
+ * 1) Remove the trace that fires when the "env" var is updated.
+ * 2) Find the existing contents of the "env", storing in a hash table.
+ * 3) Create/update elements for each environ variable, removing
+ * elements from the hash table as we go.
+ * 4) Remove the elements for each remaining entry in the hash table,
+ * which must have existed before yet have no analog in the environ
+ * variable.
+ * 5) Add a trace that synchronizes the "env" array.
*/
Tcl_UntraceVar2(interp, "env", NULL,
TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS |
TCL_TRACE_READS | TCL_TRACE_ARRAY, EnvTraceProc, NULL);
- Tcl_UnsetVar2(interp, "env", NULL, TCL_GLOBAL_ONLY);
+ /*
+ * Find out what elements are currently in the global env array.
+ */
- if (environ[0] == NULL) {
- Tcl_Obj *varNamePtr;
+ TclNewLiteralStringObj(varNamePtr, "env");
+ Tcl_IncrRefCount(varNamePtr);
+ Tcl_InitObjHashTable(&namesHash);
+ varPtr = TclObjLookupVarEx(interp, varNamePtr, NULL, TCL_GLOBAL_ONLY,
+ /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+ TclFindArrayPtrElements(varPtr, &namesHash);
+
+ /*
+ * Go through the environment array and transfer its values into Tcl. At
+ * the same time, remove those elements we add/update from the hash table
+ * of existing elements, so that after this part processes, that table
+ * will hold just the parts to remove.
+ */
+
+ if (environ[0] != NULL) {
+ int i;
- TclNewLiteralStringObj(varNamePtr, "env");
- Tcl_IncrRefCount(varNamePtr);
- TclArraySet(interp, varNamePtr, NULL);
- Tcl_DecrRefCount(varNamePtr);
- } else {
Tcl_MutexLock(&envMutex);
for (i = 0; environ[i] != NULL; i++) {
+ Tcl_Obj *obj1, *obj2;
+ char *p1, *p2;
+
p1 = Tcl_ExternalToUtfDString(NULL, environ[i], -1, &envString);
p2 = strchr(p1, '=');
if (p2 == NULL) {
@@ -122,12 +139,41 @@ TclSetupEnv(
}
p2++;
p2[-1] = '\0';
- Tcl_SetVar2(interp, "env", p1, p2, TCL_GLOBAL_ONLY);
+ obj1 = Tcl_NewStringObj(p1, -1);
+ obj2 = Tcl_NewStringObj(p2, -1);
Tcl_DStringFree(&envString);
+
+ Tcl_IncrRefCount(obj1);
+ Tcl_IncrRefCount(obj2);
+ Tcl_ObjSetVar2(interp, varNamePtr, obj1, obj2, TCL_GLOBAL_ONLY);
+ hPtr = Tcl_FindHashEntry(&namesHash, obj1);
+ if (hPtr != NULL) {
+ Tcl_DeleteHashEntry(hPtr);
+ }
+ Tcl_DecrRefCount(obj1);
+ Tcl_DecrRefCount(obj2);
}
Tcl_MutexUnlock(&envMutex);
}
+ /*
+ * Delete those elements that existed in the array but which had no
+ * counterparts in the environment array.
+ */
+
+ for (hPtr=Tcl_FirstHashEntry(&namesHash, &search); hPtr!=NULL;
+ hPtr=Tcl_NextHashEntry(&search)) {
+ Tcl_Obj *elemName = Tcl_GetHashValue(hPtr);
+
+ TclObjUnsetVar2(interp, varNamePtr, elemName, TCL_GLOBAL_ONLY);
+ }
+ Tcl_DeleteHashTable(&namesHash);
+ Tcl_DecrRefCount(varNamePtr);
+
+ /*
+ * Re-establish the trace.
+ */
+
Tcl_TraceVar2(interp, "env", NULL,
TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS |
TCL_TRACE_READS | TCL_TRACE_ARRAY, EnvTraceProc, NULL);
@@ -398,7 +444,7 @@ TclUnsetEnv(
* that no = should be included, and Windows requires it.
*/
-#if defined(__WIN32__) || defined(__CYGWIN__)
+#if defined(_WIN32) || defined(__CYGWIN__)
string = ckalloc(length + 2);
memcpy(string, name, (size_t) length);
string[length] = '=';
@@ -407,7 +453,7 @@ TclUnsetEnv(
string = ckalloc(length + 1);
memcpy(string, name, (size_t) length);
string[length] = '\0';
-#endif /* WIN32 */
+#endif /* _WIN32 */
Tcl_UtfToExternalDString(NULL, string, -1, &envString);
string = ckrealloc(string, Tcl_DStringLength(&envString) + 1);
@@ -568,7 +614,8 @@ EnvTraceProc(
const char *value = TclGetEnv(name2, &valueString);
if (value == NULL) {
- return (char *) "no such variable";
+ Tcl_UnsetVar2(interp, name1, name2, 0);
+ return NULL;
}
Tcl_SetVar2(interp, name1, name2, value, 0);
Tcl_DStringFree(&valueString);
@@ -701,6 +748,7 @@ TclFinalizeEnvironment(void)
* fork) and the Windows environment (in case the application TCL code calls
* exec, which calls the Windows CreateProcess function).
*/
+DLLIMPORT extern void __stdcall SetEnvironmentVariableA(const char*, const char *);
static void
TclCygwinPutenv(
@@ -754,15 +802,11 @@ TclCygwinPutenv(
*/
if (strcmp(name, "Path") == 0) {
-#ifdef __WIN32__
SetEnvironmentVariableA("PATH", NULL);
-#endif
unsetenv("PATH");
}
-#ifdef __WIN32__
SetEnvironmentVariableA(name, value);
-#endif
} else {
char *buf;
@@ -770,9 +814,7 @@ TclCygwinPutenv(
* Eliminate any Path variable, to prevent any confusion.
*/
-#ifdef __WIN32__
SetEnvironmentVariableA("Path", NULL);
-#endif
unsetenv("Path");
if (value == NULL) {
@@ -780,14 +822,12 @@ TclCygwinPutenv(
} else {
int size;
- size = cygwin_posix_to_win32_path_list_buf_size(value);
+ size = cygwin_conv_path_list(0, value, NULL, 0);
buf = alloca(size + 1);
- cygwin_posix_to_win32_path_list(value, buf);
+ cygwin_conv_path_list(0, value, buf, size);
}
-#ifdef __WIN32__
SetEnvironmentVariableA(name, buf);
-#endif
}
}
#endif /* __CYGWIN__ */
diff --git a/generic/tclEvent.c b/generic/tclEvent.c
index e65862c..941d566 100644
--- a/generic/tclEvent.c
+++ b/generic/tclEvent.c
@@ -1030,14 +1030,8 @@ TclInitSubsystems(void)
TclpInitLock();
if (subsystemsInitialized == 0) {
- /*
- * Have to set this bit here to avoid deadlock with the routines
- * below us that call into TclInitSubsystems.
- */
-
- subsystemsInitialized = 1;
- /*
+ /*
* Initialize locks used by the memory allocators before anything
* interesting happens so we can use the allocators in the
* implementation of self-initializing locks.
@@ -1061,6 +1055,7 @@ TclInitSubsystems(void)
TclInitEncodingSubsystem(); /* Process wide encoding init. */
TclpSetInterfaces();
TclInitNamespaceSubsystem();/* Register ns obj type (mutexed). */
+ subsystemsInitialized = 1;
}
TclpInitUnlock();
}
@@ -1176,8 +1171,6 @@ Tcl_Finalize(void)
TclFinalizeEncodingSubsystem();
- Tcl_SetPanicProc(NULL);
-
/*
* Repeat finalization of the thread local storage once more. Although
* this step is already done by the Tcl_FinalizeThread call above, series
@@ -1402,7 +1395,7 @@ Tcl_VwaitObjCmd(
return TCL_ERROR;
}
nameString = Tcl_GetString(objv[1]);
- if (Tcl_TraceVar(interp, nameString,
+ if (Tcl_TraceVar2(interp, nameString, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
VwaitVarProc, &done) != TCL_OK) {
return TCL_ERROR;
@@ -1416,18 +1409,19 @@ Tcl_VwaitObjCmd(
}
if (Tcl_LimitExceeded(interp)) {
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "limit exceeded", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("limit exceeded", -1));
break;
}
}
- Tcl_UntraceVar(interp, nameString,
+ Tcl_UntraceVar2(interp, nameString, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
VwaitVarProc, &done);
if (!foundEvent) {
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "can't wait for variable \"", nameString,
- "\": would wait forever", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't wait for variable \"%s\": would wait forever",
+ nameString));
Tcl_SetErrorCode(interp, "TCL", "EVENT", "NO_SOURCES", NULL);
return TCL_ERROR;
}
@@ -1519,7 +1513,7 @@ Tcl_UpdateObjCmd(
}
if (Tcl_LimitExceeded(interp)) {
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "limit exceeded", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("limit exceeded", -1));
return TCL_ERROR;
}
}
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 691c8d7..4ecca5b 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -17,6 +17,7 @@
#include "tclInt.h"
#include "tclCompile.h"
+#include "tclOOInt.h"
#include "tommath.h"
#include <math.h>
@@ -173,32 +174,32 @@ static BuiltinFunc const tclBuiltinFuncTable[] = {
typedef struct TEBCdata {
ByteCode *codePtr; /* Constant until the BC returns */
/* -----------------------------------------*/
- const unsigned char *pc; /* These fields are used on return TO this */
- ptrdiff_t *catchTop; /* this level: they record the state when a */
- int cleanup; /* new codePtr was received for NR */
- Tcl_Obj *auxObjList; /* execution. */
- int checkInterp;
- CmdFrame cmdFrame;
- void * stack[1]; /* Start of the actual combined catch and obj
+ ptrdiff_t *catchTop; /* These fields are used on return TO this */
+ Tcl_Obj *auxObjList; /* this level: they record the state when a */
+ CmdFrame cmdFrame; /* new codePtr was received for NR */
+ /* execution. */
+ void *stack[1]; /* Start of the actual combined catch and obj
* stacks; the struct will be expanded as
* necessary */
} TEBCdata;
-#define TEBC_YIELD() \
- esPtr->tosPtr = tosPtr; \
- TD->pc = pc; \
- TD->cleanup = cleanup; \
- TclNRAddCallback(interp, TEBCresume, TD, \
- INT2PTR(1), NULL, NULL)
-
+#define TEBC_YIELD() \
+ do { \
+ esPtr->tosPtr = tosPtr; \
+ TclNRAddCallback(interp, TEBCresume, \
+ TD, pc, INT2PTR(cleanup), NULL); \
+ } while (0)
+
#define TEBC_DATA_DIG() \
- pc = TD->pc; \
- cleanup = TD->cleanup; \
- tosPtr = esPtr->tosPtr
-
+ do { \
+ tosPtr = esPtr->tosPtr; \
+ } while (0)
#define PUSH_TAUX_OBJ(objPtr) \
do { \
+ if (auxObjList) { \
+ objPtr->length += auxObjList->length; \
+ } \
objPtr->internalRep.ptrAndLongRep.ptr = auxObjList; \
auxObjList = objPtr; \
} while (0)
@@ -248,13 +249,27 @@ VarHashCreateVar(
* otherwise, push objResultPtr. If (result < 0), objResultPtr already
* has the correct reference count.
*
- * We use the new compile-time assertions to cheack that nCleanup is constant
+ * We use the new compile-time assertions to check that nCleanup is constant
* and within range.
*/
-#define NEXT_INST_F(pcAdjustment, nCleanup, resultHandling) \
+/* Verify the stack depth, only when no expansion is in progress */
+
+#ifdef TCL_COMPILE_DEBUG
+#define CHECK_STACK() \
+ do { \
+ ValidatePcAndStackTop(codePtr, pc, CURR_DEPTH, \
+ /*checkStack*/ !(starting || auxObjList)); \
+ starting = 0; \
+ } while (0)
+#else
+#define CHECK_STACK()
+#endif
+
+#define NEXT_INST_F(pcAdjustment, nCleanup, resultHandling) \
do { \
TCL_CT_ASSERT((nCleanup >= 0) && (nCleanup <= 2)); \
+ CHECK_STACK(); \
if (nCleanup == 0) { \
if (resultHandling != 0) { \
if ((resultHandling) > 0) { \
@@ -273,17 +288,20 @@ VarHashCreateVar(
switch (nCleanup) { \
case 1: goto cleanup1_pushObjResultPtr; \
case 2: goto cleanup2_pushObjResultPtr; \
+ case 0: break; \
} \
} else { \
pc += (pcAdjustment); \
switch (nCleanup) { \
case 1: goto cleanup1; \
case 2: goto cleanup2; \
+ case 0: break; \
} \
} \
} while (0)
-#define NEXT_INST_V(pcAdjustment, nCleanup, resultHandling) \
+#define NEXT_INST_V(pcAdjustment, nCleanup, resultHandling) \
+ CHECK_STACK(); \
do { \
pc += (pcAdjustment); \
cleanup = (nCleanup); \
@@ -297,6 +315,70 @@ VarHashCreateVar(
} \
} while (0)
+#ifndef TCL_COMPILE_DEBUG
+#define JUMP_PEEPHOLE_F(condition, pcAdjustment, cleanup) \
+ do { \
+ pc += (pcAdjustment); \
+ switch (*pc) { \
+ case INST_JUMP_FALSE1: \
+ NEXT_INST_F(((condition)? 2 : TclGetInt1AtPtr(pc+1)), (cleanup), 0); \
+ case INST_JUMP_TRUE1: \
+ NEXT_INST_F(((condition)? TclGetInt1AtPtr(pc+1) : 2), (cleanup), 0); \
+ case INST_JUMP_FALSE4: \
+ NEXT_INST_F(((condition)? 5 : TclGetInt4AtPtr(pc+1)), (cleanup), 0); \
+ case INST_JUMP_TRUE4: \
+ NEXT_INST_F(((condition)? TclGetInt4AtPtr(pc+1) : 5), (cleanup), 0); \
+ default: \
+ if ((condition) < 0) { \
+ TclNewIntObj(objResultPtr, -1); \
+ } else { \
+ objResultPtr = TCONST((condition) > 0); \
+ } \
+ NEXT_INST_F(0, (cleanup), 1); \
+ } \
+ } while (0)
+#define JUMP_PEEPHOLE_V(condition, pcAdjustment, cleanup) \
+ do { \
+ pc += (pcAdjustment); \
+ switch (*pc) { \
+ case INST_JUMP_FALSE1: \
+ NEXT_INST_V(((condition)? 2 : TclGetInt1AtPtr(pc+1)), (cleanup), 0); \
+ case INST_JUMP_TRUE1: \
+ NEXT_INST_V(((condition)? TclGetInt1AtPtr(pc+1) : 2), (cleanup), 0); \
+ case INST_JUMP_FALSE4: \
+ NEXT_INST_V(((condition)? 5 : TclGetInt4AtPtr(pc+1)), (cleanup), 0); \
+ case INST_JUMP_TRUE4: \
+ NEXT_INST_V(((condition)? TclGetInt4AtPtr(pc+1) : 5), (cleanup), 0); \
+ default: \
+ if ((condition) < 0) { \
+ TclNewIntObj(objResultPtr, -1); \
+ } else { \
+ objResultPtr = TCONST((condition) > 0); \
+ } \
+ NEXT_INST_V(0, (cleanup), 1); \
+ } \
+ } while (0)
+#else /* TCL_COMPILE_DEBUG */
+#define JUMP_PEEPHOLE_F(condition, pcAdjustment, cleanup) \
+ do{ \
+ if ((condition) < 0) { \
+ TclNewIntObj(objResultPtr, -1); \
+ } else { \
+ objResultPtr = TCONST((condition) > 0); \
+ } \
+ NEXT_INST_F((pcAdjustment), (cleanup), 1); \
+ } while (0)
+#define JUMP_PEEPHOLE_V(condition, pcAdjustment, cleanup) \
+ do{ \
+ if ((condition) < 0) { \
+ TclNewIntObj(objResultPtr, -1); \
+ } else { \
+ objResultPtr = TCONST((condition) > 0); \
+ } \
+ NEXT_INST_V((pcAdjustment), (cleanup), 1); \
+ } while (0)
+#endif
+
/*
* Macros used to cache often-referenced Tcl evaluation stack information
* in local variables. Note that a DECACHE_STACK_INFO()-CACHE_STACK_INFO()
@@ -339,6 +421,8 @@ VarHashCreateVar(
#define CURR_DEPTH ((ptrdiff_t) (tosPtr - initTosPtr))
+#define STACK_BASE(esPtr) ((esPtr)->stackWords - 1)
+
/*
* Macros used to trace instruction execution. The macros TRACE,
* TRACE_WITH_OBJ, and O2S are only used inside TclNRExecuteByteCode. O2S is
@@ -347,7 +431,7 @@ VarHashCreateVar(
#ifdef TCL_COMPILE_DEBUG
# define TRACE(a) \
- while (traceInstructions) { \
+ while (traceInstructions) { \
fprintf(stdout, "%2d: %2d (%u) %s ", iPtr->numLevels, \
(int) CURR_DEPTH, \
(unsigned) (pc - codePtr->codeStart), \
@@ -356,12 +440,14 @@ VarHashCreateVar(
break; \
}
# define TRACE_APPEND(a) \
- while (traceInstructions) { \
+ while (traceInstructions) { \
printf a; \
break; \
}
+# define TRACE_ERROR(interp) \
+ TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp))));
# define TRACE_WITH_OBJ(a, objPtr) \
- while (traceInstructions) { \
+ while (traceInstructions) { \
fprintf(stdout, "%2d: %2d (%u) %s ", iPtr->numLevels, \
(int) CURR_DEPTH, \
(unsigned) (pc - codePtr->codeStart), \
@@ -376,6 +462,7 @@ VarHashCreateVar(
#else /* !TCL_COMPILE_DEBUG */
# define TRACE(a)
# define TRACE_APPEND(a)
+# define TRACE_ERROR(interp)
# define TRACE_WITH_OBJ(a, objPtr)
# define O2S(objPtr)
#endif /* TCL_COMPILE_DEBUG */
@@ -387,13 +474,13 @@ VarHashCreateVar(
#define TCL_DTRACE_INST_NEXT() \
do { \
if (TCL_DTRACE_INST_DONE_ENABLED()) { \
- if (curInstName) { \
- TCL_DTRACE_INST_DONE(curInstName, (int) CURR_DEPTH, \
+ if (curInstName) { \
+ TCL_DTRACE_INST_DONE(curInstName, (int) CURR_DEPTH, \
tosPtr); \
} \
curInstName = tclInstructionTable[*pc].name; \
if (TCL_DTRACE_INST_START_ENABLED()) { \
- TCL_DTRACE_INST_START(curInstName, (int) CURR_DEPTH, \
+ TCL_DTRACE_INST_START(curInstName, (int) CURR_DEPTH, \
tosPtr); \
} \
} else if (TCL_DTRACE_INST_START_ENABLED()) { \
@@ -403,7 +490,7 @@ VarHashCreateVar(
} while (0)
#define TCL_DTRACE_INST_LAST() \
do { \
- if (TCL_DTRACE_INST_DONE_ENABLED() && curInstName) { \
+ if (TCL_DTRACE_INST_DONE_ENABLED() && curInstName) { \
TCL_DTRACE_INST_DONE(curInstName, (int) CURR_DEPTH, tosPtr);\
} \
} while (0)
@@ -416,7 +503,7 @@ VarHashCreateVar(
* ClientData *ptrPtr, int *tPtr);
*/
-#ifdef NO_WIDE_TYPE
+#ifdef TCL_WIDE_INT_IS_LONG
#define GetNumberFromObj(interp, objPtr, ptrPtr, tPtr) \
(((objPtr)->typePtr == &tclIntType) \
? (*(tPtr) = TCL_NUMBER_LONG, \
@@ -430,9 +517,9 @@ VarHashCreateVar(
(&((objPtr)->internalRep.doubleValue)), TCL_OK) : \
((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) || \
(((objPtr)->bytes != NULL) && ((objPtr)->length == 0))) \
- ? TCL_ERROR : \
+ ? (*(tPtr) = TCL_NUMBER_LONG),TCL_ERROR : \
TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr)))
-#else /* !NO_WIDE_TYPE */
+#else /* !TCL_WIDE_INT_IS_LONG */
#define GetNumberFromObj(interp, objPtr, ptrPtr, tPtr) \
(((objPtr)->typePtr == &tclIntType) \
? (*(tPtr) = TCL_NUMBER_LONG, \
@@ -450,9 +537,9 @@ VarHashCreateVar(
(&((objPtr)->internalRep.doubleValue)), TCL_OK) : \
((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) || \
(((objPtr)->bytes != NULL) && ((objPtr)->length == 0))) \
- ? TCL_ERROR : \
+ ? (*(tPtr) = TCL_NUMBER_LONG),TCL_ERROR : \
TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr)))
-#endif /* NO_WIDE_TYPE */
+#endif /* TCL_WIDE_INT_IS_LONG */
/*
* Macro used in this file to save a function call for common uses of
@@ -476,13 +563,13 @@ VarHashCreateVar(
* Tcl_WideInt *wideIntPtr);
*/
-#ifdef NO_WIDE_TYPE
+#ifdef TCL_WIDE_INT_IS_LONG
#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \
(((objPtr)->typePtr == &tclIntType) \
? (*(wideIntPtr) = (Tcl_WideInt) \
((objPtr)->internalRep.longValue), TCL_OK) : \
Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr)))
-#else /* !NO_WIDE_TYPE */
+#else /* !TCL_WIDE_INT_IS_LONG */
#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \
(((objPtr)->typePtr == &tclWideIntType) \
? (*(wideIntPtr) = (objPtr)->internalRep.wideValue, TCL_OK) : \
@@ -490,7 +577,7 @@ VarHashCreateVar(
? (*(wideIntPtr) = (Tcl_WideInt) \
((objPtr)->internalRep.longValue), TCL_OK) : \
Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr)))
-#endif /* NO_WIDE_TYPE */
+#endif /* TCL_WIDE_INT_IS_LONG */
/*
* Macro used to make the check for type overflow more mnemonic. This works by
@@ -682,7 +769,7 @@ static void PrintByteCodeInfo(ByteCode *codePtr);
static const char * StringForResultCode(int result);
static void ValidatePcAndStackTop(ByteCode *codePtr,
const unsigned char *pc, int stackTop,
- int stackLowerBound, int checkStack);
+ int checkStack);
#endif /* TCL_COMPILE_DEBUG */
static ByteCode * CompileExprObj(Tcl_Interp *interp, Tcl_Obj *objPtr);
static void DeleteExecStack(ExecStack *esPtr);
@@ -700,20 +787,21 @@ static ExceptionRange * GetExceptRangeForPc(const unsigned char *pc,
int catchOnly, ByteCode *codePtr);
static const char * GetSrcInfoForPc(const unsigned char *pc,
ByteCode *codePtr, int *lengthPtr,
- const unsigned char **pcBeg);
+ const unsigned char **pcBeg, int *cmdIdxPtr);
static Tcl_Obj ** GrowEvaluationStack(ExecEnv *eePtr, int growth,
int move);
static void IllegalExprOperandType(Tcl_Interp *interp,
const unsigned char *pc, Tcl_Obj *opndPtr);
static void InitByteCodeExecution(Tcl_Interp *interp);
-static inline int OFFSET(void *ptr);
+static inline int wordSkip(void *ptr);
static void ReleaseDictIterator(Tcl_Obj *objPtr);
/* Useful elsewhere, make available in tclInt.h or stubs? */
static Tcl_Obj ** StackAllocWords(Tcl_Interp *interp, int numWords);
static Tcl_Obj ** StackReallocWords(Tcl_Interp *interp, int numWords);
static Tcl_NRPostProc CopyCallback;
static Tcl_NRPostProc ExprObjCallback;
-
+static Tcl_NRPostProc FinalizeOONext;
+static Tcl_NRPostProc FinalizeOONextFilter;
static Tcl_NRPostProc TEBCresume;
/*
@@ -864,7 +952,7 @@ TclCreateExecEnv(
esPtr->nextPtr = NULL;
esPtr->markerPtr = NULL;
esPtr->endPtr = &esPtr->stackWords[size-1];
- esPtr->tosPtr = &esPtr->stackWords[-1];
+ esPtr->tosPtr = STACK_BASE(esPtr);
Tcl_MutexLock(&execMutex);
if (!execInitialized) {
@@ -983,13 +1071,13 @@ TclFinalizeExecution(void)
(TCL_ALLOCALIGN/sizeof(Tcl_Obj *))
/*
- * OFFSET computes how many words have to be skipped until the next aligned
+ * wordSkip computes how many words have to be skipped until the next aligned
* word. Note that we are only interested in the low order bits of ptr, so
* that any possible information loss in PTR2INT is of no consequence.
*/
static inline int
-OFFSET(
+wordSkip(
void *ptr)
{
int mask = TCL_ALLOCALIGN-1;
@@ -1002,7 +1090,7 @@ OFFSET(
*/
#define MEMSTART(markerPtr) \
- ((markerPtr) + OFFSET(markerPtr))
+ ((markerPtr) + wordSkip(markerPtr))
/*
*----------------------------------------------------------------------
@@ -1045,8 +1133,9 @@ GrowEvaluationStack(
return MEMSTART(markerPtr);
}
} else {
+#ifndef PURIFY
Tcl_Obj **tmpMarkerPtr = esPtr->tosPtr + 1;
- int offset = OFFSET(tmpMarkerPtr);
+ int offset = wordSkip(tmpMarkerPtr);
if (needed + offset < 0) {
/*
@@ -1061,6 +1150,7 @@ GrowEvaluationStack(
*esPtr->markerPtr = (Tcl_Obj *) markerPtr;
return memStart;
}
+#endif
}
/*
@@ -1074,6 +1164,7 @@ GrowEvaluationStack(
}
needed = growth + moveWords + WALLOCALIGN;
+
/*
* Check if there is enough room in the next stack (if there is one, it
* should be both empty and the last one!)
@@ -1082,8 +1173,8 @@ GrowEvaluationStack(
if (esPtr->nextPtr) {
oldPtr = esPtr;
esPtr = oldPtr->nextPtr;
- currElems = esPtr->endPtr - &esPtr->stackWords[-1];
- if (esPtr->markerPtr || (esPtr->tosPtr != &esPtr->stackWords[-1])) {
+ currElems = esPtr->endPtr - STACK_BASE(esPtr);
+ if (esPtr->markerPtr || (esPtr->tosPtr != STACK_BASE(esPtr))) {
Tcl_Panic("STACK: Stack after current is in use");
}
if (esPtr->nextPtr) {
@@ -1095,7 +1186,7 @@ GrowEvaluationStack(
DeleteExecStack(esPtr);
esPtr = oldPtr;
} else {
- currElems = esPtr->endPtr - &esPtr->stackWords[-1];
+ currElems = esPtr->endPtr - STACK_BASE(esPtr);
}
/*
@@ -1103,10 +1194,15 @@ GrowEvaluationStack(
* including the elements to be copied over and the new marker.
*/
+#ifndef PURIFY
newElems = 2*currElems;
while (needed > newElems) {
newElems *= 2;
}
+#else
+ newElems = needed;
+#endif
+
newBytes = sizeof(ExecStack) + (newElems-1) * sizeof(Tcl_Obj *);
oldPtr = esPtr;
@@ -1209,7 +1305,7 @@ TclStackFree(
Tcl_Obj **markerPtr, *marker;
if (iPtr == NULL || iPtr->execEnvPtr == NULL) {
- Tcl_Free((char *) freePtr);
+ ckfree((char *) freePtr);
return;
}
@@ -1244,10 +1340,10 @@ TclStackFree(
while (esPtr->nextPtr) {
esPtr = esPtr->nextPtr;
}
- esPtr->tosPtr = &esPtr->stackWords[-1];
+ esPtr->tosPtr = STACK_BASE(esPtr);
while (esPtr->prevPtr) {
ExecStack *tmpPtr = esPtr->prevPtr;
- if (tmpPtr->tosPtr == &tmpPtr->stackWords[-1]) {
+ if (tmpPtr->tosPtr == STACK_BASE(tmpPtr)) {
DeleteExecStack(tmpPtr);
} else {
break;
@@ -1255,9 +1351,13 @@ TclStackFree(
}
if (esPtr->prevPtr) {
eePtr->execStackPtr = esPtr->prevPtr;
+#ifdef PURIFY
+ eePtr->execStackPtr->nextPtr = NULL;
+ DeleteExecStack(esPtr);
+#endif
} else {
eePtr->execStackPtr = esPtr;
- }
+ }
}
void *
@@ -1269,7 +1369,7 @@ TclStackAlloc(
int numWords = (numBytes + (sizeof(Tcl_Obj *) - 1))/sizeof(Tcl_Obj *);
if (iPtr == NULL || iPtr->execEnvPtr == NULL) {
- return (void *) Tcl_Alloc(numBytes);
+ return (void *) ckalloc(numBytes);
}
return (void *) StackAllocWords(interp, numWords);
@@ -1288,7 +1388,7 @@ TclStackRealloc(
int numWords;
if (iPtr == NULL || iPtr->execEnvPtr == NULL) {
- return (void *) Tcl_Realloc((char *) ptr, numBytes);
+ return (void *) ckrealloc((char *) ptr, numBytes);
}
eePtr = iPtr->execEnvPtr;
@@ -1393,17 +1493,12 @@ Tcl_NRExprObj(
Tcl_Obj *resultPtr)
{
ByteCode *codePtr;
+ Tcl_InterpState state = Tcl_SaveInterpState(interp, TCL_OK);
- /* TODO: consider saving whole state? */
- Tcl_Obj *saveObjPtr = Tcl_GetObjResult(interp);
-
- Tcl_IncrRefCount(saveObjPtr);
-
+ Tcl_ResetResult(interp);
codePtr = CompileExprObj(interp, objPtr);
- /* TODO: Confirm reset not required? */
- /*Tcl_ResetResult(interp);*/
- Tcl_NRAddCallback(interp, ExprObjCallback, saveObjPtr, resultPtr,
+ Tcl_NRAddCallback(interp, ExprObjCallback, state, resultPtr,
NULL, NULL);
return TclNRExecuteByteCode(interp, codePtr);
}
@@ -1414,14 +1509,15 @@ ExprObjCallback(
Tcl_Interp *interp,
int result)
{
- Tcl_Obj *saveObjPtr = data[0];
+ Tcl_InterpState state = data[0];
Tcl_Obj *resultPtr = data[1];
if (result == TCL_OK) {
TclSetDuplicateObj(resultPtr, Tcl_GetObjResult(interp));
- Tcl_SetObjResult(interp, saveObjPtr);
+ (void) Tcl_RestoreInterpState(interp, state);
+ } else {
+ Tcl_DiscardInterpState(state);
}
- TclDecrRefCount(saveObjPtr);
return result;
}
@@ -1464,7 +1560,7 @@ CompileExprObj(
if (objPtr->typePtr == &exprCodeType) {
Namespace *namespacePtr = iPtr->varFramePtr->nsPtr;
- codePtr = objPtr->internalRep.otherValuePtr;
+ codePtr = objPtr->internalRep.twoPtrValue.ptr1;
if (((Interp *) *codePtr->interpHandle != iPtr)
|| (codePtr->compileEpoch != iPtr->compileEpoch)
|| (codePtr->nsPtr != namespacePtr)
@@ -1504,7 +1600,7 @@ CompileExprObj(
TclInitByteCodeObj(objPtr, &compEnv);
objPtr->typePtr = &exprCodeType;
TclFreeCompileEnv(&compEnv);
- codePtr = objPtr->internalRep.otherValuePtr;
+ codePtr = objPtr->internalRep.twoPtrValue.ptr1;
if (iPtr->varFramePtr->localCachePtr) {
codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr;
codePtr->localCachePtr->refCount++;
@@ -1576,10 +1672,9 @@ static void
FreeExprCodeInternalRep(
Tcl_Obj *objPtr)
{
- ByteCode *codePtr = objPtr->internalRep.otherValuePtr;
+ ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
objPtr->typePtr = NULL;
- objPtr->internalRep.otherValuePtr = NULL;
codePtr->refCount--;
if (codePtr->refCount <= 0) {
TclCleanupByteCode(codePtr);
@@ -1591,13 +1686,13 @@ FreeExprCodeInternalRep(
*
* TclCompileObj --
*
- * This procedure compiles the script contained in a Tcl_Obj
+ * This procedure compiles the script contained in a Tcl_Obj.
*
* Results:
* A pointer to the corresponding ByteCode, never NULL.
*
* Side effects:
- * The object is shimmered to bytecode type
+ * The object is shimmered to bytecode type.
*
*----------------------------------------------------------------------
*/
@@ -1637,30 +1732,29 @@ TclCompileObj(
* here.
*/
- codePtr = objPtr->internalRep.otherValuePtr;
+ codePtr = objPtr->internalRep.twoPtrValue.ptr1;
if (((Interp *) *codePtr->interpHandle != iPtr)
|| (codePtr->compileEpoch != iPtr->compileEpoch)
|| (codePtr->nsPtr != namespacePtr)
|| (codePtr->nsEpoch != namespacePtr->resolverEpoch)) {
- if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
- if ((Interp *) *codePtr->interpHandle != iPtr) {
- Tcl_Panic("Tcl_EvalObj: compiled script jumped interps");
- }
- codePtr->compileEpoch = iPtr->compileEpoch;
- } else {
+ if (!(codePtr->flags & TCL_BYTECODE_PRECOMPILED)) {
goto recompileObj;
}
+ if ((Interp *) *codePtr->interpHandle != iPtr) {
+ Tcl_Panic("Tcl_EvalObj: compiled script jumped interps");
+ }
+ codePtr->compileEpoch = iPtr->compileEpoch;
}
- if (codePtr->procPtr == NULL) {
- /*
- * Check that any compiled locals do refer to the current proc
- * environment! If not, recompile.
- */
+ /*
+ * Check that any compiled locals do refer to the current proc
+ * environment! If not, recompile.
+ */
- if (codePtr->localCachePtr != iPtr->varFramePtr->localCachePtr) {
- goto recompileObj;
- }
+ if (!(codePtr->flags & TCL_BYTECODE_PRECOMPILED) &&
+ (codePtr->procPtr == NULL) &&
+ (codePtr->localCachePtr != iPtr->varFramePtr->localCachePtr)){
+ goto recompileObj;
}
/*
@@ -1692,15 +1786,13 @@ TclCompileObj(
* information.
*/
- if (!invoker) {
+ if (invoker == NULL) {
return codePtr;
- }
-
- {
+ } else {
Tcl_HashEntry *hePtr =
Tcl_FindHashEntry(iPtr->lineBCPtr, codePtr);
ExtCmdLoc *eclPtr;
- CmdFrame *ctxPtr;
+ CmdFrame *ctxCopyPtr;
int redo;
if (!hePtr) {
@@ -1709,8 +1801,8 @@ TclCompileObj(
eclPtr = Tcl_GetHashValue(hePtr);
redo = 0;
- ctxPtr = TclStackAlloc(interp, sizeof(CmdFrame));
- *ctxPtr = *invoker;
+ ctxCopyPtr = TclStackAlloc(interp, sizeof(CmdFrame));
+ *ctxCopyPtr = *invoker;
if (invoker->type == TCL_LOCATION_BC) {
/*
@@ -1718,18 +1810,18 @@ TclCompileObj(
* ctx.data.tebc.codePtr used instead
*/
- TclGetSrcInfoForPc(ctxPtr);
- if (ctxPtr->type == TCL_LOCATION_SOURCE) {
+ TclGetSrcInfoForPc(ctxCopyPtr);
+ if (ctxCopyPtr->type == TCL_LOCATION_SOURCE) {
/*
* The reference made by 'TclGetSrcInfoForPc' is dead.
*/
- Tcl_DecrRefCount(ctxPtr->data.eval.path);
- ctxPtr->data.eval.path = NULL;
+ Tcl_DecrRefCount(ctxCopyPtr->data.eval.path);
+ ctxCopyPtr->data.eval.path = NULL;
}
}
- if (word < ctxPtr->nline) {
+ if (word < ctxCopyPtr->nline) {
/*
* Note: We do not care if the line[word] is -1. This is a
* difference and requires a recompile (location changed from
@@ -1742,12 +1834,12 @@ TclCompileObj(
*/
redo = ((eclPtr->type == TCL_LOCATION_SOURCE)
- && (eclPtr->start != ctxPtr->line[word]))
+ && (eclPtr->start != ctxCopyPtr->line[word]))
|| ((eclPtr->type == TCL_LOCATION_BC)
- && (ctxPtr->type == TCL_LOCATION_SOURCE));
+ && (ctxCopyPtr->type == TCL_LOCATION_SOURCE));
}
- TclStackFree(interp, ctxPtr);
+ TclStackFree(interp, ctxCopyPtr);
if (!redo) {
return codePtr;
}
@@ -1766,9 +1858,9 @@ TclCompileObj(
iPtr->invokeCmdFramePtr = invoker;
iPtr->invokeWord = word;
- tclByteCodeType.setFromAnyProc(interp, objPtr);
+ TclSetByteCodeFromAny(interp, objPtr, NULL, NULL);
iPtr->invokeCmdFramePtr = NULL;
- codePtr = objPtr->internalRep.otherValuePtr;
+ codePtr = objPtr->internalRep.twoPtrValue.ptr1;
if (iPtr->varFramePtr->localCachePtr) {
codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr;
codePtr->localCachePtr->refCount++;
@@ -1842,7 +1934,7 @@ TclIncrObj(
TclSetLongObj(valuePtr, sum);
return TCL_OK;
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
{
Tcl_WideInt w1 = (Tcl_WideInt) augend;
Tcl_WideInt w2 = (Tcl_WideInt) addend;
@@ -1875,7 +1967,7 @@ TclIncrObj(
return TCL_ERROR;
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if ((type1 != TCL_NUMBER_BIG) && (type2 != TCL_NUMBER_BIG)) {
Tcl_WideInt w1, w2, sum;
@@ -1905,6 +1997,41 @@ TclIncrObj(
/*
*----------------------------------------------------------------------
*
+ * ArgumentBCEnter --
+ *
+ * This is a helper for TclNRExecuteByteCode/TEBCresume that encapsulates
+ * a code sequence that is fairly common in the code but *not* commonly
+ * called.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * May register information about the bytecode in the command frame.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ArgumentBCEnter(
+ Tcl_Interp *interp,
+ ByteCode *codePtr,
+ TEBCdata *tdPtr,
+ const unsigned char *pc,
+ int objc,
+ Tcl_Obj **objv)
+{
+ int cmd;
+
+ if (GetSrcInfoForPc(pc, codePtr, NULL, NULL, &cmd)) {
+ TclArgumentBCEnter(interp, objv, objc, codePtr, &tdPtr->cmdFrame, cmd,
+ pc - codePtr->codeStart);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclNRExecuteByteCode --
*
* This procedure executes the instructions of a ByteCode structure. It
@@ -1923,7 +2050,7 @@ TclIncrObj(
#define bcFramePtr (&TD->cmdFrame)
#define initCatchTop ((ptrdiff_t *) (&TD->stack[-1]))
#define initTosPtr ((Tcl_Obj **) (initCatchTop+codePtr->maxExceptDepth))
-#define esPtr (iPtr->execEnvPtr->execStackPtr)
+#define esPtr (iPtr->execEnvPtr->execStackPtr)
int
TclNRExecuteByteCode(
@@ -1932,15 +2059,11 @@ TclNRExecuteByteCode(
{
Interp *iPtr = (Interp *) interp;
TEBCdata *TD;
- int size = sizeof(TEBCdata) -1 +
+ int size = sizeof(TEBCdata) - 1
+ (codePtr->maxStackDepth + codePtr->maxExceptDepth)
- *(sizeof(void *));
- int numWords = (size + sizeof(Tcl_Obj *) - 1)/sizeof(Tcl_Obj *);
-
- if (iPtr->execEnvPtr->rewind) {
- return TCL_ERROR;
- }
-
+ * sizeof(void *);
+ int numWords = (size + sizeof(Tcl_Obj *) - 1) / sizeof(Tcl_Obj *);
+
codePtr->refCount++;
/*
@@ -1957,14 +2080,11 @@ TclNRExecuteByteCode(
TD = (TEBCdata *) GrowEvaluationStack(iPtr->execEnvPtr, numWords, 0);
esPtr->tosPtr = initTosPtr;
-
+
TD->codePtr = codePtr;
- TD->pc = codePtr->codeStart;
TD->catchTop = initCatchTop;
- TD->cleanup = 0;
TD->auxObjList = NULL;
- TD->checkInterp = 0;
-
+
/*
* TIP #280: Initialize the frame. Do not push it yet: it will be pushed
* every time that we call out from this TD, popped when we return to it.
@@ -1973,7 +2093,6 @@ TclNRExecuteByteCode(
bcFramePtr->type = ((codePtr->flags & TCL_BYTECODE_PRECOMPILED)
? TCL_LOCATION_PREBC : TCL_LOCATION_BC);
bcFramePtr->level = (iPtr->cmdFramePtr ? iPtr->cmdFramePtr->level+1 : 1);
- bcFramePtr->numLevels = iPtr->numLevels;
bcFramePtr->framePtr = iPtr->framePtr;
bcFramePtr->nextPtr = iPtr->cmdFramePtr;
bcFramePtr->nline = 0;
@@ -1981,8 +2100,9 @@ TclNRExecuteByteCode(
bcFramePtr->litarg = NULL;
bcFramePtr->data.tebc.codePtr = codePtr;
bcFramePtr->data.tebc.pc = NULL;
- bcFramePtr->cmd.str.cmd = NULL;
- bcFramePtr->cmd.str.len = 0;
+ bcFramePtr->cmdObj = NULL;
+ bcFramePtr->cmd = NULL;
+ bcFramePtr->len = 0;
#ifdef TCL_COMPILE_STATS
iPtr->stats.numExecutions++;
@@ -1991,10 +2111,9 @@ TclNRExecuteByteCode(
/*
* Push the callback for bytecode execution
*/
-
- TclNRAddCallback(interp, TEBCresume, TD,
- /*resume*/ INT2PTR(0), NULL, NULL);
-
+
+ TclNRAddCallback(interp, TEBCresume, TD, /* pc */ NULL,
+ /* cleanup */ INT2PTR(0), NULL);
return TCL_OK;
}
@@ -2034,10 +2153,10 @@ TEBCresume(
int traceInstructions; /* Whether we are doing instruction-level
* tracing or not. */
#endif
-
+
Var *compiledLocals = iPtr->varFramePtr->compiledLocals;
Tcl_Obj **constants = &iPtr->execEnvPtr->constants[0];
-
+
#define LOCAL(i) (&compiledLocals[(i)])
#define TCONST(i) (constants[(i)])
@@ -2049,26 +2168,27 @@ TEBCresume(
TEBCdata *TD = data[0];
#define auxObjList (TD->auxObjList)
#define catchTop (TD->catchTop)
-#define codePtr (TD->codePtr)
-#define checkInterp (TD->checkInterp)
- /* Indicates when a check of interp readyness
- * is necessary. Set by CACHE_STACK_INFO() */
+#define codePtr (TD->codePtr)
/*
* Globals: variables that store state, must remain valid at all times.
*/
- Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation
- * stack. */
- const unsigned char *pc; /* The current program counter. */
-
+ Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation
+ * stack. */
+ const unsigned char *pc = data[1];
+ /* The current program counter. */
+ unsigned char inst; /* The currently running instruction */
+
/*
* Transfer variables - needed only between opcodes, but not while
* executing an instruction.
*/
- int cleanup = 0;
+ int cleanup = PTR2INT(data[2]);
Tcl_Obj *objResultPtr;
+ int checkInterp; /* Indicates when a check of interp readyness
+ * is necessary. Set by CACHE_STACK_INFO() */
/*
* Locals - variables that are used within opcodes or bounded sections of
@@ -2086,88 +2206,84 @@ TEBCresume(
#endif
#ifdef TCL_COMPILE_DEBUG
+ int starting = 1;
traceInstructions = (tclTraceExec == 3);
#endif
TEBC_DATA_DIG();
#ifdef TCL_COMPILE_DEBUG
- if (!data[1] && (tclTraceExec >= 2)) {
+ if (!pc && (tclTraceExec >= 2)) {
PrintByteCodeInfo(codePtr);
fprintf(stdout, " Starting stack top=%d\n", (int) CURR_DEPTH);
fflush(stdout);
}
#endif
- if (data[1] /* resume from invocation */) {
+ if (!pc) {
+ /* bytecode is starting from scratch */
+ checkInterp = 0;
+ pc = codePtr->codeStart;
+ goto cleanup0;
+ } else {
+ /* resume from invocation */
+ CACHE_STACK_INFO();
if (iPtr->execEnvPtr->rewind) {
result = TCL_ERROR;
+ goto abnormalReturn;
}
+
NRE_ASSERT(iPtr->cmdFramePtr == bcFramePtr);
+ if (bcFramePtr->cmdObj) {
+ Tcl_DecrRefCount(bcFramePtr->cmdObj);
+ bcFramePtr->cmdObj = NULL;
+ bcFramePtr->cmd = NULL;
+ }
iPtr->cmdFramePtr = bcFramePtr->nextPtr;
if (iPtr->flags & INTERP_DEBUG_FRAME) {
- TclArgumentBCRelease((Tcl_Interp *) iPtr, bcFramePtr);
+ TclArgumentBCRelease(interp, bcFramePtr);
}
if (codePtr->flags & TCL_BYTECODE_RECOMPILE) {
iPtr->flags |= ERR_ALREADY_LOGGED;
codePtr->flags &= ~TCL_BYTECODE_RECOMPILE;
}
- CACHE_STACK_INFO();
- if (result == TCL_OK) {
-#ifndef TCL_COMPILE_DEBUG
- if (*pc == INST_POP) {
- NEXT_INST_V(1, cleanup, 0);
- }
-#endif
- /*
- * Push the call's object result and continue execution with the
- * next instruction.
- */
-
- TRACE_WITH_OBJ(("%u => ... after \"%.20s\": TCL_OK, result=",
- objc, cmdNameBuf), Tcl_GetObjResult(interp));
-
- objResultPtr = Tcl_GetObjResult(interp);
-
- /*
- * Reset the interp's result to avoid possible duplications of
- * large objects [Bug 781585]. We do not call Tcl_ResetResult to
- * avoid any side effects caused by the resetting of errorInfo and
- * errorCode [Bug 804681], which are not needed here. We chose
- * instead to manipulate the interp's object result directly.
- *
- * Note that the result object is now in objResultPtr, it keeps
- * the refCount it had in its role of iPtr->objResultPtr.
- */
-
- TclNewObj(objPtr);
- Tcl_IncrRefCount(objPtr);
- iPtr->objResultPtr = objPtr;
- NEXT_INST_V(0, cleanup, -1);
+ if (result != TCL_OK) {
+ pc--;
+ goto processExceptionReturn;
}
-
+
/*
- * Result not TCL_OK: fall through
+ * Push the call's object result and continue execution with the next
+ * instruction.
*/
- }
-
- if (iPtr->execEnvPtr->rewind) {
- result = TCL_ERROR;
- goto abnormalReturn;
- }
- if (result != TCL_OK) {
- pc--;
- goto processExceptionReturn;
- }
+ TRACE_WITH_OBJ(("%u => ... after \"%.20s\": TCL_OK, result=",
+ objc, cmdNameBuf), Tcl_GetObjResult(interp));
- /*
- * Loop executing instructions until a "done" instruction, a TCL_RETURN,
- * or some error.
- */
+ /*
+ * Reset the interp's result to avoid possible duplications of large
+ * objects [Bug 781585]. We do not call Tcl_ResetResult to avoid any
+ * side effects caused by the resetting of errorInfo and errorCode
+ * [Bug 804681], which are not needed here. We chose instead to
+ * manipulate the interp's object result directly.
+ *
+ * Note that the result object is now in objResultPtr, it keeps the
+ * refCount it had in its role of iPtr->objResultPtr.
+ */
- goto cleanup0;
+ objResultPtr = Tcl_GetObjResult(interp);
+ TclNewObj(objPtr);
+ Tcl_IncrRefCount(objPtr);
+ iPtr->objResultPtr = objPtr;
+#ifndef TCL_COMPILE_DEBUG
+ if (*pc == INST_POP) {
+ TclDecrRefCount(objResultPtr);
+ NEXT_INST_V(1, cleanup, 0);
+ }
+#endif
+ NEXT_INST_V(0, cleanup, -1);
+ }
/*
* Targets for standard instruction endings; unrolled for speed in the
@@ -2227,24 +2343,6 @@ TEBCresume(
}
cleanup0:
-#ifdef TCL_COMPILE_DEBUG
- /*
- * Skip the stack depth check if an expansion is in progress.
- */
-
- ValidatePcAndStackTop(codePtr, pc, CURR_DEPTH, 0,
- /*checkStack*/ auxObjList == NULL);
- if (traceInstructions) {
- fprintf(stdout, "%2d: %2d ", iPtr->numLevels, (int) CURR_DEPTH);
- TclPrintInstruction(codePtr, pc);
- fflush(stdout);
- }
-#endif /* TCL_COMPILE_DEBUG */
-
-#ifdef TCL_COMPILE_STATS
- iPtr->stats.instructionCount[*pc]++;
-#endif
-
/*
* Check for asynchronous handlers [Bug 746722]; we do the check every
* ASYNC_CHECK_COUNT_MASK instruction, of the form (2**n-1).
@@ -2276,8 +2374,6 @@ TEBCresume(
CACHE_STACK_INFO();
}
- TCL_DTRACE_INST_NEXT();
-
/*
* These two instructions account for 26% of all instructions (according
* to measurements on tclbench by Ben Vitale
@@ -2287,13 +2383,62 @@ TEBCresume(
* reduces total obj size.
*/
- if (*pc == INST_LOAD_SCALAR1) {
- goto instLoadScalar1;
- } else if (*pc == INST_PUSH1) {
- goto instPush1Peephole;
+ inst = *pc;
+
+ peepholeStart:
+#ifdef TCL_COMPILE_STATS
+ iPtr->stats.instructionCount[*pc]++;
+#endif
+
+#ifdef TCL_COMPILE_DEBUG
+ /*
+ * Skip the stack depth check if an expansion is in progress.
+ */
+
+ CHECK_STACK();
+ if (traceInstructions) {
+ fprintf(stdout, "%2d: %2d ", iPtr->numLevels, (int) CURR_DEPTH);
+ TclPrintInstruction(codePtr, pc);
+ fflush(stdout);
}
+#endif /* TCL_COMPILE_DEBUG */
- switch (*pc) {
+ TCL_DTRACE_INST_NEXT();
+
+ if (inst == INST_LOAD_SCALAR1) {
+ goto instLoadScalar1;
+ } else if (inst == INST_PUSH1) {
+ PUSH_OBJECT(codePtr->objArrayPtr[TclGetUInt1AtPtr(pc+1)]);
+ TRACE_WITH_OBJ(("%u => ", TclGetUInt1AtPtr(pc+1)), OBJ_AT_TOS);
+ inst = *(pc += 2);
+ goto peepholeStart;
+ } else if (inst == INST_START_CMD) {
+ /*
+ * Peephole: do not run INST_START_CMD, just skip it
+ */
+
+ iPtr->cmdCount += TclGetUInt4AtPtr(pc+5);
+ if (checkInterp) {
+ checkInterp = 0;
+ if (((codePtr->compileEpoch != iPtr->compileEpoch) ||
+ (codePtr->nsEpoch != iPtr->varFramePtr->nsPtr->resolverEpoch)) &&
+ !(codePtr->flags & TCL_BYTECODE_PRECOMPILED)) {
+ goto instStartCmdFailed;
+ }
+ }
+ inst = *(pc += 9);
+ goto peepholeStart;
+ } else if (inst == INST_NOP) {
+#ifndef TCL_COMPILE_DEBUG
+ while (inst == INST_NOP)
+#endif
+ {
+ inst = *++pc;
+ }
+ goto peepholeStart;
+ }
+
+ switch (inst) {
case INST_SYNTAX:
case INST_RETURN_IMM: {
int code = TclGetInt4AtPtr(pc+1);
@@ -2306,7 +2451,7 @@ TEBCresume(
TRACE(("%u %u => ", code, level));
result = TclProcessReturn(interp, code, level, OBJ_AT_TOS);
if (result == TCL_OK) {
- TRACE_APPEND(("continuing to next instruction (result=\"%.30s\")",
+ TRACE_APPEND(("continuing to next instruction (result=\"%.30s\")\n",
O2S(objResultPtr)));
NEXT_INST_F(9, 1, 0);
}
@@ -2315,6 +2460,7 @@ TEBCresume(
iPtr->flags &= ~ERR_ALREADY_LOGGED;
}
cleanup = 2;
+ TRACE_APPEND(("\n"));
goto processExceptionReturn;
}
@@ -2322,16 +2468,186 @@ TEBCresume(
TRACE(("=> "));
objResultPtr = POP_OBJECT();
result = Tcl_SetReturnOptions(interp, OBJ_AT_TOS);
- Tcl_DecrRefCount(OBJ_AT_TOS);
- OBJ_AT_TOS = objResultPtr;
if (result == TCL_OK) {
- TRACE_APPEND(("continuing to next instruction (result=\"%.30s\")",
+ Tcl_DecrRefCount(OBJ_AT_TOS);
+ OBJ_AT_TOS = objResultPtr;
+ TRACE_APPEND(("continuing to next instruction (result=\"%.30s\")\n",
O2S(objResultPtr)));
NEXT_INST_F(1, 0, 0);
+ } else if (result == TCL_ERROR) {
+ /*
+ * BEWARE! Must do this in this order, because an error in the
+ * option dictionary overrides the result (and can be verified by
+ * test).
+ */
+
+ Tcl_SetObjResult(interp, objResultPtr);
+ Tcl_SetReturnOptions(interp, OBJ_AT_TOS);
+ Tcl_DecrRefCount(OBJ_AT_TOS);
+ OBJ_AT_TOS = objResultPtr;
+ } else {
+ Tcl_DecrRefCount(OBJ_AT_TOS);
+ OBJ_AT_TOS = objResultPtr;
+ Tcl_SetObjResult(interp, objResultPtr);
+ }
+ cleanup = 1;
+ TRACE_APPEND(("\n"));
+ goto processExceptionReturn;
+
+ {
+ CoroutineData *corPtr;
+ int yieldParameter;
+
+ case INST_YIELD:
+ corPtr = iPtr->execEnvPtr->corPtr;
+ TRACE(("%.30s => ", O2S(OBJ_AT_TOS)));
+ if (!corPtr) {
+ TRACE_APPEND(("ERROR: yield outside coroutine\n"));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "yield can only be called in a coroutine", -1));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD",
+ NULL);
+ CACHE_STACK_INFO();
+ goto gotError;
+ }
+
+#ifdef TCL_COMPILE_DEBUG
+ if (tclTraceExec >= 2) {
+ if (traceInstructions) {
+ TRACE_APPEND(("YIELD...\n"));
+ } else {
+ fprintf(stdout, "%d: (%u) yielding value \"%.30s\"\n",
+ iPtr->numLevels, (unsigned)(pc - codePtr->codeStart),
+ Tcl_GetString(OBJ_AT_TOS));
+ }
+ fflush(stdout);
+ }
+#endif
+ yieldParameter = 0;
+ Tcl_SetObjResult(interp, OBJ_AT_TOS);
+ goto doYield;
+
+ case INST_YIELD_TO_INVOKE:
+ corPtr = iPtr->execEnvPtr->corPtr;
+ valuePtr = OBJ_AT_TOS;
+ if (!corPtr) {
+ TRACE(("[%.30s] => ERROR: yield outside coroutine\n",
+ O2S(valuePtr)));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "yieldto can only be called in a coroutine", -1));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD",
+ NULL);
+ CACHE_STACK_INFO();
+ goto gotError;
+ }
+ if (((Namespace *)TclGetCurrentNamespace(interp))->flags & NS_DYING) {
+ TRACE(("[%.30s] => ERROR: yield in deleted\n",
+ O2S(valuePtr)));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "yieldto called in deleted namespace", -1));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "YIELDTO_IN_DELETED",
+ NULL);
+ CACHE_STACK_INFO();
+ goto gotError;
+ }
+
+#ifdef TCL_COMPILE_DEBUG
+ if (tclTraceExec >= 2) {
+ if (traceInstructions) {
+ TRACE(("[%.30s] => YIELD...\n", O2S(valuePtr)));
+ } else {
+ /* FIXME: What is the right thing to trace? */
+ fprintf(stdout, "%d: (%u) yielding to [%.30s]\n",
+ iPtr->numLevels, (unsigned)(pc - codePtr->codeStart),
+ Tcl_GetString(valuePtr));
+ }
+ fflush(stdout);
+ }
+#endif
+
+ /*
+ * Install a tailcall record in the caller and continue with the
+ * yield. The yield is switched into multi-return mode (via the
+ * 'yieldParameter').
+ */
+
+ Tcl_IncrRefCount(valuePtr);
+ iPtr->execEnvPtr = corPtr->callerEEPtr;
+ TclSetTailcall(interp, valuePtr);
+ iPtr->execEnvPtr = corPtr->eePtr;
+ yieldParameter = (PTR2INT(NULL)+1); /*==CORO_ACTIVATE_YIELDM*/
+
+ doYield:
+ /* TIP #280: Record the last piece of info needed by
+ * 'TclGetSrcInfoForPc', and push the frame.
+ */
+
+ bcFramePtr->data.tebc.pc = (char *) pc;
+ iPtr->cmdFramePtr = bcFramePtr;
+
+ if (iPtr->flags & INTERP_DEBUG_FRAME) {
+ ArgumentBCEnter(interp, codePtr, TD, pc, objc, objv);
}
- Tcl_SetObjResult(interp, objResultPtr);
+
+ pc++;
cleanup = 1;
+ TEBC_YIELD();
+ TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
+ INT2PTR(yieldParameter), NULL, NULL);
+ return TCL_OK;
+ }
+
+ case INST_TAILCALL: {
+ Tcl_Obj *listPtr, *nsObjPtr;
+
+ opnd = TclGetUInt1AtPtr(pc+1);
+
+ if (!(iPtr->varFramePtr->isProcCallFrame & 1)) {
+ TRACE(("%d => ERROR: tailcall in non-proc context\n", opnd));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "tailcall can only be called from a proc or lambda", -1));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "TAILCALL", "ILLEGAL", NULL);
+ CACHE_STACK_INFO();
+ goto gotError;
+ }
+
+#ifdef TCL_COMPILE_DEBUG
+ /* FIXME: What is the right thing to trace? */
+ {
+ register int i;
+
+ TRACE(("%d [", opnd));
+ for (i=opnd-1 ; i>=0 ; i--) {
+ TRACE_APPEND(("\"%.30s\"", O2S(OBJ_AT_DEPTH(i))));
+ if (i > 0) {
+ TRACE_APPEND((" "));
+ }
+ }
+ TRACE_APPEND(("] => RETURN..."));
+ }
+#endif
+
+ /*
+ * Push the evaluation of the called command into the NR callback
+ * stack.
+ */
+
+ listPtr = Tcl_NewListObj(opnd, &OBJ_AT_DEPTH(opnd-1));
+ nsObjPtr = Tcl_NewStringObj(iPtr->varFramePtr->nsPtr->fullName, -1);
+ TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
+ if (iPtr->varFramePtr->tailcallPtr) {
+ Tcl_DecrRefCount(iPtr->varFramePtr->tailcallPtr);
+ }
+ iPtr->varFramePtr->tailcallPtr = listPtr;
+
+ result = TCL_RETURN;
+ cleanup = opnd;
goto processExceptionReturn;
+ }
case INST_DONE:
if (tosPtr > initTosPtr) {
@@ -2355,23 +2671,6 @@ TEBCresume(
(void) POP_OBJECT();
goto abnormalReturn;
- case INST_PUSH1:
- instPush1Peephole:
- PUSH_OBJECT(codePtr->objArrayPtr[TclGetUInt1AtPtr(pc+1)]);
- TRACE_WITH_OBJ(("%u => ", TclGetInt1AtPtr(pc+1)), OBJ_AT_TOS);
- pc += 2;
-#if !TCL_COMPILE_DEBUG
- /*
- * Runtime peephole optimisation: check if we are pushing again.
- */
-
- if (*pc == INST_PUSH1) {
- TCL_DTRACE_INST_NEXT();
- goto instPush1Peephole;
- }
-#endif
- NEXT_INST_F(0, 0, 0);
-
case INST_PUSH4:
objResultPtr = codePtr->objArrayPtr[TclGetUInt4AtPtr(pc+1)];
TRACE_WITH_OBJ(("%u => ", TclGetUInt4AtPtr(pc+1)), objResultPtr);
@@ -2381,68 +2680,7 @@ TEBCresume(
TRACE_WITH_OBJ(("=> discarding "), OBJ_AT_TOS);
objPtr = POP_OBJECT();
TclDecrRefCount(objPtr);
-
- /*
- * Runtime peephole optimisation: an INST_POP is scheduled at the end
- * of most commands. If the next instruction is an INST_START_CMD,
- * fall through to it.
- */
-
- pc++;
-#if !TCL_COMPILE_DEBUG
- if (*pc == INST_START_CMD) {
- TCL_DTRACE_INST_NEXT();
- goto instStartCmdPeephole;
- }
-#endif
- NEXT_INST_F(0, 0, 0);
-
- case INST_START_CMD:
-#if !TCL_COMPILE_DEBUG
- instStartCmdPeephole:
-#endif
- /*
- * Remark that if the interpreter is marked for deletion its
- * compileEpoch is modified, so that the epoch check also verifies
- * that the interp is not deleted. If no outside call has been made
- * since the last check, it is safe to omit the check.
- */
-
- iPtr->cmdCount += TclGetUInt4AtPtr(pc+5);
- if (!checkInterp) {
- goto instStartCmdOK;
- } else if (((codePtr->compileEpoch == iPtr->compileEpoch)
- && (codePtr->nsEpoch == iPtr->varFramePtr->nsPtr->resolverEpoch))
- || (codePtr->flags & TCL_BYTECODE_PRECOMPILED)) {
- checkInterp = 0;
- instStartCmdOK:
- NEXT_INST_F(9, 0, 0);
- } else {
- const char *bytes;
-
- length = 0;
-
- /*
- * We used to switch to direct eval; for NRE-awareness we now
- * compile and eval the command so that this evaluation does not
- * add a new TEBC instance. [Bug 2910748]
- */
-
- if (TclInterpReady(interp) == TCL_ERROR) {
- goto gotError;
- }
-
- codePtr->flags |= TCL_BYTECODE_RECOMPILE;
- bytes = GetSrcInfoForPc(pc, codePtr, &length, NULL);
- opnd = TclGetUInt4AtPtr(pc+1);
- pc += (opnd-1);
- PUSH_OBJECT(Tcl_NewStringObj(bytes, length));
- goto instEvalStk;
- }
-
- case INST_NOP:
- pc += 1;
- goto cleanup0;
+ NEXT_INST_F(1, 0, 0);
case INST_DUP:
objResultPtr = OBJ_AT_TOS;
@@ -2452,7 +2690,7 @@ TEBCresume(
case INST_OVER:
opnd = TclGetUInt4AtPtr(pc+1);
objResultPtr = OBJ_AT_DEPTH(opnd);
- TRACE_WITH_OBJ(("=> "), objResultPtr);
+ TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr);
NEXT_INST_F(5, 0, 1);
case INST_REVERSE: {
@@ -2467,10 +2705,11 @@ TEBCresume(
*b = tmpPtr;
a++; b--;
}
+ TRACE(("%u => OK\n", opnd));
NEXT_INST_F(5, 0, 0);
}
- case INST_CONCAT1: {
+ case INST_STR_CONCAT1: {
int appendLen = 0;
char *bytes, *p;
Tcl_Obj **currPtr;
@@ -2550,7 +2789,7 @@ TEBCresume(
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded",
INT_MAX);
}
-#if !TCL_COMPILE_DEBUG
+#ifndef TCL_COMPILE_DEBUG
if (bytes != tclEmptyStringRep && !Tcl_IsShared(objResultPtr)) {
TclFreeIntRep(objResultPtr);
objResultPtr->bytes = ckrealloc(bytes, length+appendLen+1);
@@ -2586,7 +2825,7 @@ TEBCresume(
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded",
INT_MAX);
}
-#if !TCL_COMPILE_DEBUG
+#ifndef TCL_COMPILE_DEBUG
if (!Tcl_IsShared(objResultPtr)) {
bytes = (char *) Tcl_SetByteArrayLength(objResultPtr,
length + appendLen);
@@ -2619,6 +2858,17 @@ TEBCresume(
NEXT_INST_V(2, opnd, 1);
}
+ case INST_CONCAT_STK:
+ /*
+ * Pop the opnd (objc) top stack elements, run through Tcl_ConcatObj,
+ * and then decrement their ref counts.
+ */
+
+ opnd = TclGetUInt4AtPtr(pc+1);
+ objResultPtr = Tcl_ConcatObj(opnd, &OBJ_AT_DEPTH(opnd-1));
+ TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr);
+ NEXT_INST_V(5, opnd, 1);
+
case INST_EXPAND_START:
/*
* Push an element to the auxObjList. This records the current
@@ -2635,9 +2885,28 @@ TEBCresume(
TclNewObj(objPtr);
objPtr->internalRep.ptrAndLongRep.value = CURR_DEPTH;
+ objPtr->length = 0;
PUSH_TAUX_OBJ(objPtr);
+ TRACE(("=> mark depth as %d\n", (int) CURR_DEPTH));
NEXT_INST_F(1, 0, 0);
+ case INST_EXPAND_DROP:
+ /*
+ * Drops an element of the auxObjList, popping stack elements to
+ * restore the stack to the state before the point where the aux
+ * element was created.
+ */
+
+ CLANG_ASSERT(auxObjList);
+ objc = CURR_DEPTH - auxObjList->internalRep.ptrAndLongRep.value;
+ POP_TAUX_OBJ();
+#ifdef TCL_COMPILE_DEBUG
+ /* Ugly abuse! */
+ starting = 1;
+#endif
+ TRACE(("=> drop %d items\n", objc));
+ NEXT_INST_V(1, objc, 0);
+
case INST_EXPAND_STKTOP: {
int i;
ptrdiff_t moved;
@@ -2649,9 +2918,9 @@ TEBCresume(
*/
objPtr = OBJ_AT_TOS;
+ TRACE(("\"%.30s\" => ", O2S(objPtr)));
if (TclListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
- TRACE_WITH_OBJ(("%.30s => ERROR: ", O2S(objPtr)),
- Tcl_GetObjResult(interp));
+ TRACE_ERROR(interp);
goto gotError;
}
(void) POP_OBJECT();
@@ -2663,22 +2932,27 @@ TEBCresume(
* stack depth, as seen by the compiler.
*/
- length = objc + (codePtr->maxStackDepth - TclGetInt4AtPtr(pc+1));
- DECACHE_STACK_INFO();
- moved = GrowEvaluationStack(iPtr->execEnvPtr, length, 1)
- - (Tcl_Obj **) TD;
- if (moved) {
- /*
- * Change the global data to point to the new stack: move the
- * TEBCdataPtr TD, recompute the position of every other
- * stack-allocated parameter, update the stack pointers.
- */
+ auxObjList->length += objc - 1;
+ if ((objc > 1) && (auxObjList->length > 0)) {
+ length = auxObjList->length /* Total expansion room we need */
+ + codePtr->maxStackDepth /* Beyond the original max */
+ - CURR_DEPTH; /* Relative to where we are */
+ DECACHE_STACK_INFO();
+ moved = GrowEvaluationStack(iPtr->execEnvPtr, length, 1)
+ - (Tcl_Obj **) TD;
+ if (moved) {
+ /*
+ * Change the global data to point to the new stack: move the
+ * TEBCdataPtr TD, recompute the position of every other
+ * stack-allocated parameter, update the stack pointers.
+ */
- esPtr = iPtr->execEnvPtr->execStackPtr;
- TD = (TEBCdata *) (((Tcl_Obj **)TD) + moved);
+ esPtr = iPtr->execEnvPtr->execStackPtr;
+ TD = (TEBCdata *) (((Tcl_Obj **)TD) + moved);
- catchTop += moved;
- tosPtr += moved;
+ catchTop += moved;
+ tosPtr += moved;
+ }
}
/*
@@ -2690,6 +2964,7 @@ TEBCresume(
PUSH_OBJECT(objv[i]);
}
+ TRACE_APPEND(("OK\n"));
Tcl_DecrRefCount(objPtr);
NEXT_INST_F(5, 0, 0);
}
@@ -2782,8 +3057,7 @@ TEBCresume(
iPtr->cmdFramePtr = bcFramePtr;
if (iPtr->flags & INTERP_DEBUG_FRAME) {
- TclArgumentBCEnter((Tcl_Interp *) iPtr, objv, objc,
- codePtr, bcFramePtr, pc - codePtr->codeStart);
+ ArgumentBCEnter(interp, codePtr, TD, pc, objc, objv);
}
DECACHE_STACK_INFO();
@@ -2791,7 +3065,7 @@ TEBCresume(
pc += pcAdjustment;
TEBC_YIELD();
return TclNREvalObjv(interp, objc, objv,
- TCL_EVAL_NOERR, NULL);
+ TCL_EVAL_NOERR | TCL_EVAL_SOURCE_IN_FRAME, NULL);
#if TCL_SUPPORT_84_BYTECODE
case INST_CALL_BUILTIN_FUNC1:
@@ -2878,6 +3152,69 @@ TEBCresume(
Tcl_Panic("TclNRExecuteByteCode: obsolete INST_CALL_FUNC1 found");
#endif
+ case INST_INVOKE_REPLACE:
+ objc = TclGetUInt4AtPtr(pc+1);
+ opnd = TclGetUInt1AtPtr(pc+5);
+ objPtr = POP_OBJECT();
+ objv = &OBJ_AT_DEPTH(objc-1);
+ cleanup = objc;
+#ifdef TCL_COMPILE_DEBUG
+ if (tclTraceExec >= 2) {
+ int i;
+
+ if (traceInstructions) {
+ strncpy(cmdNameBuf, TclGetString(objv[0]), 20);
+ TRACE(("%u => call (implementation %s) ", objc, O2S(objPtr)));
+ } else {
+ fprintf(stdout,
+ "%d: (%u) invoking (using implementation %s) ",
+ iPtr->numLevels, (unsigned)(pc - codePtr->codeStart),
+ O2S(objPtr));
+ }
+ for (i = 0; i < objc; i++) {
+ if (i < opnd) {
+ fprintf(stdout, "<");
+ TclPrintObject(stdout, objv[i], 15);
+ fprintf(stdout, ">");
+ } else {
+ TclPrintObject(stdout, objv[i], 15);
+ }
+ fprintf(stdout, " ");
+ }
+ fprintf(stdout, "\n");
+ fflush(stdout);
+ }
+#endif /*TCL_COMPILE_DEBUG*/
+ {
+ Tcl_Obj *copyPtr = Tcl_NewListObj(objc - opnd + 1, NULL);
+ register List *listRepPtr = copyPtr->internalRep.twoPtrValue.ptr1;
+ Tcl_Obj **copyObjv = &listRepPtr->elements;
+ int i;
+
+ listRepPtr->elemCount = objc - opnd + 1;
+ copyObjv[0] = objPtr;
+ memcpy(copyObjv+1, objv+opnd, sizeof(Tcl_Obj *) * (objc - opnd));
+ for (i=1 ; i<objc-opnd+1 ; i++) {
+ Tcl_IncrRefCount(copyObjv[i]);
+ }
+ objPtr = copyPtr;
+ }
+ bcFramePtr->data.tebc.pc = (char *) pc;
+ iPtr->cmdFramePtr = bcFramePtr;
+ if (iPtr->flags & INTERP_DEBUG_FRAME) {
+ ArgumentBCEnter(interp, codePtr, TD, pc, objc, objv);
+ }
+ iPtr->ensembleRewrite.sourceObjs = objv;
+ iPtr->ensembleRewrite.numRemovedObjs = opnd;
+ iPtr->ensembleRewrite.numInsertedObjs = 1;
+ DECACHE_STACK_INFO();
+ pc += 6;
+ TEBC_YIELD();
+
+ TclNRAddCallback(interp, TclClearRootEnsemble, NULL,NULL,NULL,NULL);
+ TclSkipTailcall(interp);
+ return TclNREvalObjEx(interp, objPtr, TCL_EVAL_INVOKE, NULL, INT_MIN);
+
/*
* -----------------------------------------------------------------
* Start of INST_LOAD instructions.
@@ -2964,7 +3301,7 @@ TEBCresume(
varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
TCL_LEAVE_ERR_MSG, "read", 0, 1, arrayPtr, opnd);
if (varPtr == NULL) {
- TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
goto gotError;
}
cleanup = 1;
@@ -2990,7 +3327,7 @@ TEBCresume(
TCL_LEAVE_ERR_MSG, "read", /*createPart1*/0, /*createPart2*/1,
&arrayPtr);
if (!varPtr) {
- TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
goto gotError;
}
@@ -3017,7 +3354,7 @@ TEBCresume(
part1Ptr, part2Ptr, TCL_LEAVE_ERR_MSG, opnd);
CACHE_STACK_INFO();
if (!objResultPtr) {
- TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
goto gotError;
}
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
@@ -3166,7 +3503,7 @@ TEBCresume(
varPtr = TclObjLookupVarEx(interp, objPtr,part2Ptr, TCL_LEAVE_ERR_MSG,
"set", /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
if (!varPtr) {
- TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
goto gotError;
}
cleanup = ((part2Ptr == NULL)? 2 : 3);
@@ -3216,7 +3553,7 @@ TEBCresume(
varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
TCL_LEAVE_ERR_MSG, "set", 1, 1, arrayPtr, opnd);
if (!varPtr) {
- TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
goto gotError;
}
goto doCallPtrSetVar;
@@ -3264,7 +3601,7 @@ TEBCresume(
part1Ptr, part2Ptr, valuePtr, storeFlags, opnd);
CACHE_STACK_INFO();
if (!objResultPtr) {
- TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
goto gotError;
}
#ifndef TCL_COMPILE_DEBUG
@@ -3290,7 +3627,7 @@ TEBCresume(
{
Tcl_Obj *incrPtr;
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
Tcl_WideInt w;
#endif
long increment;
@@ -3339,9 +3676,11 @@ TEBCresume(
varPtr = TclObjLookupVarEx(interp, objPtr, part2Ptr,
TCL_LEAVE_ERR_MSG, "read", 1, 1, &arrayPtr);
if (!varPtr) {
- Tcl_AddObjErrorInfo(interp,
- "\n (reading value of variable to increment)", -1);
- TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp))));
+ DECACHE_STACK_INFO();
+ Tcl_AddErrorInfo(interp,
+ "\n (reading value of variable to increment)");
+ CACHE_STACK_INFO();
+ TRACE_ERROR(interp);
Tcl_DecrRefCount(incrPtr);
goto gotError;
}
@@ -3367,7 +3706,7 @@ TEBCresume(
varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
TCL_LEAVE_ERR_MSG, "read", 1, 1, arrayPtr, opnd);
if (!varPtr) {
- TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
Tcl_DecrRefCount(incrPtr);
goto gotError;
}
@@ -3412,7 +3751,7 @@ TEBCresume(
}
goto doneIncr;
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
w = (Tcl_WideInt)augend;
TRACE(("%u %ld => ", opnd, increment));
@@ -3434,7 +3773,7 @@ TEBCresume(
goto doneIncr;
#endif
} /* end if (type == TCL_NUMBER_LONG) */
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if (type == TCL_NUMBER_WIDE) {
Tcl_WideInt sum;
@@ -3479,8 +3818,7 @@ TEBCresume(
TclNewLongObj(incrPtr, increment);
if (TclIncrObj(interp, objResultPtr, incrPtr) != TCL_OK) {
Tcl_DecrRefCount(incrPtr);
- TRACE_APPEND(("ERROR: %.30s\n",
- O2S(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
goto gotError;
}
Tcl_DecrRefCount(incrPtr);
@@ -3502,7 +3840,7 @@ TEBCresume(
arrayPtr = NULL;
part1Ptr = part2Ptr = NULL;
cleanup = 0;
- TRACE(("%u %ld => ", opnd, increment));
+ TRACE(("%u %s => ", opnd, Tcl_GetString(incrPtr)));
doIncrVar:
if (TclIsVarDirectModifyable2(varPtr, arrayPtr)) {
@@ -3517,8 +3855,7 @@ TEBCresume(
}
if (TclIncrObj(interp, objResultPtr, incrPtr) != TCL_OK) {
Tcl_DecrRefCount(incrPtr);
- TRACE_APPEND(("ERROR: %.30s\n",
- O2S(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
goto gotError;
}
Tcl_DecrRefCount(incrPtr);
@@ -3529,8 +3866,7 @@ TEBCresume(
CACHE_STACK_INFO();
Tcl_DecrRefCount(incrPtr);
if (objResultPtr == NULL) {
- TRACE_APPEND(("ERROR: %.30s\n",
- O2S(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
goto gotError;
}
}
@@ -3551,6 +3887,8 @@ TEBCresume(
*/
case INST_EXIST_SCALAR:
+ cleanup = 0;
+ pcAdjustment = 5;
opnd = TclGetUInt4AtPtr(pc+1);
varPtr = LOCAL(opnd);
while (TclIsVarLink(varPtr)) {
@@ -3567,16 +3905,11 @@ TEBCresume(
varPtr = NULL;
}
}
-
- /*
- * Tricky! Arrays always exist.
- */
-
- objResultPtr = TCONST(!varPtr || TclIsVarUndefined(varPtr) ? 0 : 1);
- TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
- NEXT_INST_F(5, 0, 1);
+ goto afterExistsPeephole;
case INST_EXIST_ARRAY:
+ cleanup = 1;
+ pcAdjustment = 5;
opnd = TclGetUInt4AtPtr(pc+1);
part2Ptr = OBJ_AT_TOS;
arrayPtr = LOCAL(opnd);
@@ -3587,7 +3920,7 @@ TEBCresume(
if (TclIsVarArray(arrayPtr) && !ReadTraced(arrayPtr)) {
varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
if (!varPtr || !ReadTraced(varPtr)) {
- goto doneExistArray;
+ goto afterExistsPeephole;
}
}
varPtr = TclLookupArrayElement(interp, NULL, part2Ptr, 0, "access",
@@ -3604,13 +3937,11 @@ TEBCresume(
varPtr = NULL;
}
}
- doneExistArray:
- objResultPtr = TCONST(!varPtr || TclIsVarUndefined(varPtr) ? 0 : 1);
- TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
- NEXT_INST_F(5, 1, 1);
+ goto afterExistsPeephole;
case INST_EXIST_ARRAY_STK:
cleanup = 2;
+ pcAdjustment = 1;
part2Ptr = OBJ_AT_TOS; /* element name */
part1Ptr = OBJ_UNDER_TOS; /* array name */
TRACE(("\"%.30s(%.30s)\" => ", O2S(part1Ptr), O2S(part2Ptr)));
@@ -3618,6 +3949,7 @@ TEBCresume(
case INST_EXIST_STK:
cleanup = 1;
+ pcAdjustment = 1;
part2Ptr = NULL;
part1Ptr = OBJ_AT_TOS; /* variable name */
TRACE(("\"%.30s\" => ", O2S(part1Ptr)));
@@ -3637,9 +3969,17 @@ TEBCresume(
varPtr = NULL;
}
}
- objResultPtr = TCONST(!varPtr || TclIsVarUndefined(varPtr) ? 0 : 1);
- TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
- NEXT_INST_V(1, cleanup, 1);
+
+ /*
+ * Peep-hole optimisation: if you're about to jump, do jump from here.
+ */
+
+ afterExistsPeephole: {
+ int found = (varPtr && !TclIsVarUndefined(varPtr));
+
+ TRACE_APPEND(("%d\n", found ? 1 : 0));
+ JUMP_PEEPHOLE_V(found, pcAdjustment, cleanup);
+ }
/*
* End of INST_EXIST instructions.
@@ -3657,7 +3997,7 @@ TEBCresume(
while (TclIsVarLink(varPtr)) {
varPtr = varPtr->value.linkPtr;
}
- TRACE(("%s %u\n", (flags?"normal":"noerr"), opnd));
+ TRACE(("%s %u => ", (flags ? "normal" : "noerr"), opnd));
if (TclIsVarDirectUnsettable(varPtr) && !TclIsVarInHash(varPtr)) {
/*
* No errors, no traces, no searches: just make the variable cease
@@ -3670,6 +4010,7 @@ TEBCresume(
goto slowUnsetScalar;
}
varPtr->value.objPtr = NULL;
+ TRACE_APPEND(("OK\n"));
NEXT_INST_F(6, 0, 0);
}
@@ -3690,7 +4031,7 @@ TEBCresume(
while (TclIsVarLink(arrayPtr)) {
arrayPtr = arrayPtr->value.linkPtr;
}
- TRACE(("%s %u \"%.30s\"\n",
+ TRACE(("%s %u \"%.30s\" => ",
(flags ? "normal" : "noerr"), opnd, O2S(part2Ptr)));
if (TclIsVarArray(arrayPtr) && !UnsetTraced(arrayPtr)) {
varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
@@ -3706,12 +4047,14 @@ TEBCresume(
goto slowUnsetArray;
}
varPtr->value.objPtr = NULL;
+ TRACE_APPEND(("OK\n"));
NEXT_INST_F(6, 1, 0);
} else if (!varPtr && !(flags & TCL_LEAVE_ERR_MSG)) {
/*
* Don't need to do anything here.
*/
+ TRACE_APPEND(("OK\n"));
NEXT_INST_F(6, 1, 0);
}
}
@@ -3735,7 +4078,7 @@ TEBCresume(
cleanup = 2;
part2Ptr = OBJ_AT_TOS; /* element name */
part1Ptr = OBJ_UNDER_TOS; /* array name */
- TRACE(("%s \"%.30s(%.30s)\"\n", (flags?"normal":"noerr"),
+ TRACE(("%s \"%.30s(%.30s)\" => ", (flags ? "normal" : "noerr"),
O2S(part1Ptr), O2S(part2Ptr)));
goto doUnsetStk;
@@ -3744,7 +4087,8 @@ TEBCresume(
cleanup = 1;
part2Ptr = NULL;
part1Ptr = OBJ_AT_TOS; /* variable name */
- TRACE(("%s \"%.30s\"\n", (flags?"normal":"noerr"), O2S(part1Ptr)));
+ TRACE(("%s \"%.30s\" => ", (flags ? "normal" : "noerr"),
+ O2S(part1Ptr)));
doUnsetStk:
DECACHE_STACK_INFO();
@@ -3753,11 +4097,12 @@ TEBCresume(
goto errorInUnset;
}
CACHE_STACK_INFO();
+ TRACE_APPEND(("OK\n"));
NEXT_INST_V(2, cleanup, 0);
errorInUnset:
CACHE_STACK_INFO();
- TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
goto gotError;
/*
@@ -3766,7 +4111,7 @@ TEBCresume(
case INST_DICT_DONE:
opnd = TclGetUInt4AtPtr(pc+1);
- TRACE(("%u\n", opnd));
+ TRACE(("%u => OK\n", opnd));
varPtr = LOCAL(opnd);
while (TclIsVarLink(varPtr)) {
varPtr = varPtr->value.linkPtr;
@@ -3787,6 +4132,104 @@ TEBCresume(
/*
* End of INST_UNSET instructions.
* -----------------------------------------------------------------
+ * Start of INST_ARRAY instructions.
+ */
+
+ case INST_ARRAY_EXISTS_IMM:
+ opnd = TclGetUInt4AtPtr(pc+1);
+ pcAdjustment = 5;
+ cleanup = 0;
+ part1Ptr = NULL;
+ arrayPtr = NULL;
+ TRACE(("%u => ", opnd));
+ varPtr = LOCAL(opnd);
+ while (TclIsVarLink(varPtr)) {
+ varPtr = varPtr->value.linkPtr;
+ }
+ goto doArrayExists;
+ case INST_ARRAY_EXISTS_STK:
+ opnd = -1;
+ pcAdjustment = 1;
+ cleanup = 1;
+ part1Ptr = OBJ_AT_TOS;
+ TRACE(("\"%.30s\" => ", O2S(part1Ptr)));
+ 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;
+ }
+ }
+ if (varPtr && TclIsVarArray(varPtr) && !TclIsVarUndefined(varPtr)) {
+ objResultPtr = TCONST(1);
+ } else {
+ objResultPtr = TCONST(0);
+ }
+ TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+ NEXT_INST_V(pcAdjustment, cleanup, 1);
+
+ case INST_ARRAY_MAKE_IMM:
+ opnd = TclGetUInt4AtPtr(pc+1);
+ pcAdjustment = 5;
+ cleanup = 0;
+ part1Ptr = NULL;
+ arrayPtr = NULL;
+ TRACE(("%u => ", opnd));
+ varPtr = LOCAL(opnd);
+ while (TclIsVarLink(varPtr)) {
+ varPtr = varPtr->value.linkPtr;
+ }
+ goto doArrayMake;
+ case INST_ARRAY_MAKE_STK:
+ opnd = -1;
+ pcAdjustment = 1;
+ cleanup = 1;
+ part1Ptr = OBJ_AT_TOS;
+ TRACE(("\"%.30s\" => ", O2S(part1Ptr)));
+ varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, TCL_LEAVE_ERR_MSG,
+ "set", /*createPart1*/1, /*createPart2*/0, &arrayPtr);
+ if (varPtr == NULL) {
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+ doArrayMake:
+ if (varPtr && !TclIsVarArray(varPtr)) {
+ if (TclIsVarArrayElement(varPtr) || !TclIsVarUndefined(varPtr)) {
+ /*
+ * Either an array element, or a scalar: lose!
+ */
+
+ TclObjVarErrMsg(interp, part1Ptr, NULL, "array set",
+ "variable isn't array", opnd);
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "WRITE", "ARRAY", NULL);
+ CACHE_STACK_INFO();
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+ TclSetVarArray(varPtr);
+ varPtr->value.tablePtr = ckalloc(sizeof(TclVarHashTable));
+ TclInitVarHashTable(varPtr->value.tablePtr,
+ TclGetVarNsPtr(varPtr));
+#ifdef TCL_COMPILE_DEBUG
+ TRACE_APPEND(("done\n"));
+ } else {
+ TRACE_APPEND(("nothing to do\n"));
+#endif
+ }
+ NEXT_INST_V(pcAdjustment, cleanup, 0);
+
+ /*
+ * End of INST_ARRAY instructions.
+ * -----------------------------------------------------------------
* Start of variable linking instructions.
*/
@@ -3797,9 +4240,11 @@ TEBCresume(
Namespace *savedNsPtr;
case INST_UPVAR:
- TRACE_WITH_OBJ(("upvar "), OBJ_UNDER_TOS);
+ TRACE(("%d %.30s %.30s => ", TclGetInt4AtPtr(pc+1),
+ O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS)));
if (TclObjGetFrame(interp, OBJ_UNDER_TOS, &framePtr) == -1) {
+ TRACE_ERROR(interp);
goto gotError;
}
@@ -3814,13 +4259,16 @@ TEBCresume(
/*createPart2*/ 1, &varPtr);
iPtr->varFramePtr = savedFramePtr;
if (!otherPtr) {
+ TRACE_ERROR(interp);
goto gotError;
}
goto doLinkVars;
case INST_NSUPVAR:
- TRACE_WITH_OBJ(("nsupvar "), OBJ_UNDER_TOS);
+ TRACE(("%d %.30s %.30s => ", TclGetInt4AtPtr(pc+1),
+ O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS)));
if (TclGetNamespaceFromObj(interp, OBJ_UNDER_TOS, &nsPtr) != TCL_OK) {
+ TRACE_ERROR(interp);
goto gotError;
}
@@ -3835,16 +4283,18 @@ TEBCresume(
/*createPart1*/ 1, /*createPart2*/ 1, &varPtr);
iPtr->varFramePtr->nsPtr = savedNsPtr;
if (!otherPtr) {
+ TRACE_ERROR(interp);
goto gotError;
}
goto doLinkVars;
case INST_VARIABLE:
- TRACE(("variable "));
+ TRACE(("%d, %.30s => ", TclGetInt4AtPtr(pc+1), O2S(OBJ_AT_TOS)));
otherPtr = TclObjLookupVarEx(interp, OBJ_AT_TOS, NULL,
(TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG), "access",
/*createPart1*/ 1, /*createPart2*/ 1, &varPtr);
if (!otherPtr) {
+ TRACE_ERROR(interp);
goto gotError;
}
@@ -3862,7 +4312,7 @@ TEBCresume(
* if there are no errors; otherwise, let it handle the case.
*/
- opnd = TclGetInt4AtPtr(pc+1);;
+ opnd = TclGetInt4AtPtr(pc+1);
varPtr = LOCAL(opnd);
if ((varPtr != otherPtr) && !TclIsVarTraced(varPtr)
&& (TclIsVarUndefined(varPtr) || TclIsVarLink(varPtr))) {
@@ -3874,6 +4324,7 @@ TEBCresume(
Var *linkPtr = varPtr->value.linkPtr;
if (linkPtr == otherPtr) {
+ TRACE_APPEND(("already linked\n"));
NEXT_INST_F(5, 1, 0);
}
if (TclIsVarInHash(linkPtr)) {
@@ -3890,6 +4341,7 @@ TEBCresume(
}
} else if (TclPtrObjMakeUpvar(interp, otherPtr, NULL, 0,
opnd) != TCL_OK) {
+ TRACE_ERROR(interp);
goto gotError;
}
@@ -3898,6 +4350,7 @@ TEBCresume(
* variables - and [variable] did not push it at all.
*/
+ TRACE_APPEND(("link made\n"));
NEXT_INST_F(5, 1, 0);
}
@@ -3944,32 +4397,30 @@ TEBCresume(
doCondJump:
valuePtr = OBJ_AT_TOS;
+ TRACE(("%d => ", jmpOffset[
+ (*pc==INST_JUMP_FALSE1 || *pc==INST_JUMP_FALSE4) ? 0 : 1]));
/* TODO - check claim that taking address of b harms performance */
/* TODO - consider optimization search for constants */
if (TclGetBooleanFromObj(interp, valuePtr, &b) != TCL_OK) {
- TRACE_WITH_OBJ(("%d => ERROR: ", jmpOffset[
- ((*pc == INST_JUMP_FALSE1) || (*pc == INST_JUMP_FALSE4))
- ? 0 : 1]), Tcl_GetObjResult(interp));
+ TRACE_ERROR(interp);
goto gotError;
}
#ifdef TCL_COMPILE_DEBUG
if (b) {
if ((*pc == INST_JUMP_TRUE1) || (*pc == INST_JUMP_TRUE4)) {
- TRACE(("%d => %.20s true, new pc %u\n", jmpOffset[1],
- O2S(valuePtr),
+ TRACE_APPEND(("%.20s true, new pc %u\n", O2S(valuePtr),
(unsigned)(pc + jmpOffset[1] - codePtr->codeStart)));
} else {
- TRACE(("%d => %.20s true\n", jmpOffset[0], O2S(valuePtr)));
+ TRACE_APPEND(("%.20s true\n", O2S(valuePtr)));
}
} else {
if ((*pc == INST_JUMP_TRUE1) || (*pc == INST_JUMP_TRUE4)) {
- TRACE(("%d => %.20s false\n", jmpOffset[0], O2S(valuePtr)));
+ TRACE_APPEND(("%.20s false\n", O2S(valuePtr)));
} else {
- TRACE(("%d => %.20s false, new pc %u\n", jmpOffset[0],
- O2S(valuePtr),
- (unsigned)(pc + jmpOffset[1] - codePtr->codeStart)));
+ TRACE_APPEND(("%.20s false, new pc %u\n", O2S(valuePtr),
+ (unsigned)(pc + jmpOffset[0] - codePtr->codeStart)));
}
}
#endif
@@ -3987,7 +4438,7 @@ TEBCresume(
opnd = TclGetInt4AtPtr(pc+1);
jtPtr = (JumptableInfo *) codePtr->auxDataArrayPtr[opnd].clientData;
- TRACE(("%d => %.20s ", opnd, O2S(OBJ_AT_TOS)));
+ TRACE(("%d \"%.20s\" => ", opnd, O2S(OBJ_AT_TOS)));
hPtr = Tcl_FindHashEntry(&jtPtr->hashTable, TclGetString(OBJ_AT_TOS));
if (hPtr != NULL) {
int jumpOffset = PTR2INT(Tcl_GetHashValue(hPtr));
@@ -4022,7 +4473,7 @@ TEBCresume(
(valuePtr->typePtr? valuePtr->typePtr->name : "null")));
DECACHE_STACK_INFO();
IllegalExprOperandType(interp, pc, valuePtr);
- CACHE_STACK_INFO();
+ CACHE_STACK_INFO();
goto gotError;
}
@@ -4031,7 +4482,7 @@ TEBCresume(
(value2Ptr->typePtr? value2Ptr->typePtr->name : "null")));
DECACHE_STACK_INFO();
IllegalExprOperandType(interp, pc, value2Ptr);
- CACHE_STACK_INFO();
+ CACHE_STACK_INFO();
goto gotError;
}
@@ -4047,6 +4498,376 @@ TEBCresume(
/*
* -----------------------------------------------------------------
+ * Start of general introspector instructions.
+ */
+
+ case INST_NS_CURRENT: {
+ Namespace *currNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+
+ if (currNsPtr == (Namespace *) TclGetGlobalNamespace(interp)) {
+ TclNewLiteralStringObj(objResultPtr, "::");
+ } else {
+ TclNewStringObj(objResultPtr, currNsPtr->fullName,
+ strlen(currNsPtr->fullName));
+ }
+ TRACE_WITH_OBJ(("=> "), objResultPtr);
+ NEXT_INST_F(1, 0, 1);
+ }
+ case INST_COROUTINE_NAME: {
+ CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
+
+ TclNewObj(objResultPtr);
+ if (corPtr && !(corPtr->cmdPtr->flags & CMD_IS_DELETED)) {
+ Tcl_GetCommandFullName(interp, (Tcl_Command) corPtr->cmdPtr,
+ objResultPtr);
+ }
+ TRACE_WITH_OBJ(("=> "), objResultPtr);
+ NEXT_INST_F(1, 0, 1);
+ }
+ case INST_INFO_LEVEL_NUM:
+ TclNewIntObj(objResultPtr, iPtr->varFramePtr->level);
+ TRACE_WITH_OBJ(("=> "), objResultPtr);
+ NEXT_INST_F(1, 0, 1);
+ case INST_INFO_LEVEL_ARGS: {
+ int level;
+ register CallFrame *framePtr = iPtr->varFramePtr;
+ register CallFrame *rootFramePtr = iPtr->rootFramePtr;
+
+ TRACE(("\"%.30s\" => ", O2S(OBJ_AT_TOS)));
+ if (TclGetIntFromObj(interp, OBJ_AT_TOS, &level) != TCL_OK) {
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+ if (level <= 0) {
+ level += framePtr->level;
+ }
+ for (; (framePtr->level!=level) && (framePtr!=rootFramePtr) ;
+ framePtr = framePtr->callerVarPtr) {
+ /* Empty loop body */
+ }
+ if (framePtr == rootFramePtr) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad level \"%s\"", TclGetString(OBJ_AT_TOS)));
+ TRACE_ERROR(interp);
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_LEVEL",
+ TclGetString(OBJ_AT_TOS), NULL);
+ CACHE_STACK_INFO();
+ goto gotError;
+ }
+ objResultPtr = Tcl_NewListObj(framePtr->objc, framePtr->objv);
+ TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+ NEXT_INST_F(1, 1, 1);
+ }
+ {
+ Tcl_Command cmd, origCmd;
+
+ case INST_RESOLVE_COMMAND:
+ cmd = Tcl_GetCommandFromObj(interp, OBJ_AT_TOS);
+ TclNewObj(objResultPtr);
+ if (cmd != NULL) {
+ Tcl_GetCommandFullName(interp, cmd, objResultPtr);
+ }
+ TRACE_WITH_OBJ(("\"%.20s\" => ", O2S(OBJ_AT_TOS)), objResultPtr);
+ NEXT_INST_F(1, 1, 1);
+
+ case INST_ORIGIN_COMMAND:
+ TRACE(("\"%.30s\" => ", O2S(OBJ_AT_TOS)));
+ cmd = Tcl_GetCommandFromObj(interp, OBJ_AT_TOS);
+ if (cmd == NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid command name \"%s\"", TclGetString(OBJ_AT_TOS)));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND",
+ TclGetString(OBJ_AT_TOS), NULL);
+ CACHE_STACK_INFO();
+ TRACE_APPEND(("ERROR: not command\n"));
+ goto gotError;
+ }
+ origCmd = TclGetOriginalCommand(cmd);
+ if (origCmd == NULL) {
+ origCmd = cmd;
+ }
+ TclNewObj(objResultPtr);
+ Tcl_GetCommandFullName(interp, origCmd, objResultPtr);
+ TRACE_APPEND(("\"%.30s\"", O2S(OBJ_AT_TOS)));
+ NEXT_INST_F(1, 1, 1);
+ }
+
+ /*
+ * -----------------------------------------------------------------
+ * Start of TclOO support instructions.
+ */
+
+ {
+ Object *oPtr;
+ CallFrame *framePtr;
+ CallContext *contextPtr;
+ int skip, newDepth;
+
+ case INST_TCLOO_SELF:
+ framePtr = iPtr->varFramePtr;
+ if (framePtr == NULL ||
+ !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
+ TRACE(("=> ERROR: no TclOO call context\n"));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "self may only be called from inside a method",
+ -1));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
+ CACHE_STACK_INFO();
+ goto gotError;
+ }
+ contextPtr = framePtr->clientData;
+
+ /*
+ * Call out to get the name; it's expensive to compute but cached.
+ */
+
+ objResultPtr = TclOOObjectName(interp, contextPtr->oPtr);
+ TRACE_WITH_OBJ(("=> "), objResultPtr);
+ NEXT_INST_F(1, 0, 1);
+
+ case INST_TCLOO_NEXT_CLASS:
+ opnd = TclGetUInt1AtPtr(pc+1);
+ framePtr = iPtr->varFramePtr;
+ valuePtr = OBJ_AT_DEPTH(opnd - 2);
+ objv = &OBJ_AT_DEPTH(opnd - 1);
+ skip = 2;
+ TRACE(("%d => ", opnd));
+ if (framePtr == NULL ||
+ !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
+ TRACE_APPEND(("ERROR: no TclOO call context\n"));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "nextto may only be called from inside a method",
+ -1));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
+ CACHE_STACK_INFO();
+ goto gotError;
+ }
+ contextPtr = framePtr->clientData;
+
+ oPtr = (Object *) Tcl_GetObjectFromObj(interp, valuePtr);
+ if (oPtr == NULL) {
+ TRACE_APPEND(("ERROR: \"%.30s\" not object\n", O2S(valuePtr)));
+ goto gotError;
+ } else {
+ Class *classPtr = oPtr->classPtr;
+ struct MInvoke *miPtr;
+ int i;
+ const char *methodType;
+
+ if (classPtr == NULL) {
+ TRACE_APPEND(("ERROR: \"%.30s\" not class\n", O2S(valuePtr)));
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" is not a class", TclGetString(valuePtr)));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_REQUIRED", NULL);
+ CACHE_STACK_INFO();
+ goto gotError;
+ }
+
+ for (i=contextPtr->index+1 ; i<contextPtr->callPtr->numChain ; i++) {
+ miPtr = contextPtr->callPtr->chain + i;
+ if (!miPtr->isFilter &&
+ miPtr->mPtr->declaringClassPtr == classPtr) {
+ newDepth = i;
+#ifdef TCL_COMPILE_DEBUG
+ if (tclTraceExec >= 2) {
+ if (traceInstructions) {
+ strncpy(cmdNameBuf, TclGetString(objv[0]), 20);
+ } else {
+ fprintf(stdout, "%d: (%u) invoking ",
+ iPtr->numLevels,
+ (unsigned)(pc - codePtr->codeStart));
+ }
+ for (i = 0; i < opnd; i++) {
+ TclPrintObject(stdout, objv[i], 15);
+ fprintf(stdout, " ");
+ }
+ fprintf(stdout, "\n");
+ fflush(stdout);
+ }
+#endif /*TCL_COMPILE_DEBUG*/
+ goto doInvokeNext;
+ }
+ }
+
+ if (contextPtr->callPtr->flags & CONSTRUCTOR) {
+ methodType = "constructor";
+ } else if (contextPtr->callPtr->flags & DESTRUCTOR) {
+ methodType = "destructor";
+ } else {
+ methodType = "method";
+ }
+
+ TRACE_APPEND(("ERROR: \"%.30s\" not on reachable chain\n",
+ O2S(valuePtr)));
+ for (i=contextPtr->index ; i>=0 ; i--) {
+ miPtr = contextPtr->callPtr->chain + i;
+ if (miPtr->isFilter
+ || miPtr->mPtr->declaringClassPtr != classPtr) {
+ continue;
+ }
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "%s implementation by \"%s\" not reachable from here",
+ methodType, TclGetString(valuePtr)));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_NOT_REACHABLE",
+ NULL);
+ CACHE_STACK_INFO();
+ goto gotError;
+ }
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "%s has no non-filter implementation by \"%s\"",
+ methodType, TclGetString(valuePtr)));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_NOT_THERE", NULL);
+ CACHE_STACK_INFO();
+ goto gotError;
+ }
+
+ case INST_TCLOO_NEXT:
+ opnd = TclGetUInt1AtPtr(pc+1);
+ objv = &OBJ_AT_DEPTH(opnd - 1);
+ framePtr = iPtr->varFramePtr;
+ skip = 1;
+ TRACE(("%d => ", opnd));
+ if (framePtr == NULL ||
+ !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
+ TRACE_APPEND(("ERROR: no TclOO call context\n"));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "next may only be called from inside a method",
+ -1));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
+ CACHE_STACK_INFO();
+ goto gotError;
+ }
+ contextPtr = framePtr->clientData;
+
+ newDepth = contextPtr->index + 1;
+ if (newDepth >= contextPtr->callPtr->numChain) {
+ /*
+ * We're at the end of the chain; generate an error message unless
+ * the interpreter is being torn down, in which case we might be
+ * getting here because of methods/destructors doing a [next] (or
+ * equivalent) unexpectedly.
+ */
+
+ const char *methodType;
+
+ if (contextPtr->callPtr->flags & CONSTRUCTOR) {
+ methodType = "constructor";
+ } else if (contextPtr->callPtr->flags & DESTRUCTOR) {
+ methodType = "destructor";
+ } else {
+ methodType = "method";
+ }
+
+ TRACE_APPEND(("ERROR: no TclOO next impl\n"));
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "no next %s implementation", methodType));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "OO", "NOTHING_NEXT", NULL);
+ CACHE_STACK_INFO();
+ goto gotError;
+#ifdef TCL_COMPILE_DEBUG
+ } else if (tclTraceExec >= 2) {
+ int i;
+
+ if (traceInstructions) {
+ strncpy(cmdNameBuf, TclGetString(objv[0]), 20);
+ } else {
+ fprintf(stdout, "%d: (%u) invoking ",
+ iPtr->numLevels, (unsigned)(pc - codePtr->codeStart));
+ }
+ for (i = 0; i < opnd; i++) {
+ TclPrintObject(stdout, objv[i], 15);
+ fprintf(stdout, " ");
+ }
+ fprintf(stdout, "\n");
+ fflush(stdout);
+#endif /*TCL_COMPILE_DEBUG*/
+ }
+
+ doInvokeNext:
+ bcFramePtr->data.tebc.pc = (char *) pc;
+ iPtr->cmdFramePtr = bcFramePtr;
+
+ if (iPtr->flags & INTERP_DEBUG_FRAME) {
+ ArgumentBCEnter(interp, codePtr, TD, pc, opnd, objv);
+ }
+
+ pcAdjustment = 2;
+ cleanup = opnd;
+ DECACHE_STACK_INFO();
+ iPtr->varFramePtr = framePtr->callerVarPtr;
+ pc += pcAdjustment;
+ TEBC_YIELD();
+
+ oPtr = contextPtr->oPtr;
+ if (oPtr->flags & FILTER_HANDLING) {
+ TclNRAddCallback(interp, FinalizeOONextFilter,
+ framePtr, contextPtr, INT2PTR(contextPtr->index),
+ INT2PTR(contextPtr->skip));
+ } else {
+ TclNRAddCallback(interp, FinalizeOONext,
+ framePtr, contextPtr, INT2PTR(contextPtr->index),
+ INT2PTR(contextPtr->skip));
+ }
+ contextPtr->skip = skip;
+ contextPtr->index = newDepth;
+ if (contextPtr->callPtr->chain[newDepth].isFilter
+ || contextPtr->callPtr->flags & FILTER_HANDLING) {
+ oPtr->flags |= FILTER_HANDLING;
+ } else {
+ oPtr->flags &= ~FILTER_HANDLING;
+ }
+
+ {
+ register Method *const mPtr =
+ contextPtr->callPtr->chain[newDepth].mPtr;
+
+ return mPtr->typePtr->callProc(mPtr->clientData, interp,
+ (Tcl_ObjectContext) contextPtr, opnd, objv);
+ }
+
+ case INST_TCLOO_IS_OBJECT:
+ oPtr = (Object *) Tcl_GetObjectFromObj(interp, OBJ_AT_TOS);
+ objResultPtr = TCONST(oPtr != NULL ? 1 : 0);
+ TRACE_WITH_OBJ(("%.30s => ", O2S(OBJ_AT_TOS)), objResultPtr);
+ NEXT_INST_F(1, 1, 1);
+ case INST_TCLOO_CLASS:
+ oPtr = (Object *) Tcl_GetObjectFromObj(interp, OBJ_AT_TOS);
+ if (oPtr == NULL) {
+ TRACE(("%.30s => ERROR: not object\n", O2S(OBJ_AT_TOS)));
+ goto gotError;
+ }
+ objResultPtr = TclOOObjectName(interp, oPtr->selfCls->thisPtr);
+ TRACE_WITH_OBJ(("%.30s => ", O2S(OBJ_AT_TOS)), objResultPtr);
+ NEXT_INST_F(1, 1, 1);
+ case INST_TCLOO_NS:
+ oPtr = (Object *) Tcl_GetObjectFromObj(interp, OBJ_AT_TOS);
+ if (oPtr == NULL) {
+ TRACE(("%.30s => ERROR: not object\n", O2S(OBJ_AT_TOS)));
+ goto gotError;
+ }
+
+ /*
+ * TclOO objects *never* have the global namespace as their NS.
+ */
+
+ TclNewStringObj(objResultPtr, oPtr->namespacePtr->fullName,
+ strlen(oPtr->namespacePtr->fullName));
+ TRACE_WITH_OBJ(("%.30s => ", O2S(OBJ_AT_TOS)), objResultPtr);
+ NEXT_INST_F(1, 1, 1);
+ }
+
+ /*
+ * End of TclOO support instructions.
+ * -----------------------------------------------------------------
* Start of INST_LIST and related instructions.
*/
@@ -4067,19 +4888,19 @@ TEBCresume(
NEXT_INST_V(5, opnd, 1);
case INST_LIST_LENGTH:
- valuePtr = OBJ_AT_TOS;
- if (TclListObjLength(interp, valuePtr, &length) != TCL_OK) {
- TRACE_WITH_OBJ(("%.30s => ERROR: ", O2S(valuePtr)),
- Tcl_GetObjResult(interp));
+ TRACE(("\"%.30s\" => ", O2S(OBJ_AT_TOS)));
+ if (TclListObjLength(interp, OBJ_AT_TOS, &length) != TCL_OK) {
+ TRACE_ERROR(interp);
goto gotError;
}
TclNewIntObj(objResultPtr, length);
- TRACE(("%.20s => %d\n", O2S(valuePtr), length));
+ TRACE_APPEND(("%d\n", length));
NEXT_INST_F(1, 1, 1);
case INST_LIST_INDEX: /* lindex with objc == 3 */
value2Ptr = OBJ_AT_TOS;
valuePtr = OBJ_UNDER_TOS;
+ TRACE(("\"%.30s\" \"%.30s\" => ", O2S(valuePtr), O2S(value2Ptr)));
/*
* Extract the desired list element.
@@ -4097,8 +4918,7 @@ TEBCresume(
objResultPtr = TclLindexList(interp, valuePtr, value2Ptr);
if (!objResultPtr) {
- TRACE_WITH_OBJ(("%.30s %.30s => ERROR: ", O2S(valuePtr),
- O2S(value2Ptr)), Tcl_GetObjResult(interp));
+ TRACE_ERROR(interp);
goto gotError;
}
@@ -4106,8 +4926,7 @@ TEBCresume(
* Stash the list element on the stack.
*/
- TRACE(("%.20s %.20s => %s\n",
- O2S(valuePtr), O2S(value2Ptr), O2S(objResultPtr)));
+ TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
NEXT_INST_F(1, 2, -1); /* Already has the correct refCount */
case INST_LIST_INDEX_IMM: /* lindex with objc==3 and index in bytecode
@@ -4119,6 +4938,7 @@ TEBCresume(
valuePtr = OBJ_AT_TOS;
opnd = TclGetInt4AtPtr(pc+1);
+ TRACE(("\%.30s\" %d => ", O2S(valuePtr), opnd));
/*
* Get the contents of the list, making sure that it really is a list
@@ -4126,8 +4946,7 @@ TEBCresume(
*/
if (TclListObjGetElements(interp, valuePtr, &objc, &objv) != TCL_OK) {
- TRACE_WITH_OBJ(("\"%.30s\" %d => ERROR: ", O2S(valuePtr), opnd),
- Tcl_GetObjResult(interp));
+ TRACE_ERROR(interp);
goto gotError;
}
@@ -4150,8 +4969,7 @@ TEBCresume(
TclNewObj(objResultPtr);
}
- TRACE_WITH_OBJ(("\"%.30s\" %d => ", O2S(valuePtr), opnd),
- objResultPtr);
+ TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
NEXT_INST_F(pcAdjustment, 1, 1);
case INST_LIST_INDEX_MULTI: /* 'lindex' with multiple index args */
@@ -4166,10 +4984,11 @@ TEBCresume(
* Do the 'lindex' operation.
*/
+ TRACE(("%d => ", opnd));
objResultPtr = TclLindexFlat(interp, OBJ_AT_DEPTH(numIndices),
numIndices, &OBJ_AT_DEPTH(numIndices - 1));
if (!objResultPtr) {
- TRACE_WITH_OBJ(("%d => ERROR: ", opnd), Tcl_GetObjResult(interp));
+ TRACE_ERROR(interp);
goto gotError;
}
@@ -4177,7 +4996,7 @@ TEBCresume(
* Set result.
*/
- TRACE(("%d => %s\n", opnd, O2S(objResultPtr)));
+ TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
NEXT_INST_V(5, opnd, -1);
case INST_LSET_FLAT:
@@ -4187,6 +5006,7 @@ TEBCresume(
opnd = TclGetUInt4AtPtr(pc + 1);
numIndices = opnd - 2;
+ TRACE(("%d => ", opnd));
/*
* Get the old value of variable, and remove the stack ref. This is
@@ -4205,7 +5025,7 @@ TEBCresume(
objResultPtr = TclLsetFlat(interp, valuePtr, numIndices,
&OBJ_AT_DEPTH(numIndices), OBJ_AT_TOS);
if (!objResultPtr) {
- TRACE_WITH_OBJ(("%d => ERROR: ", opnd), Tcl_GetObjResult(interp));
+ TRACE_ERROR(interp);
goto gotError;
}
@@ -4213,7 +5033,7 @@ TEBCresume(
* Set result.
*/
- TRACE(("%d => %s\n", opnd, O2S(objResultPtr)));
+ TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
NEXT_INST_V(5, numIndices+1, -1);
case INST_LSET_LIST: /* 'lset' with 4 args */
@@ -4233,6 +5053,8 @@ TEBCresume(
valuePtr = OBJ_AT_TOS;
value2Ptr = OBJ_UNDER_TOS;
+ TRACE(("\"%.30s\" \"%.30s\" \"%.30s\" => ",
+ O2S(value2Ptr), O2S(valuePtr), O2S(objPtr)));
/*
* Compute the new variable value.
@@ -4240,8 +5062,7 @@ TEBCresume(
objResultPtr = TclLsetList(interp, objPtr, value2Ptr, valuePtr);
if (!objResultPtr) {
- TRACE_WITH_OBJ(("\"%.30s\" => ERROR: ", O2S(value2Ptr)),
- Tcl_GetObjResult(interp));
+ TRACE_ERROR(interp);
goto gotError;
}
@@ -4249,7 +5070,7 @@ TEBCresume(
* Set result.
*/
- TRACE(("=> %s\n", O2S(objResultPtr)));
+ TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
NEXT_INST_F(1, 2, -1);
case INST_LIST_RANGE_IMM: /* lrange with objc==4 and both indices in
@@ -4262,6 +5083,8 @@ TEBCresume(
valuePtr = OBJ_AT_TOS;
fromIdx = TclGetInt4AtPtr(pc+1);
toIdx = TclGetInt4AtPtr(pc+5);
+ TRACE(("\"%.30s\" %d %d => ", O2S(valuePtr), TclGetInt4AtPtr(pc+1),
+ TclGetInt4AtPtr(pc+5)));
/*
* Get the contents of the list, making sure that it really is a list
@@ -4269,8 +5092,7 @@ TEBCresume(
*/
if (TclListObjGetElements(interp, valuePtr, &objc, &objv) != TCL_OK) {
- TRACE_WITH_OBJ(("\"%.30s\" %d %d => ERROR: ", O2S(valuePtr),
- fromIdx, toIdx), Tcl_GetObjResult(interp));
+ TRACE_ERROR(interp);
goto gotError;
}
@@ -4312,19 +5134,37 @@ TEBCresume(
*/
if (fromIdx<=toIdx && fromIdx<objc && toIdx>=0) {
- if (fromIdx<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;
+
+ 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);
+ }
+ }
objResultPtr = Tcl_NewListObj(toIdx-fromIdx+1, objv+fromIdx);
} else {
TclNewObj(objResultPtr);
}
- TRACE_WITH_OBJ(("\"%.30s\" %d %d => ", O2S(valuePtr),
- TclGetInt4AtPtr(pc+1), TclGetInt4AtPtr(pc+5)), objResultPtr);
+ TRACE_APPEND(("\"%.30s\"", O2S(objResultPtr)));
NEXT_INST_F(9, 1, 1);
case INST_LIST_IN:
@@ -4333,9 +5173,9 @@ TEBCresume(
valuePtr = OBJ_UNDER_TOS;
s1 = TclGetStringFromObj(valuePtr, &s1len);
+ TRACE(("\"%.30s\" \"%.30s\" => ", O2S(valuePtr), O2S(value2Ptr)));
if (TclListObjLength(interp, value2Ptr, &length) != TCL_OK) {
- TRACE_WITH_OBJ(("\"%.30s\" \"%.30s\" => ERROR: ", O2S(valuePtr),
- O2S(value2Ptr)), Tcl_GetObjResult(interp));
+ TRACE_ERROR(interp);
goto gotError;
}
match = 0;
@@ -4366,7 +5206,7 @@ TEBCresume(
match = !match;
}
- TRACE(("%.20s %.20s => %d\n", O2S(valuePtr), O2S(value2Ptr), match));
+ TRACE_APPEND(("%d\n", match));
/*
* Peep-hole optimisation: if you're about to jump, do jump from here.
@@ -4374,21 +5214,30 @@ TEBCresume(
* for branching.
*/
- pc++;
-#ifndef TCL_COMPILE_DEBUG
- switch (*pc) {
- case INST_JUMP_FALSE1:
- NEXT_INST_F((match ? 2 : TclGetInt1AtPtr(pc+1)), 2, 0);
- case INST_JUMP_TRUE1:
- NEXT_INST_F((match ? TclGetInt1AtPtr(pc+1) : 2), 2, 0);
- case INST_JUMP_FALSE4:
- NEXT_INST_F((match ? 5 : TclGetInt4AtPtr(pc+1)), 2, 0);
- case INST_JUMP_TRUE4:
- NEXT_INST_F((match ? TclGetInt4AtPtr(pc+1) : 5), 2, 0);
+ JUMP_PEEPHOLE_F(match, 1, 2);
+
+ case INST_LIST_CONCAT:
+ value2Ptr = OBJ_AT_TOS;
+ valuePtr = OBJ_UNDER_TOS;
+ TRACE(("\"%.30s\" \"%.30s\" => ", O2S(valuePtr), O2S(value2Ptr)));
+ if (Tcl_IsShared(valuePtr)) {
+ objResultPtr = Tcl_DuplicateObj(valuePtr);
+ if (Tcl_ListObjAppendList(interp, objResultPtr,
+ value2Ptr) != TCL_OK) {
+ TRACE_ERROR(interp);
+ TclDecrRefCount(objResultPtr);
+ goto gotError;
+ }
+ TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+ NEXT_INST_F(1, 2, 1);
+ } else {
+ if (Tcl_ListObjAppendList(interp, valuePtr, value2Ptr) != TCL_OK){
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+ TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
+ NEXT_INST_F(1, 1, 0);
}
-#endif
- objResultPtr = TCONST(match);
- NEXT_INST_F(0, 2, 1);
/*
* End of INST_LIST and related instructions.
@@ -4423,7 +5272,7 @@ TEBCresume(
s2 = (char *) Tcl_GetByteArrayFromObj(value2Ptr, &s2len);
memCmpFn = memcmp;
} else if (((valuePtr->typePtr == &tclStringType)
- && (value2Ptr->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
@@ -4518,25 +5367,74 @@ TEBCresume(
break;
}
}
- if (match < 0) {
- TclNewIntObj(objResultPtr, -1);
- } else {
- objResultPtr = TCONST(match > 0);
- }
- TRACE(("%.20s %.20s => %s\n", O2S(valuePtr), O2S(value2Ptr),
- O2S(objResultPtr)));
- NEXT_INST_F(1, 2, 1);
+
+ TRACE(("\"%.20s\" \"%.20s\" => %d\n", O2S(valuePtr), O2S(value2Ptr),
+ (match < 0 ? -1 : match > 0 ? 1 : 0)));
+ JUMP_PEEPHOLE_F(match, 1, 2);
case INST_STR_LEN:
valuePtr = OBJ_AT_TOS;
length = Tcl_GetCharLength(valuePtr);
TclNewIntObj(objResultPtr, length);
- TRACE(("%.20s => %d\n", O2S(valuePtr), length));
+ TRACE(("\"%.20s\" => %d\n", O2S(valuePtr), length));
NEXT_INST_F(1, 1, 1);
+ case INST_STR_UPPER:
+ valuePtr = OBJ_AT_TOS;
+ TRACE(("\"%.20s\" => ", O2S(valuePtr)));
+ if (Tcl_IsShared(valuePtr)) {
+ s1 = TclGetStringFromObj(valuePtr, &length);
+ TclNewStringObj(objResultPtr, s1, length);
+ length = Tcl_UtfToUpper(TclGetString(objResultPtr));
+ Tcl_SetObjLength(objResultPtr, length);
+ TRACE_APPEND(("\"%.20s\"\n", O2S(objResultPtr)));
+ NEXT_INST_F(1, 1, 1);
+ } else {
+ length = Tcl_UtfToUpper(TclGetString(valuePtr));
+ Tcl_SetObjLength(valuePtr, length);
+ TclFreeIntRep(valuePtr);
+ TRACE_APPEND(("\"%.20s\"\n", O2S(valuePtr)));
+ NEXT_INST_F(1, 0, 0);
+ }
+ case INST_STR_LOWER:
+ valuePtr = OBJ_AT_TOS;
+ TRACE(("\"%.20s\" => ", O2S(valuePtr)));
+ if (Tcl_IsShared(valuePtr)) {
+ s1 = TclGetStringFromObj(valuePtr, &length);
+ TclNewStringObj(objResultPtr, s1, length);
+ length = Tcl_UtfToLower(TclGetString(objResultPtr));
+ Tcl_SetObjLength(objResultPtr, length);
+ TRACE_APPEND(("\"%.20s\"\n", O2S(objResultPtr)));
+ NEXT_INST_F(1, 1, 1);
+ } else {
+ length = Tcl_UtfToLower(TclGetString(valuePtr));
+ Tcl_SetObjLength(valuePtr, length);
+ TclFreeIntRep(valuePtr);
+ TRACE_APPEND(("\"%.20s\"\n", O2S(valuePtr)));
+ NEXT_INST_F(1, 0, 0);
+ }
+ case INST_STR_TITLE:
+ valuePtr = OBJ_AT_TOS;
+ TRACE(("\"%.20s\" => ", O2S(valuePtr)));
+ if (Tcl_IsShared(valuePtr)) {
+ s1 = TclGetStringFromObj(valuePtr, &length);
+ TclNewStringObj(objResultPtr, s1, length);
+ length = Tcl_UtfToTitle(TclGetString(objResultPtr));
+ Tcl_SetObjLength(objResultPtr, length);
+ TRACE_APPEND(("\"%.20s\"\n", O2S(objResultPtr)));
+ NEXT_INST_F(1, 1, 1);
+ } else {
+ length = Tcl_UtfToTitle(TclGetString(valuePtr));
+ Tcl_SetObjLength(valuePtr, length);
+ TclFreeIntRep(valuePtr);
+ TRACE_APPEND(("\"%.20s\"\n", O2S(valuePtr)));
+ NEXT_INST_F(1, 0, 0);
+ }
+
case INST_STR_INDEX:
value2Ptr = OBJ_AT_TOS;
valuePtr = OBJ_UNDER_TOS;
+ TRACE(("\"%.20s\" %.20s => ", O2S(valuePtr), O2S(value2Ptr)));
/*
* Get char length to calulate what 'end' means.
@@ -4544,6 +5442,7 @@ TEBCresume(
length = Tcl_GetCharLength(valuePtr);
if (TclGetIntForIndexM(interp, value2Ptr, length-1, &index)!=TCL_OK) {
+ TRACE_ERROR(interp);
goto gotError;
}
@@ -4569,10 +5468,382 @@ TEBCresume(
objResultPtr = Tcl_NewStringObj(buf, length);
}
- TRACE(("%.20s %.20s => %s\n", O2S(valuePtr), O2S(value2Ptr),
- O2S(objResultPtr)));
+ TRACE_APPEND(("\"%s\"\n", O2S(objResultPtr)));
+ NEXT_INST_F(1, 2, 1);
+
+ case INST_STR_RANGE:
+ TRACE(("\"%.20s\" %.20s %.20s =>",
+ O2S(OBJ_AT_DEPTH(2)), O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS)));
+ length = Tcl_GetCharLength(OBJ_AT_DEPTH(2)) - 1;
+ if (TclGetIntForIndexM(interp, OBJ_UNDER_TOS, length,
+ &fromIdx) != TCL_OK
+ || TclGetIntForIndexM(interp, OBJ_AT_TOS, length,
+ &toIdx) != TCL_OK) {
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+
+ if (fromIdx < 0) {
+ fromIdx = 0;
+ }
+ if (toIdx >= length) {
+ toIdx = length;
+ }
+ if (toIdx >= fromIdx) {
+ objResultPtr = Tcl_GetRange(OBJ_AT_DEPTH(2), fromIdx, toIdx);
+ } else {
+ TclNewObj(objResultPtr);
+ }
+ TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+ NEXT_INST_V(1, 3, 1);
+
+ case INST_STR_RANGE_IMM:
+ valuePtr = OBJ_AT_TOS;
+ fromIdx = TclGetInt4AtPtr(pc+1);
+ toIdx = TclGetInt4AtPtr(pc+5);
+ length = Tcl_GetCharLength(valuePtr);
+ TRACE(("\"%.20s\" %d %d => ", O2S(valuePtr), fromIdx, toIdx));
+
+ /*
+ * Adjust indices for end-based indexing.
+ */
+
+ if (fromIdx < -1) {
+ fromIdx += 1 + length;
+ if (fromIdx < 0) {
+ fromIdx = 0;
+ }
+ } else if (fromIdx >= length) {
+ fromIdx = length;
+ }
+ if (toIdx < -1) {
+ toIdx += 1 + length;
+ } else if (toIdx >= length) {
+ toIdx = length - 1;
+ }
+
+ /*
+ * Check if we can do a sane substring.
+ */
+
+ if (fromIdx <= toIdx) {
+ objResultPtr = Tcl_GetRange(valuePtr, fromIdx, toIdx);
+ } else {
+ TclNewObj(objResultPtr);
+ }
+ TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+ NEXT_INST_F(9, 1, 1);
+
+ {
+ Tcl_UniChar *ustring1, *ustring2, *ustring3, *end, *p;
+ int length3;
+ Tcl_Obj *value3Ptr;
+
+ case INST_STR_REPLACE:
+ value3Ptr = POP_OBJECT();
+ valuePtr = OBJ_AT_DEPTH(2);
+ length = 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,
+ &fromIdx) != TCL_OK
+ || TclGetIntForIndexM(interp, OBJ_AT_TOS, length,
+ &toIdx) != TCL_OK) {
+ TclDecrRefCount(value3Ptr);
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+ TclDecrRefCount(OBJ_AT_TOS);
+ (void) POP_OBJECT();
+ TclDecrRefCount(OBJ_AT_TOS);
+ (void) POP_OBJECT();
+ if (fromIdx < 0) {
+ fromIdx = 0;
+ }
+
+ if (fromIdx > toIdx || fromIdx > length) {
+ TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
+ TclDecrRefCount(value3Ptr);
+ NEXT_INST_F(1, 0, 0);
+ }
+
+ if (toIdx > length) {
+ toIdx = length;
+ }
+
+ if (fromIdx == 0 && toIdx == length) {
+ TclDecrRefCount(OBJ_AT_TOS);
+ OBJ_AT_TOS = value3Ptr;
+ TRACE_APPEND(("\"%.30s\"\n", O2S(value3Ptr)));
+ NEXT_INST_F(1, 0, 0);
+ }
+
+ length3 = Tcl_GetCharLength(value3Ptr);
+
+ /*
+ * Remove substring. In-place.
+ */
+
+ if (length3 == 0 && !Tcl_IsShared(valuePtr) && toIdx == length) {
+ TclDecrRefCount(value3Ptr);
+ Tcl_SetObjLength(valuePtr, fromIdx);
+ TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
+ NEXT_INST_F(1, 0, 0);
+ }
+
+ /*
+ * See if we can splice in place. This happens when the number of
+ * characters being replaced is the same as the number of characters
+ * in the string to be inserted.
+ */
+
+ if (length3 - 1 == toIdx - fromIdx) {
+ unsigned char *bytes1, *bytes2;
+
+ if (Tcl_IsShared(valuePtr)) {
+ objResultPtr = Tcl_DuplicateObj(valuePtr);
+ if (TclIsPureByteArray(objResultPtr)
+ && TclIsPureByteArray(value3Ptr)) {
+ bytes1 = Tcl_GetByteArrayFromObj(objResultPtr, NULL);
+ bytes2 = Tcl_GetByteArrayFromObj(value3Ptr, NULL);
+ memcpy(bytes1 + fromIdx, bytes2, length3);
+ } else {
+ ustring1 = Tcl_GetUnicodeFromObj(objResultPtr, NULL);
+ ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
+ memcpy(ustring1 + fromIdx, ustring2,
+ length3 * sizeof(Tcl_UniChar));
+
+ /*
+ * Magic! Flush the info in the string internal rep that
+ * refers to the about-to-be-invalidated UTF-8 rep. This
+ * sets the 'allocated' field of the String structure to 0
+ * to indicate that a new buffer needs to be allocated.
+ * This is safe; we know we've got a tclStringTypePtr set
+ * at this point (post Tcl_GetUnicodeFromObj).
+ */
+
+ ((int *) objResultPtr->internalRep.otherValuePtr)[1] = 0;
+ }
+ Tcl_InvalidateStringRep(objResultPtr);
+ TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+ NEXT_INST_F(1, 1, 1);
+ } else {
+ if (TclIsPureByteArray(valuePtr)
+ && TclIsPureByteArray(value3Ptr)) {
+ bytes1 = Tcl_GetByteArrayFromObj(valuePtr, NULL);
+ bytes2 = Tcl_GetByteArrayFromObj(value3Ptr, NULL);
+ memcpy(bytes1 + fromIdx, bytes2, length3);
+ } else {
+ ustring1 = Tcl_GetUnicodeFromObj(valuePtr, NULL);
+ ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
+ memcpy(ustring1 + fromIdx, ustring2,
+ length3 * sizeof(Tcl_UniChar));
+
+ /*
+ * Magic! Flush the info in the string internal rep that
+ * refers to the about-to-be-invalidated UTF-8 rep. This
+ * sets the 'allocated' field of the String structure to 0
+ * to indicate that a new buffer needs to be allocated.
+ * This is safe; we know we've got a tclStringTypePtr set
+ * at this point (post Tcl_GetUnicodeFromObj).
+ */
+
+ ((int *) objResultPtr->internalRep.otherValuePtr)[1] = 0;
+ }
+ Tcl_InvalidateStringRep(valuePtr);
+ TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
+ NEXT_INST_F(1, 0, 0);
+ }
+ }
+
+ /*
+ * Get the unicode representation; this is where we guarantee to lose
+ * bytearrays.
+ */
+
+ ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length);
+ length--;
+
+ /*
+ * Remove substring using copying.
+ */
+
+ if (length3 == 0) {
+ if (fromIdx > 0) {
+ objResultPtr = Tcl_NewUnicodeObj(ustring1, fromIdx);
+ if (toIdx < length) {
+ Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1,
+ length - toIdx);
+ }
+ } else {
+ objResultPtr = Tcl_NewUnicodeObj(ustring1 + toIdx + 1,
+ length - toIdx);
+ }
+ TclDecrRefCount(value3Ptr);
+ TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+ NEXT_INST_F(1, 1, 1);
+ }
+
+ /*
+ * Splice string pieces by full copying.
+ */
+
+ if (fromIdx > 0) {
+ objResultPtr = Tcl_NewUnicodeObj(ustring1, fromIdx);
+ Tcl_AppendObjToObj(objResultPtr, value3Ptr);
+ if (toIdx < length) {
+ Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1,
+ length - toIdx);
+ }
+ } else if (Tcl_IsShared(value3Ptr)) {
+ objResultPtr = Tcl_DuplicateObj(value3Ptr);
+ if (toIdx < length) {
+ Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1,
+ length - toIdx);
+ }
+ } else {
+ /*
+ * Be careful with splicing the stack in this case; we have a
+ * refCount:1 object in value3Ptr and we want to append to it and
+ * make it be the refCount:1 object at the top of the stack
+ * afterwards. [Bug 82e7f67325]
+ */
+
+ if (toIdx < length) {
+ Tcl_AppendUnicodeToObj(value3Ptr, ustring1 + toIdx + 1,
+ length - toIdx);
+ }
+ TRACE_APPEND(("\"%.30s\"\n", O2S(value3Ptr)));
+ TclDecrRefCount(valuePtr);
+ OBJ_AT_TOS = value3Ptr; /* Tricky! */
+ NEXT_INST_F(1, 0, 0);
+ }
+ TclDecrRefCount(value3Ptr);
+ TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+ NEXT_INST_F(1, 1, 1);
+
+ case INST_STR_MAP:
+ valuePtr = OBJ_AT_TOS; /* "Main" string. */
+ value3Ptr = OBJ_UNDER_TOS; /* "Target" string. */
+ value2Ptr = OBJ_AT_DEPTH(2); /* "Source" string. */
+ if (value3Ptr == value2Ptr) {
+ objResultPtr = valuePtr;
+ goto doneStringMap;
+ } else if (valuePtr == value2Ptr) {
+ objResultPtr = value3Ptr;
+ goto doneStringMap;
+ }
+ ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length);
+ if (length == 0) {
+ objResultPtr = valuePtr;
+ goto doneStringMap;
+ }
+ ustring2 = Tcl_GetUnicodeFromObj(value2Ptr, &length2);
+ if (length2 > length || length2 == 0) {
+ objResultPtr = valuePtr;
+ goto doneStringMap;
+ } else if (length2 == length) {
+ if (memcmp(ustring1, ustring2, sizeof(Tcl_UniChar) * length)) {
+ objResultPtr = valuePtr;
+ } else {
+ objResultPtr = value3Ptr;
+ }
+ goto doneStringMap;
+ }
+ ustring3 = Tcl_GetUnicodeFromObj(value3Ptr, &length3);
+
+ objResultPtr = Tcl_NewUnicodeObj(ustring1, 0);
+ p = ustring1;
+ end = ustring1 + length;
+ for (; ustring1 < end; ustring1++) {
+ if ((*ustring1 == *ustring2) && (length2==1 ||
+ memcmp(ustring1, ustring2, sizeof(Tcl_UniChar) * length2)
+ == 0)) {
+ if (p != ustring1) {
+ Tcl_AppendUnicodeToObj(objResultPtr, p, ustring1-p);
+ p = ustring1 + length2;
+ } else {
+ p += length2;
+ }
+ ustring1 = p - 1;
+
+ Tcl_AppendUnicodeToObj(objResultPtr, ustring3, length3);
+ }
+ }
+ if (p != ustring1) {
+ /*
+ * Put the rest of the unmapped chars onto result.
+ */
+
+ Tcl_AppendUnicodeToObj(objResultPtr, p, ustring1 - p);
+ }
+ doneStringMap:
+ TRACE_WITH_OBJ(("%.20s %.20s %.20s => ",
+ O2S(value2Ptr), O2S(value3Ptr), O2S(valuePtr)), objResultPtr);
+ NEXT_INST_V(1, 3, 1);
+
+ case INST_STR_FIND:
+ ustring1 = Tcl_GetUnicodeFromObj(OBJ_AT_TOS, &length); /* Haystack */
+ ustring2 = Tcl_GetUnicodeFromObj(OBJ_UNDER_TOS, &length2);/* Needle */
+
+ match = -1;
+ if (length2 > 0 && length2 <= length) {
+ end = ustring1 + length - length2 + 1;
+ for (p=ustring1 ; p<end ; p++) {
+ if ((*p == *ustring2) &&
+ memcmp(ustring2,p,sizeof(Tcl_UniChar)*length2) == 0) {
+ match = p - ustring1;
+ break;
+ }
+ }
+ }
+
+ TRACE(("%.20s %.20s => %d\n",
+ O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), match));
+ TclNewIntObj(objResultPtr, match);
+ NEXT_INST_F(1, 2, 1);
+
+ case INST_STR_FIND_LAST:
+ ustring1 = Tcl_GetUnicodeFromObj(OBJ_AT_TOS, &length); /* Haystack */
+ ustring2 = Tcl_GetUnicodeFromObj(OBJ_UNDER_TOS, &length2);/* Needle */
+
+ match = -1;
+ if (length2 > 0 && length2 <= length) {
+ for (p=ustring1+length-length2 ; p>=ustring1 ; p--) {
+ if ((*p == *ustring2) &&
+ memcmp(ustring2,p,sizeof(Tcl_UniChar)*length2) == 0) {
+ match = p - ustring1;
+ break;
+ }
+ }
+ }
+
+ TRACE(("%.20s %.20s => %d\n",
+ O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), match));
+
+ TclNewIntObj(objResultPtr, match);
NEXT_INST_F(1, 2, 1);
+ case INST_STR_CLASS:
+ opnd = TclGetInt1AtPtr(pc+1);
+ valuePtr = OBJ_AT_TOS;
+ TRACE(("%s \"%.30s\" => ", tclStringClassTable[opnd].name,
+ O2S(valuePtr)));
+ ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length);
+ match = 1;
+ if (length > 0) {
+ end = ustring1 + length;
+ for (p=ustring1 ; p<end ; p++) {
+ if (!tclStringClassTable[opnd].comparator(*p)) {
+ match = 0;
+ break;
+ }
+ }
+ }
+ TRACE_APPEND(("%d\n", match));
+ JUMP_PEEPHOLE_F(match, 2, 1);
+ }
+
case INST_STR_MATCH:
nocase = TclGetInt1AtPtr(pc+1);
valuePtr = OBJ_AT_TOS; /* String */
@@ -4613,26 +5884,77 @@ TEBCresume(
* Peep-hole optimisation: if you're about to jump, do jump from here.
*/
- pc += 2;
-#ifndef TCL_COMPILE_DEBUG
- switch (*pc) {
- case INST_JUMP_FALSE1:
- NEXT_INST_F((match? 2 : TclGetInt1AtPtr(pc+1)), 2, 0);
- case INST_JUMP_TRUE1:
- NEXT_INST_F((match? TclGetInt1AtPtr(pc+1) : 2), 2, 0);
- case INST_JUMP_FALSE4:
- NEXT_INST_F((match? 5 : TclGetInt4AtPtr(pc+1)), 2, 0);
- case INST_JUMP_TRUE4:
- NEXT_INST_F((match? TclGetInt4AtPtr(pc+1) : 5), 2, 0);
+ JUMP_PEEPHOLE_F(match, 2, 2);
+
+ {
+ const char *string1, *string2;
+ int trim1, trim2;
+
+ case INST_STR_TRIM_LEFT:
+ valuePtr = OBJ_UNDER_TOS; /* String */
+ value2Ptr = OBJ_AT_TOS; /* TrimSet */
+ string2 = TclGetStringFromObj(value2Ptr, &length2);
+ string1 = TclGetStringFromObj(valuePtr, &length);
+ trim1 = TclTrimLeft(string1, length, string2, length2);
+ trim2 = 0;
+ goto createTrimmedString;
+ case INST_STR_TRIM_RIGHT:
+ valuePtr = OBJ_UNDER_TOS; /* String */
+ value2Ptr = OBJ_AT_TOS; /* TrimSet */
+ string2 = TclGetStringFromObj(value2Ptr, &length2);
+ string1 = TclGetStringFromObj(valuePtr, &length);
+ trim2 = TclTrimRight(string1, length, string2, length2);
+ trim1 = 0;
+ goto createTrimmedString;
+ case INST_STR_TRIM:
+ valuePtr = OBJ_UNDER_TOS; /* String */
+ 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;
}
+ createTrimmedString:
+ /*
+ * Careful here; trim set often contains non-ASCII characters so we
+ * take care when printing. [Bug 971cb4f1db]
+ */
+
+#ifdef TCL_COMPILE_DEBUG
+ if (traceInstructions) {
+ TRACE(("\"%.30s\" ", O2S(valuePtr)));
+ TclPrintObject(stdout, value2Ptr, 30);
+ printf(" => ");
+ }
+#endif
+ if (trim1 == 0 && trim2 == 0) {
+#ifdef TCL_COMPILE_DEBUG
+ if (traceInstructions) {
+ TclPrintObject(stdout, valuePtr, 30);
+ printf("\n");
+ }
+#endif
+ NEXT_INST_F(1, 1, 0);
+ } else {
+ objResultPtr = Tcl_NewStringObj(string1+trim1, length-trim1-trim2);
+#ifdef TCL_COMPILE_DEBUG
+ if (traceInstructions) {
+ TclPrintObject(stdout, objResultPtr, 30);
+ printf("\n");
+ }
#endif
- objResultPtr = TCONST(match);
- NEXT_INST_F(0, 2, 1);
+ NEXT_INST_F(1, 2, 1);
+ }
+ }
case INST_REGEXP:
cflags = TclGetInt1AtPtr(pc+1); /* RE compile flages like NOCASE */
valuePtr = OBJ_AT_TOS; /* String */
value2Ptr = OBJ_UNDER_TOS; /* Pattern */
+ TRACE(("\"%.30s\" \"%.30s\" => ", O2S(valuePtr), O2S(value2Ptr)));
/*
* Compile and match the regular expression.
@@ -4643,44 +5965,24 @@ TEBCresume(
Tcl_GetRegExpFromObj(interp, value2Ptr, cflags);
if (regExpr == NULL) {
- goto regexpFailure;
+ TRACE_ERROR(interp);
+ goto gotError;
}
-
match = Tcl_RegExpExecObj(interp, regExpr, valuePtr, 0, 0, 0);
-
if (match < 0) {
- regexpFailure:
-#ifdef TCL_COMPILE_DEBUG
- objResultPtr = Tcl_GetObjResult(interp);
- TRACE_WITH_OBJ(("%.20s %.20s => ERROR: ",
- O2S(valuePtr), O2S(value2Ptr)), objResultPtr);
-#endif
+ TRACE_ERROR(interp);
goto gotError;
}
}
- TRACE(("%.20s %.20s => %d\n", O2S(valuePtr), O2S(value2Ptr), match));
+ TRACE_APPEND(("%d\n", match));
/*
* Peep-hole optimisation: if you're about to jump, do jump from here.
* Adjustment is 2 due to the nocase byte.
*/
- pc += 2;
-#ifndef TCL_COMPILE_DEBUG
- switch (*pc) {
- case INST_JUMP_FALSE1:
- NEXT_INST_F((match? 2 : TclGetInt1AtPtr(pc+1)), 2, 0);
- case INST_JUMP_TRUE1:
- NEXT_INST_F((match? TclGetInt1AtPtr(pc+1) : 2), 2, 0);
- case INST_JUMP_FALSE4:
- NEXT_INST_F((match? 5 : TclGetInt4AtPtr(pc+1)), 2, 0);
- case INST_JUMP_TRUE4:
- NEXT_INST_F((match? TclGetInt4AtPtr(pc+1) : 5), 2, 0);
- }
-#endif
- objResultPtr = TCONST(match);
- NEXT_INST_F(0, 2, 1);
+ JUMP_PEEPHOLE_F(match, 2, 2);
}
/*
@@ -4694,6 +5996,39 @@ TEBCresume(
int type1, type2;
long l1, l2, lResult;
+ case INST_NUM_TYPE:
+ if (GetNumberFromObj(NULL, OBJ_AT_TOS, &ptr1, &type1) != TCL_OK) {
+ type1 = 0;
+ } else if (type1 == TCL_NUMBER_LONG) {
+ /* value is between LONG_MIN and LONG_MAX */
+ /* [string is integer] is -UINT_MAX to UINT_MAX range */
+ int i;
+
+ if (Tcl_GetIntFromObj(NULL, OBJ_AT_TOS, &i) != TCL_OK) {
+ type1 = TCL_NUMBER_WIDE;
+ }
+#ifndef TCL_WIDE_INT_IS_LONG
+ } else if (type1 == TCL_NUMBER_WIDE) {
+ /* value is between WIDE_MIN and WIDE_MAX */
+ /* [string is wideinteger] is -UWIDE_MAX to UWIDE_MAX range */
+ int i;
+ if (Tcl_GetIntFromObj(NULL, OBJ_AT_TOS, &i) == TCL_OK) {
+ type1 = TCL_NUMBER_LONG;
+ }
+#endif
+ } else if (type1 == TCL_NUMBER_BIG) {
+ /* value is an integer outside the WIDE_MIN to WIDE_MAX range */
+ /* [string is wideinteger] is -UWIDE_MAX to UWIDE_MAX range */
+ Tcl_WideInt w;
+
+ if (Tcl_GetWideIntFromObj(NULL, OBJ_AT_TOS, &w) == TCL_OK) {
+ type1 = TCL_NUMBER_WIDE;
+ }
+ }
+ TclNewIntObj(objResultPtr, type1);
+ TRACE(("\"%.20s\" => %d\n", O2S(OBJ_AT_TOS), type1));
+ NEXT_INST_F(1, 1, 1);
+
case INST_EQ:
case INST_NEQ:
case INST_LT:
@@ -4778,21 +6113,9 @@ TEBCresume(
*/
foundResult:
- pc++;
-#ifndef TCL_COMPILE_DEBUG
- switch (*pc) {
- case INST_JUMP_FALSE1:
- NEXT_INST_F((iResult? 2 : TclGetInt1AtPtr(pc+1)), 2, 0);
- case INST_JUMP_TRUE1:
- NEXT_INST_F((iResult? TclGetInt1AtPtr(pc+1) : 2), 2, 0);
- case INST_JUMP_FALSE4:
- NEXT_INST_F((iResult? 5 : TclGetInt4AtPtr(pc+1)), 2, 0);
- case INST_JUMP_TRUE4:
- NEXT_INST_F((iResult? TclGetInt4AtPtr(pc+1) : 5), 2, 0);
- }
-#endif
- objResultPtr = TCONST(iResult);
- NEXT_INST_F(0, 2, 1);
+ TRACE(("\"%.20s\" \"%.20s\" => %d\n", O2S(valuePtr), O2S(value2Ptr),
+ iResult));
+ JUMP_PEEPHOLE_F(iResult, 1, 2);
}
case INST_MOD:
@@ -4877,15 +6200,15 @@ TEBCresume(
case INST_RSHIFT:
if (l2 < 0) {
- Tcl_SetResult(interp, "negative shift argument",
- TCL_STATIC);
-#if 0
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "negative shift argument", -1));
+#ifdef ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR
DECACHE_STACK_INFO();
Tcl_SetErrorCode(interp, "ARITH", "DOMAIN",
"domain error: argument not in valid range",
NULL);
CACHE_STACK_INFO();
-#endif
+#endif /* ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR */
goto gotError;
} else if (l1 == 0) {
TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
@@ -4925,15 +6248,15 @@ TEBCresume(
case INST_LSHIFT:
if (l2 < 0) {
- Tcl_SetResult(interp, "negative shift argument",
- TCL_STATIC);
-#if 0
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "negative shift argument", -1));
+#ifdef ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR
DECACHE_STACK_INFO();
Tcl_SetErrorCode(interp, "ARITH", "DOMAIN",
"domain error: argument not in valid range",
NULL);
CACHE_STACK_INFO();
-#endif
+#endif /* ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR */
goto gotError;
} else if (l1 == 0) {
TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
@@ -4948,15 +6271,14 @@ TEBCresume(
* good place to draw the line.
*/
- Tcl_SetResult(interp,
- "integer value too large to represent",
- TCL_STATIC);
-#if 0
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "integer value too large to represent", -1));
+#ifdef ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR
DECACHE_STACK_INFO();
Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW",
"integer value too large to represent", NULL);
CACHE_STACK_INFO();
-#endif
+#endif /* ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR */
goto gotError;
} else {
int shift = (int) l2;
@@ -5014,8 +6336,7 @@ TEBCresume(
TRACE_APPEND(("DIVIDE BY ZERO\n"));
goto divideByZero;
} else if (objResultPtr == GENERAL_ARITHMETIC_ERROR) {
- TRACE_APPEND(("ERROR: %s\n",
- TclGetString(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
goto gotError;
} else if (objResultPtr == NULL) {
TRACE_APPEND(("%s\n", O2S(valuePtr)));
@@ -5092,7 +6413,7 @@ TEBCresume(
w1 = (Tcl_WideInt) l1;
w2 = (Tcl_WideInt) l2;
wResult = w1 + w2;
-#ifdef NO_WIDE_TYPE
+#ifdef TCL_WIDE_INT_IS_LONG
/*
* Check for overflow.
*/
@@ -5107,7 +6428,7 @@ TEBCresume(
w1 = (Tcl_WideInt) l1;
w2 = (Tcl_WideInt) l2;
wResult = w1 - w2;
-#ifdef NO_WIDE_TYPE
+#ifdef TCL_WIDE_INT_IS_LONG
/*
* Must check for overflow. The macro tests for overflows in
* sums by looking at the sign bits. As we have a subtraction
@@ -5187,8 +6508,7 @@ TEBCresume(
TRACE_APPEND(("EXPONENT OF ZERO\n"));
goto exponOfZero;
} else if (objResultPtr == GENERAL_ARITHMETIC_ERROR) {
- TRACE_APPEND(("ERROR: %s\n",
- TclGetString(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
goto gotError;
} else if (objResultPtr == NULL) {
TRACE_APPEND(("%s\n", O2S(valuePtr)));
@@ -5206,7 +6526,7 @@ TEBCresume(
/* TODO - check claim that taking address of b harms performance */
/* TODO - consider optimization search for constants */
if (TclGetBooleanFromObj(NULL, valuePtr, &b) != TCL_OK) {
- TRACE(("\"%.20s\" => ILLEGAL TYPE %s\n", O2S(valuePtr),
+ TRACE(("\"%.20s\" => ERROR: illegal type %s\n", O2S(valuePtr),
(valuePtr->typePtr? valuePtr->typePtr->name : "null")));
DECACHE_STACK_INFO();
IllegalExprOperandType(interp, pc, valuePtr);
@@ -5215,18 +6535,20 @@ TEBCresume(
}
/* TODO: Consider peephole opt. */
objResultPtr = TCONST(!b);
+ TRACE_WITH_OBJ(("%s => ", O2S(valuePtr)), objResultPtr);
NEXT_INST_F(1, 1, 1);
}
- case INST_BITNOT:
+ case INST_BITNOT:
valuePtr = OBJ_AT_TOS;
+ TRACE(("\"%.20s\" => ", O2S(valuePtr)));
if ((GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK)
|| (type1==TCL_NUMBER_NAN) || (type1==TCL_NUMBER_DOUBLE)) {
/*
* ... ~$NonInteger => raise an error.
*/
- TRACE(("\"%.20s\" => ILLEGAL TYPE %s \n", O2S(valuePtr),
+ TRACE_APPEND(("ERROR: illegal type %s\n",
(valuePtr->typePtr? valuePtr->typePtr->name : "null")));
DECACHE_STACK_INFO();
IllegalExprOperandType(interp, pc, valuePtr);
@@ -5237,23 +6559,28 @@ TEBCresume(
l1 = *((const long *) ptr1);
if (Tcl_IsShared(valuePtr)) {
TclNewLongObj(objResultPtr, ~l1);
+ TRACE_APPEND(("%s\n", O2S(objResultPtr)));
NEXT_INST_F(1, 1, 1);
}
TclSetLongObj(valuePtr, ~l1);
+ TRACE_APPEND(("%s\n", O2S(valuePtr)));
NEXT_INST_F(1, 0, 0);
}
objResultPtr = ExecuteExtendedUnaryMathOp(*pc, valuePtr);
if (objResultPtr != NULL) {
+ TRACE_APPEND(("%s\n", O2S(objResultPtr)));
NEXT_INST_F(1, 1, 1);
} else {
+ TRACE_APPEND(("%s\n", O2S(valuePtr)));
NEXT_INST_F(1, 0, 0);
}
case INST_UMINUS:
valuePtr = OBJ_AT_TOS;
+ TRACE(("\"%.20s\" => ", O2S(valuePtr)));
if ((GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK)
|| IsErroringNaNType(type1)) {
- TRACE(("\"%.20s\" => ILLEGAL TYPE %s \n", O2S(valuePtr),
+ TRACE_APPEND(("ERROR: illegal type %s \n",
(valuePtr->typePtr? valuePtr->typePtr->name : "null")));
DECACHE_STACK_INFO();
IllegalExprOperandType(interp, pc, valuePtr);
@@ -5263,23 +6590,28 @@ TEBCresume(
switch (type1) {
case TCL_NUMBER_NAN:
/* -NaN => NaN */
+ TRACE_APPEND(("%s\n", O2S(valuePtr)));
NEXT_INST_F(1, 0, 0);
case TCL_NUMBER_LONG:
l1 = *((const long *) ptr1);
if (l1 != LONG_MIN) {
if (Tcl_IsShared(valuePtr)) {
TclNewLongObj(objResultPtr, -l1);
+ TRACE_APPEND(("%s\n", O2S(objResultPtr)));
NEXT_INST_F(1, 1, 1);
}
TclSetLongObj(valuePtr, -l1);
+ TRACE_APPEND(("%s\n", O2S(valuePtr)));
NEXT_INST_F(1, 0, 0);
}
/* FALLTHROUGH */
}
objResultPtr = ExecuteExtendedUnaryMathOp(*pc, valuePtr);
if (objResultPtr != NULL) {
+ TRACE_APPEND(("%s\n", O2S(objResultPtr)));
NEXT_INST_F(1, 1, 1);
} else {
+ TRACE_APPEND(("%s\n", O2S(valuePtr)));
NEXT_INST_F(1, 0, 0);
}
@@ -5292,6 +6624,7 @@ TEBCresume(
*/
valuePtr = OBJ_AT_TOS;
+ TRACE(("\"%.20s\" => ", O2S(valuePtr)));
if (GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) {
if (*pc == INST_UPLUS) {
@@ -5299,7 +6632,7 @@ TEBCresume(
* ... +$NonNumeric => raise an error.
*/
- TRACE(("\"%.20s\" => ILLEGAL TYPE %s \n", O2S(valuePtr),
+ TRACE_APPEND(("ERROR: illegal type %s\n",
(valuePtr->typePtr? valuePtr->typePtr->name:"null")));
DECACHE_STACK_INFO();
IllegalExprOperandType(interp, pc, valuePtr);
@@ -5308,7 +6641,7 @@ TEBCresume(
}
/* ... TryConvertToNumeric($NonNumeric) is acceptable */
- TRACE(("\"%.20s\" => not numeric\n", O2S(valuePtr)));
+ TRACE_APPEND(("not numeric\n"));
NEXT_INST_F(1, 0, 0);
}
if (IsErroringNaNType(type1)) {
@@ -5317,7 +6650,7 @@ TEBCresume(
* ... +$NonNumeric => raise an error.
*/
- TRACE(("\"%.20s\" => ILLEGAL TYPE %s \n", O2S(valuePtr),
+ TRACE_APPEND(("ERROR: illegal type %s\n",
(valuePtr->typePtr? valuePtr->typePtr->name:"null")));
DECACHE_STACK_INFO();
IllegalExprOperandType(interp, pc, valuePtr);
@@ -5327,8 +6660,7 @@ TEBCresume(
* Numeric conversion of NaN -> error.
*/
- TRACE(("\"%.20s\" => IEEE FLOATING PT ERROR\n",
- O2S(objResultPtr)));
+ TRACE_APPEND(("ERROR: IEEE floating pt error\n"));
DECACHE_STACK_INFO();
TclExprFloatError(interp, *((const double *) ptr1));
CACHE_STACK_INFO();
@@ -5346,7 +6678,7 @@ TEBCresume(
*/
if (valuePtr->bytes == NULL) {
- TRACE(("\"%.20s\" => numeric, same Tcl_Obj\n", O2S(valuePtr)));
+ TRACE_APPEND(("numeric, same Tcl_Obj\n"));
NEXT_INST_F(1, 0, 0);
}
if (Tcl_IsShared(valuePtr)) {
@@ -5361,11 +6693,11 @@ TEBCresume(
valuePtr->bytes = NULL;
objResultPtr = Tcl_DuplicateObj(valuePtr);
valuePtr->bytes = savedString;
- TRACE(("\"%.20s\" => numeric, new Tcl_Obj\n", O2S(valuePtr)));
+ TRACE_APPEND(("numeric, new Tcl_Obj\n"));
NEXT_INST_F(1, 1, 1);
}
TclInvalidateStringRep(valuePtr);
- TRACE(("\"%.20s\" => numeric, same Tcl_Obj\n", O2S(valuePtr)));
+ TRACE_APPEND(("numeric, same Tcl_Obj\n"));
NEXT_INST_F(1, 0, 0);
}
@@ -5374,6 +6706,17 @@ TEBCresume(
* -----------------------------------------------------------------
*/
+ case INST_TRY_CVT_TO_BOOLEAN:
+ valuePtr = OBJ_AT_TOS;
+ if (valuePtr->typePtr == &tclBooleanType) {
+ objResultPtr = TCONST(1);
+ } else {
+ int result = (TclSetBooleanFromAny(NULL, valuePtr) == TCL_OK);
+ objResultPtr = TCONST(result);
+ }
+ TRACE_WITH_OBJ(("\"%.30s\" => ", O2S(valuePtr)), objResultPtr);
+ NEXT_INST_F(1, 0, 1);
+
case INST_BREAK:
/*
DECACHE_STACK_INFO();
@@ -5382,6 +6725,7 @@ TEBCresume(
*/
result = TCL_BREAK;
cleanup = 0;
+ TRACE(("=> BREAK!\n"));
goto processExceptionReturn;
case INST_CONTINUE:
@@ -5392,6 +6736,7 @@ TEBCresume(
*/
result = TCL_CONTINUE;
cleanup = 0;
+ TRACE(("=> CONTINUE!\n"));
goto processExceptionReturn;
{
@@ -5403,7 +6748,7 @@ TEBCresume(
int varIndex, valIndex, continueLoop, j, iterTmpIndex;
long i;
- case INST_FOREACH_START4:
+ case INST_FOREACH_START4: /* DEPRECATED */
/*
* Initialize the temporary local var that holds the count of the
* number of iterations of the loop body to -1.
@@ -5436,13 +6781,14 @@ TEBCresume(
NEXT_INST_F(5, 0, 0);
#endif
- case INST_FOREACH_STEP4:
+ case INST_FOREACH_STEP4: /* DEPRECATED */
/*
* "Step" a foreach loop (i.e., begin its next iteration) by assigning
* the next value list element to each loop var.
*/
opnd = TclGetUInt4AtPtr(pc+1);
+ TRACE(("%u => ", opnd));
infoPtr = codePtr->auxDataArrayPtr[opnd].clientData;
numLists = infoPtr->numLists;
@@ -5469,8 +6815,8 @@ TEBCresume(
listVarPtr = LOCAL(listTmpIndex);
listPtr = listVarPtr->value.objPtr;
if (TclListObjLength(interp, listPtr, &listLen) != TCL_OK) {
- TRACE_WITH_OBJ(("%u => ERROR converting list %ld, \"%s\": ",
- opnd, i, O2S(listPtr)), Tcl_GetObjResult(interp));
+ TRACE_APPEND(("ERROR converting list %ld, \"%.30s\": %s\n",
+ i, O2S(listPtr), O2S(Tcl_GetObjResult(interp))));
goto gotError;
}
if (listLen > iterNum * numVars) {
@@ -5525,9 +6871,9 @@ TEBCresume(
if (TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
valuePtr, TCL_LEAVE_ERR_MSG, varIndex)==NULL){
CACHE_STACK_INFO();
- TRACE_WITH_OBJ((
- "%u => ERROR init. index temp %d: ",
- opnd,varIndex), Tcl_GetObjResult(interp));
+ TRACE_APPEND((
+ "ERROR init. index temp %d: %s\n",
+ varIndex, O2S(Tcl_GetObjResult(interp))));
TclDecrRefCount(listPtr);
goto gotError;
}
@@ -5539,8 +6885,8 @@ TEBCresume(
listTmpIndex++;
}
}
- TRACE(("%u => %d lists, iter %d, %s loop\n", opnd, numLists,
- iterNum, (continueLoop? "continue" : "exit")));
+ TRACE_APPEND(("%d lists, iter %d, %s loop\n",
+ numLists, iterNum, (continueLoop? "continue" : "exit")));
/*
* Run-time peep-hole optimisation: the compiler ALWAYS follows
@@ -5554,6 +6900,200 @@ TEBCresume(
} else {
NEXT_INST_F((continueLoop? 5 : TclGetInt4AtPtr(pc+1)), 0, 0);
}
+
+ }
+ {
+ ForeachInfo *infoPtr;
+ Tcl_Obj *listPtr, **elements, *tmpPtr;
+ ForeachVarList *varListPtr;
+ int numLists, iterMax, listLen, numVars;
+ int iterTmp, iterNum, listTmpDepth;
+ int varIndex, valIndex, j;
+ long i;
+
+ case INST_FOREACH_START:
+ /*
+ * Initialize the data for the looping construct, pushing the
+ * corresponding Tcl_Objs to the stack.
+ */
+
+ opnd = TclGetUInt4AtPtr(pc+1);
+ infoPtr = codePtr->auxDataArrayPtr[opnd].clientData;
+ numLists = infoPtr->numLists;
+ TRACE(("%u => ", opnd));
+
+ /*
+ * Compute the number of iterations that will be run: iterMax
+ */
+
+ iterMax = 0;
+ listTmpDepth = numLists-1;
+ for (i = 0; i < numLists; i++) {
+ varListPtr = infoPtr->varLists[i];
+ numVars = varListPtr->numVars;
+ listPtr = OBJ_AT_DEPTH(listTmpDepth);
+ if (TclListObjLength(interp, listPtr, &listLen) != TCL_OK) {
+ TRACE_APPEND(("ERROR converting list %ld, \"%s\": %s",
+ i, O2S(listPtr), O2S(Tcl_GetObjResult(interp))));
+ goto gotError;
+ }
+ if (Tcl_IsShared(listPtr)) {
+ objPtr = TclListObjCopy(NULL, listPtr);
+ Tcl_IncrRefCount(objPtr);
+ Tcl_DecrRefCount(listPtr);
+ OBJ_AT_DEPTH(listTmpDepth) = objPtr;
+ }
+ iterTmp = (listLen + (numVars - 1))/numVars;
+ if (iterTmp > iterMax) {
+ iterMax = iterTmp;
+ }
+ listTmpDepth--;
+ }
+
+ /*
+ * Store the iterNum and iterMax in a single Tcl_Obj; we keep a
+ * nul-string obj with the pointer stored in the ptrValue so that the
+ * thing is properly garbage collected. THIS OBJ MAKES NO SENSE, but
+ * it will never leave this scope and is read-only.
+ */
+
+ TclNewObj(tmpPtr);
+ tmpPtr->internalRep.twoPtrValue.ptr1 = INT2PTR(0);
+ tmpPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(iterMax);
+ PUSH_OBJECT(tmpPtr); /* iterCounts object */
+
+ /*
+ * Store a pointer to the ForeachInfo struct; same dirty trick
+ * as above
+ */
+
+ TclNewObj(tmpPtr);
+ tmpPtr->internalRep.otherValuePtr = infoPtr;
+ PUSH_OBJECT(tmpPtr); /* infoPtr object */
+ TRACE_APPEND(("jump to loop step\n"));
+
+ /*
+ * Jump directly to the INST_FOREACH_STEP instruction; the C code just
+ * falls through.
+ */
+
+ pc += 5 - infoPtr->loopCtTemp;
+
+ case INST_FOREACH_STEP:
+ /*
+ * "Step" a foreach loop (i.e., begin its next iteration) by assigning
+ * the next value list element to each loop var.
+ */
+
+ tmpPtr = OBJ_AT_TOS;
+ infoPtr = tmpPtr->internalRep.otherValuePtr;
+ numLists = infoPtr->numLists;
+ TRACE(("=> "));
+
+ tmpPtr = OBJ_AT_DEPTH(1);
+ iterNum = PTR2INT(tmpPtr->internalRep.twoPtrValue.ptr1);
+ iterMax = PTR2INT(tmpPtr->internalRep.twoPtrValue.ptr2);
+
+ /*
+ * If some list still has a remaining list element iterate one more
+ * time. Assign to var the next element from its value list.
+ */
+
+ if (iterNum < iterMax) {
+ /*
+ * Set the variables and jump back to run the body
+ */
+
+ tmpPtr->internalRep.twoPtrValue.ptr1 = INT2PTR(iterNum + 1);
+
+ listTmpDepth = numLists + 1;
+
+ for (i = 0; i < numLists; i++) {
+ varListPtr = infoPtr->varLists[i];
+ numVars = varListPtr->numVars;
+
+ listPtr = OBJ_AT_DEPTH(listTmpDepth);
+ TclListObjGetElements(interp, listPtr, &listLen, &elements);
+
+ valIndex = (iterNum * numVars);
+ for (j = 0; j < numVars; j++) {
+ if (valIndex >= listLen) {
+ TclNewObj(valuePtr);
+ } else {
+ valuePtr = elements[valIndex];
+ }
+
+ varIndex = varListPtr->varIndexes[j];
+ varPtr = LOCAL(varIndex);
+ while (TclIsVarLink(varPtr)) {
+ varPtr = varPtr->value.linkPtr;
+ }
+ if (TclIsVarDirectWritable(varPtr)) {
+ value2Ptr = varPtr->value.objPtr;
+ if (valuePtr != value2Ptr) {
+ if (value2Ptr != NULL) {
+ TclDecrRefCount(value2Ptr);
+ }
+ varPtr->value.objPtr = valuePtr;
+ Tcl_IncrRefCount(valuePtr);
+ }
+ } else {
+ DECACHE_STACK_INFO();
+ if (TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
+ valuePtr, TCL_LEAVE_ERR_MSG, varIndex)==NULL){
+ CACHE_STACK_INFO();
+ TRACE_APPEND(("ERROR init. index temp %d: %.30s",
+ varIndex, O2S(Tcl_GetObjResult(interp))));
+ goto gotError;
+ }
+ CACHE_STACK_INFO();
+ }
+ valIndex++;
+ }
+ listTmpDepth--;
+ }
+ TRACE_APPEND(("jump to loop start\n"));
+ /* loopCtTemp being 'misused' for storing the jump size */
+ NEXT_INST_F(infoPtr->loopCtTemp, 0, 0);
+ }
+
+ TRACE_APPEND(("loop has no more iterations\n"));
+#ifdef TCL_COMPILE_DEBUG
+ NEXT_INST_F(1, 0, 0);
+#else
+ /*
+ * FALL THROUGH
+ */
+ pc++;
+#endif
+
+ case INST_FOREACH_END:
+ /* THIS INSTRUCTION IS ONLY CALLED AS A BREAK TARGET */
+ tmpPtr = OBJ_AT_TOS;
+ infoPtr = tmpPtr->internalRep.otherValuePtr;
+ numLists = infoPtr->numLists;
+ TRACE(("=> loop terminated\n"));
+ NEXT_INST_V(1, numLists+2, 0);
+
+ case INST_LMAP_COLLECT:
+ /*
+ * This instruction is only issued by lmap. The stack is:
+ * - result
+ * - infoPtr
+ * - loop counters
+ * - valLists
+ * - collecting obj (unshared)
+ * The instruction lappends the result to the collecting obj.
+ */
+
+ tmpPtr = OBJ_AT_DEPTH(1);
+ infoPtr = tmpPtr->internalRep.otherValuePtr;
+ numLists = infoPtr->numLists;
+ TRACE_APPEND(("=> appending to list at depth %d\n", 3 + numLists));
+
+ objPtr = OBJ_AT_DEPTH(3 + numLists);
+ Tcl_ListObjAppendElement(NULL, objPtr, OBJ_AT_TOS);
+ NEXT_INST_F(1, 1, 0);
}
case INST_BEGIN_CATCH4:
@@ -5615,7 +7155,8 @@ TEBCresume(
if (code < TCL_ERROR || code > TCL_CONTINUE) {
code = TCL_CONTINUE + 1;
}
- NEXT_INST_F(2*code -1, 1, 0);
+ TRACE(("\"%s\" => jump offset %d\n", O2S(OBJ_AT_TOS), 2*code-1));
+ NEXT_INST_F(2*code-1, 1, 0);
}
/*
@@ -5625,46 +7166,86 @@ TEBCresume(
{
int opnd2, allocateDict, done, i, allocdict;
- Tcl_Obj *dictPtr, *statePtr, *keyPtr;
+ Tcl_Obj *dictPtr, *statePtr, *keyPtr, *listPtr, *varNamePtr, *keysPtr;
Tcl_Obj *emptyPtr, **keyPtrPtr;
Tcl_DictSearch *searchPtr;
DictUpdateInfo *duiPtr;
+ case INST_DICT_VERIFY:
+ dictPtr = OBJ_AT_TOS;
+ TRACE(("\"%.30s\" => ", O2S(dictPtr)));
+ if (Tcl_DictObjSize(interp, dictPtr, &done) != TCL_OK) {
+ TRACE_APPEND(("ERROR verifying dictionary nature of \"%.30s\": %s\n",
+ O2S(dictPtr), O2S(Tcl_GetObjResult(interp))));
+ goto gotError;
+ }
+ TRACE_APPEND(("OK\n"));
+ NEXT_INST_F(1, 1, 0);
+
case INST_DICT_GET:
+ case INST_DICT_EXISTS: {
+ register Tcl_Interp *interp2 = interp;
+ register int found;
+
opnd = TclGetUInt4AtPtr(pc+1);
TRACE(("%u => ", opnd));
dictPtr = OBJ_AT_DEPTH(opnd);
+ if (*pc == INST_DICT_EXISTS) {
+ interp2 = NULL;
+ }
if (opnd > 1) {
- dictPtr = TclTraceDictPath(interp, dictPtr, opnd-1,
+ dictPtr = TclTraceDictPath(interp2, dictPtr, opnd-1,
&OBJ_AT_DEPTH(opnd-1), DICT_PATH_READ);
if (dictPtr == NULL) {
+ if (*pc == INST_DICT_EXISTS) {
+ found = 0;
+ goto afterDictExists;
+ }
TRACE_WITH_OBJ((
- "%u => ERROR tracing dictionary path into \"%s\": ",
- opnd, O2S(OBJ_AT_DEPTH(opnd))),
+ "ERROR tracing dictionary path into \"%.30s\": ",
+ O2S(OBJ_AT_DEPTH(opnd))),
Tcl_GetObjResult(interp));
goto gotError;
}
}
- if (Tcl_DictObjGet(interp, dictPtr, OBJ_AT_TOS,
+ if (Tcl_DictObjGet(interp2, dictPtr, OBJ_AT_TOS,
&objResultPtr) == TCL_OK) {
- if (objResultPtr) {
- TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
- NEXT_INST_V(5, opnd+1, 1);
+ if (*pc == INST_DICT_EXISTS) {
+ found = (objResultPtr ? 1 : 0);
+ goto afterDictExists;
+ }
+ if (!objResultPtr) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "key \"%s\" not known in dictionary",
+ TclGetString(OBJ_AT_TOS)));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT",
+ TclGetString(OBJ_AT_TOS), NULL);
+ CACHE_STACK_INFO();
+ TRACE_ERROR(interp);
+ goto gotError;
}
- DECACHE_STACK_INFO();
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "key \"", TclGetString(OBJ_AT_TOS),
- "\" not known in dictionary", NULL);
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT",
- TclGetString(OBJ_AT_TOS), NULL);
- CACHE_STACK_INFO();
- TRACE_WITH_OBJ(("%u => ERROR ", opnd), Tcl_GetObjResult(interp));
+ TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+ NEXT_INST_V(5, opnd+1, 1);
+ } else if (*pc != INST_DICT_EXISTS) {
+ TRACE_APPEND(("ERROR reading leaf dictionary key \"%.30s\": %s",
+ O2S(dictPtr), O2S(Tcl_GetObjResult(interp))));
+ goto gotError;
} else {
- TRACE_WITH_OBJ((
- "%u => ERROR reading leaf dictionary key \"%s\": ",
- opnd, O2S(dictPtr)), Tcl_GetObjResult(interp));
+ found = 0;
}
- goto gotError;
+ afterDictExists:
+ TRACE_APPEND(("%d\n", found));
+
+ /*
+ * The INST_DICT_EXISTS instruction is usually followed by a
+ * conditional jump, so we can take advantage of this to do some
+ * peephole optimization (note that we're careful to not close out
+ * someone doing something else).
+ */
+
+ JUMP_PEEPHOLE_V(found, 5, opnd+1);
+ }
case INST_DICT_SET:
case INST_DICT_UNSET:
@@ -5718,7 +7299,7 @@ TEBCresume(
}
result = TclIncrObj(interp, valuePtr, value2Ptr);
if (result == TCL_OK) {
- Tcl_InvalidateStringRep(dictPtr);
+ TclInvalidateStringRep(dictPtr);
}
TclDecrRefCount(value2Ptr);
}
@@ -5737,8 +7318,8 @@ TEBCresume(
if (allocateDict) {
TclDecrRefCount(dictPtr);
}
- TRACE_WITH_OBJ(("%u %u => ERROR updating dictionary: ",
- opnd, opnd2), Tcl_GetObjResult(interp));
+ TRACE_APPEND(("ERROR updating dictionary: %s\n",
+ O2S(Tcl_GetObjResult(interp))));
goto checkForCatch;
}
@@ -5760,8 +7341,7 @@ TEBCresume(
CACHE_STACK_INFO();
TclDecrRefCount(dictPtr);
if (objResultPtr == NULL) {
- TRACE_APPEND(("ERROR: %.30s\n",
- O2S(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
goto gotError;
}
}
@@ -5770,7 +7350,7 @@ TEBCresume(
NEXT_INST_V(10, cleanup, 0);
}
#endif
- TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+ TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
NEXT_INST_V(9, cleanup, 1);
case INST_DICT_APPEND:
@@ -5803,6 +7383,7 @@ TEBCresume(
if (allocateDict) {
TclDecrRefCount(dictPtr);
}
+ TRACE_ERROR(interp);
goto gotError;
}
@@ -5851,6 +7432,7 @@ TEBCresume(
if (allocateDict) {
TclDecrRefCount(dictPtr);
}
+ TRACE_ERROR(interp);
goto gotError;
}
Tcl_DictObjPut(NULL, dictPtr, OBJ_UNDER_TOS, valuePtr);
@@ -5860,6 +7442,7 @@ TEBCresume(
if (allocateDict) {
TclDecrRefCount(dictPtr);
}
+ TRACE_ERROR(interp);
goto gotError;
}
@@ -5896,8 +7479,7 @@ TEBCresume(
CACHE_STACK_INFO();
TclDecrRefCount(dictPtr);
if (objResultPtr == NULL) {
- TRACE_APPEND(("ERROR: %.30s\n",
- O2S(Tcl_GetObjResult(interp))));
+ TRACE_ERROR(interp);
goto gotError;
}
}
@@ -5917,6 +7499,7 @@ TEBCresume(
if (Tcl_DictObjFirst(interp, dictPtr, searchPtr, &keyPtr,
&valuePtr, &done) != TCL_OK) {
ckfree(searchPtr);
+ TRACE_ERROR(interp);
goto gotError;
}
TclNewObj(statePtr);
@@ -5952,8 +7535,9 @@ TEBCresume(
PUSH_OBJECT(valuePtr);
PUSH_OBJECT(keyPtr);
}
+ TRACE_APPEND(("\"%.30s\" \"%.30s\" %d\n",
+ O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), done));
-#ifndef TCL_COMPILE_DEBUG
/*
* The INST_DICT_FIRST and INST_DICT_NEXT instructsions are always
* followed by a conditional jump, so we can take advantage of this to
@@ -5961,37 +7545,17 @@ TEBCresume(
* out someone doing something else).
*/
- pc += 5;
- switch (*pc) {
- case INST_JUMP_FALSE1:
- NEXT_INST_F((done ? 2 : TclGetInt1AtPtr(pc+1)), 0, 0);
- case INST_JUMP_FALSE4:
- NEXT_INST_F((done ? 5 : TclGetInt4AtPtr(pc+1)), 0, 0);
- case INST_JUMP_TRUE1:
- NEXT_INST_F((done ? TclGetInt1AtPtr(pc+1) : 2), 0, 0);
- case INST_JUMP_TRUE4:
- NEXT_INST_F((done ? TclGetInt4AtPtr(pc+1) : 5), 0, 0);
- default:
- pc -= 5;
- /* fall through to non-debug handling */
- }
-#endif
-
- TRACE_APPEND(("\"%.30s\" \"%.30s\" %d",
- O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), done));
- objResultPtr = TCONST(done);
- /* TODO: consider opt like INST_FOREACH_STEP4 */
- NEXT_INST_F(5, 0, 1);
+ JUMP_PEEPHOLE_F(done, 5, 0);
case INST_DICT_UPDATE_START:
opnd = TclGetUInt4AtPtr(pc+1);
opnd2 = TclGetUInt4AtPtr(pc+5);
+ TRACE(("%u => ", opnd));
varPtr = LOCAL(opnd);
duiPtr = codePtr->auxDataArrayPtr[opnd2].clientData;
while (TclIsVarLink(varPtr)) {
varPtr = varPtr->value.linkPtr;
}
- TRACE(("%u => ", opnd));
if (TclIsVarDirectReadable(varPtr)) {
dictPtr = varPtr->value.objPtr;
} else {
@@ -6000,11 +7564,13 @@ TEBCresume(
TCL_LEAVE_ERR_MSG, opnd);
CACHE_STACK_INFO();
if (dictPtr == NULL) {
+ TRACE_ERROR(interp);
goto gotError;
}
}
if (TclListObjGetElements(interp, OBJ_AT_TOS, &length,
&keyPtrPtr) != TCL_OK) {
+ TRACE_ERROR(interp);
goto gotError;
}
if (length != duiPtr->length) {
@@ -6013,6 +7579,7 @@ TEBCresume(
for (i=0 ; i<length ; i++) {
if (Tcl_DictObjGet(interp, dictPtr, keyPtrPtr[i],
&valuePtr) != TCL_OK) {
+ TRACE_ERROR(interp);
goto gotError;
}
varPtr = LOCAL(duiPtr->varIndices[i]);
@@ -6028,21 +7595,23 @@ TEBCresume(
valuePtr, TCL_LEAVE_ERR_MSG,
duiPtr->varIndices[i]) == NULL) {
CACHE_STACK_INFO();
+ TRACE_ERROR(interp);
goto gotError;
}
CACHE_STACK_INFO();
}
+ TRACE_APPEND(("OK\n"));
NEXT_INST_F(9, 0, 0);
case INST_DICT_UPDATE_END:
opnd = TclGetUInt4AtPtr(pc+1);
opnd2 = TclGetUInt4AtPtr(pc+5);
+ TRACE(("%u => ", opnd));
varPtr = LOCAL(opnd);
duiPtr = codePtr->auxDataArrayPtr[opnd2].clientData;
while (TclIsVarLink(varPtr)) {
varPtr = varPtr->value.linkPtr;
}
- TRACE(("%u => ", opnd));
if (TclIsVarDirectReadable(varPtr)) {
dictPtr = varPtr->value.objPtr;
} else {
@@ -6051,11 +7620,13 @@ TEBCresume(
CACHE_STACK_INFO();
}
if (dictPtr == NULL) {
+ TRACE_APPEND(("storage was unset\n"));
NEXT_INST_F(9, 1, 0);
}
if (Tcl_DictObjSize(interp, dictPtr, &length) != TCL_OK
|| TclListObjGetElements(interp, OBJ_AT_TOS, &length,
&keyPtrPtr) != TCL_OK) {
+ TRACE_ERROR(interp);
goto gotError;
}
allocdict = Tcl_IsShared(dictPtr);
@@ -6101,10 +7672,83 @@ TEBCresume(
if (allocdict) {
TclDecrRefCount(dictPtr);
}
+ TRACE_ERROR(interp);
goto gotError;
}
}
+ TRACE_APPEND(("written back\n"));
NEXT_INST_F(9, 1, 0);
+
+ case INST_DICT_EXPAND:
+ dictPtr = OBJ_UNDER_TOS;
+ listPtr = OBJ_AT_TOS;
+ TRACE(("\"%.30s\" \"%.30s\" =>", O2S(dictPtr), O2S(listPtr)));
+ if (TclListObjGetElements(interp, listPtr, &objc, &objv) != TCL_OK) {
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+ objResultPtr = TclDictWithInit(interp, dictPtr, objc, objv);
+ if (objResultPtr == NULL) {
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+ TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+ NEXT_INST_F(1, 2, 1);
+
+ case INST_DICT_RECOMBINE_STK:
+ keysPtr = POP_OBJECT();
+ varNamePtr = OBJ_UNDER_TOS;
+ listPtr = OBJ_AT_TOS;
+ TRACE(("\"%.30s\" \"%.30s\" \"%.30s\" => ",
+ O2S(varNamePtr), O2S(valuePtr), O2S(keysPtr)));
+ if (TclListObjGetElements(interp, listPtr, &objc, &objv) != TCL_OK) {
+ TRACE_ERROR(interp);
+ TclDecrRefCount(keysPtr);
+ goto gotError;
+ }
+ varPtr = TclObjLookupVarEx(interp, varNamePtr, NULL,
+ TCL_LEAVE_ERR_MSG, "set", 1, 1, &arrayPtr);
+ if (varPtr == NULL) {
+ TRACE_ERROR(interp);
+ TclDecrRefCount(keysPtr);
+ goto gotError;
+ }
+ DECACHE_STACK_INFO();
+ result = TclDictWithFinish(interp, varPtr,arrayPtr,varNamePtr,NULL,-1,
+ objc, objv, keysPtr);
+ CACHE_STACK_INFO();
+ TclDecrRefCount(keysPtr);
+ if (result != TCL_OK) {
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+ TRACE_APPEND(("OK\n"));
+ NEXT_INST_F(1, 2, 0);
+
+ case INST_DICT_RECOMBINE_IMM:
+ opnd = TclGetUInt4AtPtr(pc+1);
+ listPtr = OBJ_UNDER_TOS;
+ keysPtr = OBJ_AT_TOS;
+ varPtr = LOCAL(opnd);
+ TRACE(("%u <- \"%.30s\" \"%.30s\" => ", opnd, O2S(valuePtr),
+ O2S(keysPtr)));
+ if (TclListObjGetElements(interp, listPtr, &objc, &objv) != TCL_OK) {
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+ while (TclIsVarLink(varPtr)) {
+ varPtr = varPtr->value.linkPtr;
+ }
+ DECACHE_STACK_INFO();
+ result = TclDictWithFinish(interp, varPtr, NULL, NULL, NULL, opnd,
+ objc, objv, keysPtr);
+ CACHE_STACK_INFO();
+ if (result != TCL_OK) {
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+ TRACE_APPEND(("OK\n"));
+ NEXT_INST_F(5, 2, 0);
}
/*
@@ -6135,7 +7779,7 @@ TEBCresume(
*/
processExceptionReturn:
-#if TCL_COMPILE_DEBUG
+#ifdef TCL_COMPILE_DEBUG
switch (*pc) {
case INST_INVOKE_STK1:
opnd = TclGetUInt1AtPtr(pc+1);
@@ -6192,14 +7836,14 @@ TEBCresume(
rangePtr->codeOffset, rangePtr->continueOffset));
NEXT_INST_F(0, 0, 0);
}
-#if TCL_COMPILE_DEBUG
+#ifdef TCL_COMPILE_DEBUG
if (traceInstructions) {
objPtr = Tcl_GetObjResult(interp);
if ((result != TCL_ERROR) && (result != TCL_RETURN)) {
- TRACE_APPEND(("OTHER RETURN CODE %d, result= \"%s\"\n ",
+ TRACE_APPEND(("OTHER RETURN CODE %d, result=\"%.30s\"\n ",
result, O2S(objPtr)));
} else {
- TRACE_APPEND(("%s, result= \"%s\"\n",
+ TRACE_APPEND(("%s, result=\"%.30s\"\n",
StringForResultCode(result), O2S(objPtr)));
}
}
@@ -6212,10 +7856,10 @@ TEBCresume(
*/
divideByZero:
- DECACHE_STACK_INFO();
- Tcl_SetResult(interp, "divide by zero", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("divide by zero", -1));
+ DECACHE_STACK_INFO();
Tcl_SetErrorCode(interp, "ARITH", "DIVZERO", "divide by zero", NULL);
- CACHE_STACK_INFO();
+ CACHE_STACK_INFO();
goto gotError;
/*
@@ -6224,9 +7868,9 @@ TEBCresume(
*/
exponOfZero:
- DECACHE_STACK_INFO();
- Tcl_SetResult(interp, "exponentiation of zero by negative power",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "exponentiation of zero by negative power", -1));
+ DECACHE_STACK_INFO();
Tcl_SetErrorCode(interp, "ARITH", "DOMAIN",
"exponentiation of zero by negative power", NULL);
CACHE_STACK_INFO();
@@ -6254,7 +7898,7 @@ TEBCresume(
if ((result == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) {
const unsigned char *pcBeg;
- bytes = GetSrcInfoForPc(pc, codePtr, &length, &pcBeg);
+ bytes = GetSrcInfoForPc(pc, codePtr, &length, &pcBeg, NULL);
DECACHE_STACK_INFO();
TclLogCommandInfo(interp, codePtr->source, bytes,
bytes ? length : 0, pcBeg, tosPtr);
@@ -6268,8 +7912,9 @@ TEBCresume(
*/
while (auxObjList) {
- if ((catchTop != initCatchTop) &&
- (*catchTop > ((ptrdiff_t) auxObjList->internalRep.ptrAndLongRep.value))) {
+ if ((catchTop != initCatchTop)
+ && (*catchTop > (ptrdiff_t)
+ auxObjList->internalRep.ptrAndLongRep.value)) {
break;
}
POP_TAUX_OBJ();
@@ -6405,6 +8050,42 @@ TEBCresume(
TclStackFree(interp, TD); /* free my stack */
return result;
+
+ /*
+ * INST_START_CMD failure case removed where it doesn't bother that much
+ *
+ * Remark that if the interpreter is marked for deletion its
+ * compileEpoch is modified, so that the epoch check also verifies
+ * that the interp is not deleted. If no outside call has been made
+ * since the last check, it is safe to omit the check.
+
+ * case INST_START_CMD:
+ */
+
+ instStartCmdFailed:
+ {
+ const char *bytes;
+
+ checkInterp = 1;
+ length = 0;
+
+ /*
+ * We used to switch to direct eval; for NRE-awareness we now
+ * compile and eval the command so that this evaluation does not
+ * add a new TEBC instance. [Bug 2910748]
+ */
+
+ if (TclInterpReady(interp) == TCL_ERROR) {
+ goto gotError;
+ }
+
+ codePtr->flags |= TCL_BYTECODE_RECOMPILE;
+ bytes = GetSrcInfoForPc(pc, codePtr, &length, NULL, NULL);
+ opnd = TclGetUInt4AtPtr(pc+1);
+ pc += (opnd-1);
+ PUSH_OBJECT(Tcl_NewStringObj(bytes, length));
+ goto instEvalStk;
+ }
}
#undef codePtr
@@ -6415,6 +8096,58 @@ TEBCresume(
#undef auxObjList
#undef catchTop
#undef TCONST
+
+static int
+FinalizeOONext(
+ ClientData data[],
+ Tcl_Interp *interp,
+ int result)
+{
+ Interp *iPtr = (Interp *) interp;
+ CallContext *contextPtr = data[1];
+
+ /*
+ * Reset the variable lookup frame.
+ */
+
+ iPtr->varFramePtr = data[0];
+
+ /*
+ * Restore the call chain context index as we've finished the inner invoke
+ * and want to operate in the outer context again.
+ */
+
+ contextPtr->index = PTR2INT(data[2]);
+ contextPtr->skip = PTR2INT(data[3]);
+ contextPtr->oPtr->flags &= ~FILTER_HANDLING;
+ return result;
+}
+
+static int
+FinalizeOONextFilter(
+ ClientData data[],
+ Tcl_Interp *interp,
+ int result)
+{
+ Interp *iPtr = (Interp *) interp;
+ CallContext *contextPtr = data[1];
+
+ /*
+ * Reset the variable lookup frame.
+ */
+
+ iPtr->varFramePtr = data[0];
+
+ /*
+ * Restore the call chain context index as we've finished the inner invoke
+ * and want to operate in the outer context again.
+ */
+
+ contextPtr->index = PTR2INT(data[2]);
+ contextPtr->skip = PTR2INT(data[3]);
+ contextPtr->oPtr->flags |= FILTER_HANDLING;
+ return result;
+}
/*
*----------------------------------------------------------------------
@@ -6511,7 +8244,7 @@ ExecuteExtendedBinaryMathOp(
return constants[0];
}
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if (type1 == TCL_NUMBER_WIDE) {
w1 = *((const Tcl_WideInt *)ptr1);
if (type2 != TCL_NUMBER_BIG) {
@@ -6586,7 +8319,7 @@ ExecuteExtendedBinaryMathOp(
case TCL_NUMBER_LONG:
invalid = (*((const long *)ptr2) < 0L);
break;
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
invalid = (*((const Tcl_WideInt *)ptr2) < (Tcl_WideInt)0);
break;
@@ -6601,7 +8334,8 @@ ExecuteExtendedBinaryMathOp(
invalid = 0;
}
if (invalid) {
- Tcl_SetResult(interp, "negative shift argument", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "negative shift argument", -1));
return GENERAL_ARITHMETIC_ERROR;
}
@@ -6631,8 +8365,8 @@ ExecuteExtendedBinaryMathOp(
* place to draw the line.
*/
- Tcl_SetResult(interp, "integer value too large to represent",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "integer value too large to represent", -1));
return GENERAL_ARITHMETIC_ERROR;
}
shift = (int)(*((const long *)ptr2));
@@ -6669,7 +8403,7 @@ ExecuteExtendedBinaryMathOp(
case TCL_NUMBER_LONG:
zero = (*(const long *)ptr1 > 0L);
break;
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
zero = (*(const Tcl_WideInt *)ptr1 > (Tcl_WideInt)0);
break;
@@ -6690,7 +8424,7 @@ ExecuteExtendedBinaryMathOp(
}
shift = (int)(*(const long *)ptr2);
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
/*
* Handle shifts within the native wide range.
*/
@@ -6873,7 +8607,7 @@ ExecuteExtendedBinaryMathOp(
BIG_RESULT(&bigResult);
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE)) {
TclGetWideIntFromObj(NULL, valuePtr, &w1);
TclGetWideIntFromObj(NULL, value2Ptr, &w2);
@@ -6951,7 +8685,7 @@ ExecuteExtendedBinaryMathOp(
negativeExponent = (l2 < 0);
oddExponent = (int) (l2 & 1);
break;
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
w2 = *((const Tcl_WideInt *)ptr2);
negativeExponent = (w2 < 0);
@@ -7033,7 +8767,8 @@ ExecuteExtendedBinaryMathOp(
*/
if (type2 != TCL_NUMBER_LONG) {
- Tcl_SetResult(interp, "exponent too large", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "exponent too large", -1));
return GENERAL_ARITHMETIC_ERROR;
}
@@ -7142,7 +8877,7 @@ ExecuteExtendedBinaryMathOp(
#if (LONG_MAX > 0x7fffffff) || !defined(TCL_WIDE_INT_IS_LONG)
if (type1 == TCL_NUMBER_LONG) {
w1 = l1;
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
} else if (type1 == TCL_NUMBER_WIDE) {
w1 = *((const Tcl_WideInt *) ptr1);
#endif
@@ -7271,7 +9006,8 @@ ExecuteExtendedBinaryMathOp(
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
if (big2.used > 1) {
mp_clear(&big2);
- Tcl_SetResult(interp, "exponent too large", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "exponent too large", -1));
return GENERAL_ARITHMETIC_ERROR;
}
Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
@@ -7344,7 +9080,7 @@ ExecuteExtendedBinaryMathOp(
switch (opcode) {
case INST_ADD:
wResult = w1 + w2;
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE))
#endif
{
@@ -7360,7 +9096,7 @@ ExecuteExtendedBinaryMathOp(
case INST_SUB:
wResult = w1 - w2;
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE))
#endif
{
@@ -7486,7 +9222,7 @@ ExecuteExtendedUnaryMathOp(
switch (opcode) {
case INST_BITNOT:
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if (type == TCL_NUMBER_WIDE) {
w = *((const Tcl_WideInt *) ptr);
WIDE_RESULT(~w);
@@ -7508,7 +9244,7 @@ ExecuteExtendedUnaryMathOp(
}
TclBNInitBignumFromLong(&big, *(const long *) ptr);
break;
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
w = *((const Tcl_WideInt *) ptr);
if (w != LLONG_MIN) {
@@ -7560,7 +9296,7 @@ TclCompareTwoNumbers(
mp_int big1, big2;
double d1, d2, tmp;
long l1, l2;
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
Tcl_WideInt w1, w2;
#endif
@@ -7575,7 +9311,7 @@ TclCompareTwoNumbers(
l2 = *((const long *)ptr2);
longCompare:
return (l1 < l2) ? MP_LT : ((l1 > l2) ? MP_GT : MP_EQ);
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
w2 = *((const Tcl_WideInt *)ptr2);
w1 = (Tcl_WideInt)l1;
@@ -7627,7 +9363,7 @@ TclCompareTwoNumbers(
return compare;
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
w1 = *((const Tcl_WideInt *)ptr1);
switch (type2) {
@@ -7688,7 +9424,7 @@ TclCompareTwoNumbers(
}
l1 = (long) d1;
goto longCompare;
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
w2 = *((const Tcl_WideInt *)ptr2);
d2 = (double) w2;
@@ -7732,7 +9468,7 @@ TclCompareTwoNumbers(
case TCL_NUMBER_BIG:
Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
switch (type2) {
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
#endif
case TCL_NUMBER_LONG:
@@ -7865,11 +9601,10 @@ ValidatePcAndStackTop(
int stackTop, /* Current stack top. Must be between
* stackLowerBound and stackUpperBound
* (inclusive). */
- int stackLowerBound, /* Smallest legal value for stackTop. */
int checkStack) /* 0 if the stack depth check should be
* skipped. */
{
- int stackUpperBound = stackLowerBound + codePtr->maxStackDepth;
+ int stackUpperBound = codePtr->maxStackDepth;
/* Greatest legal value for stackTop. */
unsigned relativePc = (unsigned) (pc - codePtr->codeStart);
unsigned long codeStart = (unsigned long) codePtr->codeStart;
@@ -7887,13 +9622,13 @@ ValidatePcAndStackTop(
(unsigned) opCode, relativePc);
Tcl_Panic("TclNRExecuteByteCode execution failure: bad opcode");
}
- if (checkStack &&
- ((stackTop < stackLowerBound) || (stackTop > stackUpperBound))) {
+ if (checkStack &&
+ ((stackTop < 0) || (stackTop > stackUpperBound))) {
int numChars;
- const char *cmd = GetSrcInfoForPc(pc, codePtr, &numChars, NULL);
+ const char *cmd = GetSrcInfoForPc(pc, codePtr, &numChars, NULL, NULL);
- fprintf(stderr, "\nBad stack top %d at pc %u in TclNRExecuteByteCode (min %i, max %i)",
- stackTop, relativePc, stackLowerBound, stackUpperBound);
+ fprintf(stderr, "\nBad stack top %d at pc %u in TclNRExecuteByteCode (min 0, max %i)",
+ stackTop, relativePc, stackUpperBound);
if (cmd != NULL) {
Tcl_Obj *message;
@@ -7940,10 +9675,12 @@ IllegalExprOperandType(
ClientData ptr;
int type;
const unsigned char opcode = *pc;
- const char *description, *operator = operatorStrings[opcode - INST_LOR];
+ const char *description, *operator = "unknown";
if (opcode == INST_EXPON) {
operator = "**";
+ } else if (opcode <= INST_STR_NEQ) {
+ operator = operatorStrings[opcode - INST_LOR];
}
if (GetNumberFromObj(NULL, opndPtr, &ptr, &type) != TCL_OK) {
@@ -7974,7 +9711,7 @@ IllegalExprOperandType(
/*
*----------------------------------------------------------------------
*
- * TclGetSrcInfoForPc, GetSrcInfoForPc, TclGetSrcInfoForCmd --
+ * TclGetSrcInfoForPc, GetSrcInfoForPc, TclGetSourceFromFrame --
*
* Given a program counter value, finds the closest command in the
* bytecode code unit's CmdLocation array and returns information about
@@ -7995,16 +9732,26 @@ IllegalExprOperandType(
*----------------------------------------------------------------------
*/
-const char *
-TclGetSrcInfoForCmd(
- Interp *iPtr,
- int *lenPtr)
+Tcl_Obj *
+TclGetSourceFromFrame(
+ CmdFrame *cfPtr,
+ int objc,
+ Tcl_Obj *const objv[])
{
- CmdFrame *cfPtr = iPtr->cmdFramePtr;
- ByteCode *codePtr = (ByteCode *) cfPtr->data.tebc.codePtr;
-
- return GetSrcInfoForPc((unsigned char *) cfPtr->data.tebc.pc,
- codePtr, lenPtr, NULL);
+ if (cfPtr == NULL) {
+ return Tcl_NewListObj(objc, objv);
+ }
+ if (cfPtr->cmdObj == NULL) {
+ if (cfPtr->cmd == NULL) {
+ ByteCode *codePtr = (ByteCode *) cfPtr->data.tebc.codePtr;
+
+ cfPtr->cmd = GetSrcInfoForPc((unsigned char *)
+ cfPtr->data.tebc.pc, codePtr, &cfPtr->len, NULL, NULL);
+ }
+ cfPtr->cmdObj = Tcl_NewStringObj(cfPtr->cmd, cfPtr->len);
+ Tcl_IncrRefCount(cfPtr->cmdObj);
+ }
+ return cfPtr->cmdObj;
}
void
@@ -8013,13 +9760,16 @@ TclGetSrcInfoForPc(
{
ByteCode *codePtr = (ByteCode *) cfPtr->data.tebc.codePtr;
- if (cfPtr->cmd.str.cmd == NULL) {
- cfPtr->cmd.str.cmd = GetSrcInfoForPc(
+ assert(cfPtr->type == TCL_LOCATION_BC);
+
+ if (cfPtr->cmd == NULL) {
+
+ cfPtr->cmd = GetSrcInfoForPc(
(unsigned char *) cfPtr->data.tebc.pc, codePtr,
- &cfPtr->cmd.str.len, NULL);
+ &cfPtr->len, NULL, NULL);
}
- if (cfPtr->cmd.str.cmd != NULL) {
+ if (cfPtr->cmd != NULL) {
/*
* We now have the command. We can get the srcOffset back and from
* there find the list of word locations for this command.
@@ -8036,7 +9786,7 @@ TclGetSrcInfoForPc(
return;
}
- srcOffset = cfPtr->cmd.str.cmd - codePtr->source;
+ srcOffset = cfPtr->cmd - codePtr->source;
eclPtr = Tcl_GetHashValue(hePtr);
for (i=0; i < eclPtr->nuloc; i++) {
@@ -8069,16 +9819,19 @@ static const char *
GetSrcInfoForPc(
const unsigned char *pc, /* The program counter value for which to
* return the closest command's source info.
- * This points within a bytecode instruction in
- * codePtr's code. */
+ * This points within a bytecode instruction
+ * in codePtr's code. */
ByteCode *codePtr, /* The bytecode sequence in which to look up
* the command source for the pc. */
int *lengthPtr, /* If non-NULL, the location where the length
* of the command's source should be stored.
* If NULL, no length is stored. */
- const unsigned char **pcBeg)/* If non-NULL, the bytecode location
+ const unsigned char **pcBeg,/* If non-NULL, the bytecode location
* where the current instruction starts.
* If NULL; no pointer is stored. */
+ int *cmdIdxPtr) /* If non-NULL, the location where the index
+ * of the command containing the pc should
+ * be stored. */
{
register int pcOffset = (pc - codePtr->codeStart);
int numCmds = codePtr->numCommands;
@@ -8088,6 +9841,7 @@ GetSrcInfoForPc(
int bestDist = INT_MAX; /* Distance of pc to best cmd's start pc. */
int bestSrcOffset = -1; /* Initialized to avoid compiler warning. */
int bestSrcLength = -1; /* Initialized to avoid compiler warning. */
+ int bestCmdIdx = -1;
if ((pcOffset < 0) || (pcOffset >= codePtr->numCodeBytes)) {
if (pcBeg != NULL) *pcBeg = NULL;
@@ -8155,24 +9909,26 @@ GetSrcInfoForPc(
bestDist = dist;
bestSrcOffset = srcOffset;
bestSrcLength = srcLen;
+ bestCmdIdx = i;
}
}
}
if (pcBeg != NULL) {
- const unsigned char *curr,*prev;
+ const unsigned char *curr, *prev;
- /* Walk from beginning of command or BC to pc, by complete
- * instructions. Stop when crossing pc; keep previous */
+ /*
+ * Walk from beginning of command or BC to pc, by complete
+ * instructions. Stop when crossing pc; keep previous.
+ */
- curr = prev = ((bestDist == INT_MAX) ?
- codePtr->codeStart :
- pc - bestDist);
+ curr = ((bestDist == INT_MAX) ? codePtr->codeStart : pc - bestDist);
+ prev = curr;
while (curr <= pc) {
prev = curr;
curr += tclInstructionTable[*curr].numBytes;
}
- *pcBeg = prev ;
+ *pcBeg = prev;
}
if (bestDist == INT_MAX) {
@@ -8183,6 +9939,10 @@ GetSrcInfoForPc(
*lengthPtr = bestSrcLength;
}
+ if (cmdIdxPtr != NULL) {
+ *cmdIdxPtr = bestCmdIdx;
+ }
+
return (codePtr->source + bestSrcOffset);
}
diff --git a/generic/tclFCmd.c b/generic/tclFCmd.c
index 048fa57..6452fff 100644
--- a/generic/tclFCmd.c
+++ b/generic/tclFCmd.c
@@ -147,9 +147,9 @@ FileCopyRename(
if ((objc - i) > 2) {
errno = ENOTDIR;
Tcl_PosixError(interp);
- Tcl_AppendResult(interp, "error ",
- (copyFlag ? "copying" : "renaming"), ": target \"",
- TclGetString(target), "\" is not a directory", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error %s: target \"%s\" is not a directory",
+ (copyFlag?"copying":"renaming"), TclGetString(target)));
result = TCL_ERROR;
} else {
/*
@@ -172,7 +172,6 @@ FileCopyRename(
for ( ; i<objc-1 ; i++) {
Tcl_Obj *jargv[2];
Tcl_Obj *source, *newFileName;
- Tcl_Obj *temp;
source = FileBasename(interp, objv[i]);
if (source == NULL) {
@@ -181,13 +180,11 @@ FileCopyRename(
}
jargv[0] = objv[objc - 1];
jargv[1] = source;
- temp = Tcl_NewListObj(2, jargv);
- newFileName = Tcl_FSJoinPath(temp, -1);
+ newFileName = TclJoinPath(2, jargv);
Tcl_IncrRefCount(newFileName);
result = CopyRenameOneFile(interp, objv[i], newFileName, copyFlag,
force);
Tcl_DecrRefCount(newFileName);
- Tcl_DecrRefCount(temp);
Tcl_DecrRefCount(source);
if (result == TCL_ERROR) {
@@ -302,8 +299,9 @@ TclFileMakeDirsCmd(
done:
if (errfile != NULL) {
- Tcl_AppendResult(interp, "can't create directory \"",
- TclGetString(errfile), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't create directory \"%s\": %s",
+ TclGetString(errfile), Tcl_PosixError(interp)));
result = TCL_ERROR;
}
if (split != NULL) {
@@ -382,9 +380,9 @@ TclFileDeleteCmd(
result = Tcl_FSRemoveDirectory(objv[i], force, &errorBuffer);
if (result != TCL_OK) {
if ((force == 0) && (errno == EEXIST)) {
- Tcl_AppendResult(interp, "error deleting \"",
- TclGetString(objv[i]), "\": directory not empty",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error deleting \"%s\": directory not empty",
+ TclGetString(objv[i])));
Tcl_PosixError(interp);
goto done;
}
@@ -424,12 +422,13 @@ TclFileDeleteCmd(
* We try to accomodate poor error results from our Tcl_FS calls.
*/
- Tcl_AppendResult(interp, "error deleting unknown file: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error deleting unknown file: %s",
+ Tcl_PosixError(interp)));
} else {
- Tcl_AppendResult(interp, "error deleting \"",
- TclGetString(errfile), "\": ", Tcl_PosixError(interp),
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error deleting \"%s\": %s",
+ TclGetString(errfile), Tcl_PosixError(interp)));
}
}
@@ -518,7 +517,7 @@ CopyRenameOneFile(
* 16 bits and we get collisions. See bug #2015723.
*/
-#ifndef WIN32
+#if !defined(_WIN32) && !defined(__CYGWIN__)
if ((sourceStatBuf.st_ino != 0) && (targetStatBuf.st_ino != 0)) {
if ((sourceStatBuf.st_ino == targetStatBuf.st_ino) &&
(sourceStatBuf.st_dev == targetStatBuf.st_dev)) {
@@ -538,17 +537,17 @@ CopyRenameOneFile(
if (S_ISDIR(sourceStatBuf.st_mode)
&& !S_ISDIR(targetStatBuf.st_mode)) {
errno = EISDIR;
- Tcl_AppendResult(interp, "can't overwrite file \"",
- TclGetString(target), "\" with directory \"",
- TclGetString(source), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't overwrite file \"%s\" with directory \"%s\"",
+ TclGetString(target), TclGetString(source)));
goto done;
}
if (!S_ISDIR(sourceStatBuf.st_mode)
&& S_ISDIR(targetStatBuf.st_mode)) {
errno = EISDIR;
- Tcl_AppendResult(interp, "can't overwrite directory \"",
- TclGetString(target), "\" with file \"",
- TclGetString(source), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't overwrite directory \"%s\" with file \"%s\"",
+ TclGetString(target), TclGetString(source)));
goto done;
}
@@ -579,10 +578,10 @@ CopyRenameOneFile(
}
if (errno == EINVAL) {
- Tcl_AppendResult(interp, "error renaming \"",
- TclGetString(source), "\" to \"", TclGetString(target),
- "\": trying to rename a volume or "
- "move a directory into itself", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error renaming \"%s\" to \"%s\": trying to rename a"
+ " volume or move a directory into itself",
+ TclGetString(source), TclGetString(target)));
goto done;
} else if (errno != EXDEV) {
errfile = target;
@@ -626,8 +625,9 @@ CopyRenameOneFile(
* Actual file doesn't exist.
*/
- Tcl_AppendResult(interp, "error copying \"", TclGetString(source),
- "\": the target of this link doesn't exist", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error copying \"%s\": the target of this link doesn't"
+ " exist", TclGetString(source)));
goto done;
} else {
int counter = 0;
@@ -734,17 +734,14 @@ CopyRenameOneFile(
*/
errfile = target;
-
- /*
- * We now need to reset the result, because the above call, if it
- * failed, may have put an error message in place. (Ideally we
- * would prefer not to pass an interpreter in above, but the
- * channel IO code used by TclCrossFilesystemCopy currently
- * requires one).
- */
-
- Tcl_ResetResult(interp);
}
+ /*
+ * We now need to reset the result, because the above call,
+ * may have left set it. (Ideally we would prefer not to pass
+ * an interpreter in above, but the channel IO code used by
+ * TclCrossFilesystemCopy currently requires one)
+ */
+ Tcl_ResetResult(interp);
}
if ((copyFlag == 0) && (result == TCL_OK)) {
if (S_ISDIR(sourceStatBuf.st_mode)) {
@@ -762,23 +759,27 @@ CopyRenameOneFile(
}
}
if (result != TCL_OK) {
- Tcl_AppendResult(interp, "can't unlink \"", TclGetString(errfile),
- "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("can't unlink \"%s\": %s",
+ TclGetString(errfile), Tcl_PosixError(interp)));
errfile = NULL;
}
}
done:
if (errfile != NULL) {
- Tcl_AppendResult(interp, "error ", (copyFlag ? "copying" : "renaming"),
- " \"", TclGetString(source), NULL);
+ Tcl_Obj *errorMsg = Tcl_ObjPrintf("error %s \"%s\"",
+ (copyFlag ? "copying" : "renaming"), TclGetString(source));
+
if (errfile != source) {
- Tcl_AppendResult(interp, "\" to \"", TclGetString(target), NULL);
+ Tcl_AppendPrintfToObj(errorMsg, " to \"%s\"",
+ TclGetString(target));
if (errfile != target) {
- Tcl_AppendResult(interp, "\": \"", TclGetString(errfile),NULL);
+ Tcl_AppendPrintfToObj(errorMsg, ": \"%s\"",
+ TclGetString(errfile));
}
}
- Tcl_AppendResult(interp, "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_AppendPrintfToObj(errorMsg, ": %s", Tcl_PosixError(interp));
+ Tcl_SetObjResult(interp, errorMsg);
}
if (errorBuffer != NULL) {
Tcl_DecrRefCount(errorBuffer);
@@ -981,9 +982,10 @@ TclFileAttrsCmd(
* There was an error, probably that the filePtr is not
* accepted by any filesystem
*/
- Tcl_AppendResult(interp, "could not read \"",
- TclGetString(filePtr), "\": ", Tcl_PosixError(interp),
- NULL);
+
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not read \"%s\": %s",
+ TclGetString(filePtr), Tcl_PosixError(interp)));
}
return TCL_ERROR;
}
@@ -1069,9 +1071,9 @@ TclFileAttrsCmd(
Tcl_Obj *objPtr = NULL;
if (numObjStrings == 0) {
- Tcl_AppendResult(interp, "bad option \"", TclGetString(objv[0]),
- "\", there are no file attributes in this filesystem.",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad option \"%s\", there are no file attributes in this"
+ " filesystem", TclGetString(objv[0])));
Tcl_SetErrorCode(interp, "TCL","OPERATION","FATTR","NONE", NULL);
goto end;
}
@@ -1096,9 +1098,9 @@ TclFileAttrsCmd(
int i, index;
if (numObjStrings == 0) {
- Tcl_AppendResult(interp, "bad option \"", TclGetString(objv[0]),
- "\", there are no file attributes in this filesystem.",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad option \"%s\", there are no file attributes in this"
+ " filesystem", TclGetString(objv[0])));
Tcl_SetErrorCode(interp, "TCL","OPERATION","FATTR","NONE", NULL);
goto end;
}
@@ -1112,8 +1114,8 @@ TclFileAttrsCmd(
TclFreeIntRep(objv[i]);
}
if (i + 1 == objc) {
- Tcl_AppendResult(interp, "value for \"",
- TclGetString(objv[i]), "\" missing", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "value for \"%s\" missing", TclGetString(objv[i])));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FATTR",
"NOVALUE", NULL);
goto end;
@@ -1222,9 +1224,9 @@ TclFileLinkCmd(
*/
if (errno == EEXIST) {
- Tcl_AppendResult(interp, "could not create new link \"",
- TclGetString(objv[index]),
- "\": that path already exists", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not create new link \"%s\": that path already"
+ " exists", TclGetString(objv[index])));
Tcl_PosixError(interp);
} else if (errno == ENOENT) {
/*
@@ -1242,23 +1244,23 @@ TclFileLinkCmd(
access = Tcl_FSAccess(dirPtr, F_OK);
Tcl_DecrRefCount(dirPtr);
if (access != 0) {
- Tcl_AppendResult(interp, "could not create new link \"",
- TclGetString(objv[index]),
- "\": no such file or directory", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not create new link \"%s\": no such file"
+ " or directory", TclGetString(objv[index])));
Tcl_PosixError(interp);
} else {
- Tcl_AppendResult(interp, "could not create new link \"",
- TclGetString(objv[index]), "\": target \"",
- TclGetString(objv[index+1]), "\" doesn't exist",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not create new link \"%s\": target \"%s\" "
+ "doesn't exist", TclGetString(objv[index]),
+ TclGetString(objv[index+1])));
errno = ENOENT;
Tcl_PosixError(interp);
}
} else {
- Tcl_AppendResult(interp, "could not create new link \"",
- TclGetString(objv[index]), "\" pointing to \"",
- TclGetString(objv[index+1]), "\": ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not create new link \"%s\" pointing to \"%s\": %s",
+ TclGetString(objv[index]),
+ TclGetString(objv[index+1]), Tcl_PosixError(interp)));
}
return TCL_ERROR;
}
@@ -1273,9 +1275,9 @@ TclFileLinkCmd(
contents = Tcl_FSLink(objv[index], NULL, 0);
if (contents == NULL) {
- Tcl_AppendResult(interp, "could not read link \"",
- TclGetString(objv[index]), "\": ", Tcl_PosixError(interp),
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not read link \"%s\": %s",
+ TclGetString(objv[index]), Tcl_PosixError(interp)));
return TCL_ERROR;
}
}
@@ -1330,8 +1332,9 @@ TclFileReadLinkCmd(
contents = Tcl_FSLink(objv[1], NULL, 0);
if (contents == NULL) {
- Tcl_AppendResult(interp, "could not readlink \"",
- TclGetString(objv[1]), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not read link \"%s\": %s",
+ TclGetString(objv[1]), Tcl_PosixError(interp)));
return TCL_ERROR;
}
Tcl_SetObjResult(interp, contents);
@@ -1485,8 +1488,8 @@ TclFileTemporaryCmd(
if (nameVarObj) {
TclDecrRefCount(nameObj);
}
- Tcl_AppendResult(interp, "can't create temporary file: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't create temporary file: %s", Tcl_PosixError(interp)));
return TCL_ERROR;
}
Tcl_RegisterChannel(interp, chan);
@@ -1497,7 +1500,7 @@ TclFileTemporaryCmd(
return TCL_ERROR;
}
}
- Tcl_AppendResult(interp, Tcl_GetChannelName(chan), NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1));
return TCL_OK;
}
diff --git a/generic/tclFileName.c b/generic/tclFileName.c
index 8ed6f96..5d4702b 100644
--- a/generic/tclFileName.c
+++ b/generic/tclFileName.c
@@ -72,9 +72,9 @@ SetResultLength(
{
Tcl_DStringSetLength(resultPtr, offset);
if (extended == 2) {
- Tcl_DStringAppend(resultPtr, "//?/UNC/", 8);
+ TclDStringAppendLiteral(resultPtr, "//?/UNC/");
} else if (extended == 1) {
- Tcl_DStringAppend(resultPtr, "//?/", 4);
+ TclDStringAppendLiteral(resultPtr, "//?/");
}
}
@@ -131,7 +131,7 @@ ExtractWinRoot(
if (path[1] != '/' && path[1] != '\\') {
SetResultLength(resultPtr, offset, extended);
*typePtr = TCL_PATH_VOLUME_RELATIVE;
- Tcl_DStringAppend(resultPtr, "/", 1);
+ TclDStringAppendLiteral(resultPtr, "/");
return &path[1];
}
host = &path[2];
@@ -161,7 +161,7 @@ ExtractWinRoot(
*/
*typePtr = TCL_PATH_VOLUME_RELATIVE;
- Tcl_DStringAppend(resultPtr, "/", 1);
+ TclDStringAppendLiteral(resultPtr, "/");
return &path[2];
}
SetResultLength(resultPtr, offset, extended);
@@ -180,9 +180,9 @@ ExtractWinRoot(
break;
}
}
- Tcl_DStringAppend(resultPtr, "//", 2);
+ TclDStringAppendLiteral(resultPtr, "//");
Tcl_DStringAppend(resultPtr, host, hlen);
- Tcl_DStringAppend(resultPtr, "/", 1);
+ TclDStringAppendLiteral(resultPtr, "/");
Tcl_DStringAppend(resultPtr, share, slen);
tail = &share[slen];
@@ -221,7 +221,7 @@ ExtractWinRoot(
*typePtr = TCL_PATH_ABSOLUTE;
Tcl_DStringAppend(resultPtr, path, 2);
- Tcl_DStringAppend(resultPtr, "/", 1);
+ TclDStringAppendLiteral(resultPtr, "/");
return tail;
}
@@ -411,25 +411,36 @@ TclpGetNativePathType(
* Paths that begin with / are absolute.
*/
-#ifdef __QNX__
- /*
- * Check for QNX //<node id> prefix
- */
- if (*path && (pathLen > 3) && (path[0] == '/')
- && (path[1] == '/') && isdigit(UCHAR(path[2]))) {
- path += 3;
- while (isdigit(UCHAR(*path))) {
- path++;
+ if (path[0] == '/') {
+ ++path;
+#if defined(__CYGWIN__) || defined(__QNX__)
+ /*
+ * Check for "//" network path prefix
+ */
+ if ((*path == '/') && path[1] && (path[1] != '/')) {
+ path += 2;
+ while (*path && *path != '/') {
+ ++path;
+ }
+#if defined(__CYGWIN__)
+ /* UNC paths need to be followed by a share name */
+ if (*path++ && (*path && *path != '/')) {
+ ++path;
+ while (*path && *path != '/') {
+ ++path;
+ }
+ } else {
+ path = origPath + 1;
+ }
+#endif
}
- }
#endif
- if (path[0] == '/') {
if (driveNameLengthPtr != NULL) {
/*
- * We need this addition in case the QNX code was used.
+ * We need this addition in case the QNX or Cygwin code was used.
*/
- *driveNameLengthPtr = (1 + path - origPath);
+ *driveNameLengthPtr = (path - origPath);
}
} else {
type = TCL_PATH_RELATIVE;
@@ -445,8 +456,7 @@ TclpGetNativePathType(
if ((rootEnd != path) && (driveNameLengthPtr != NULL)) {
*driveNameLengthPtr = rootEnd - path;
if (driveNameRef != NULL) {
- *driveNameRef = Tcl_NewStringObj(Tcl_DStringValue(&ds),
- Tcl_DStringLength(&ds));
+ *driveNameRef = TclDStringToObj(&ds);
Tcl_IncrRefCount(*driveNameRef);
}
}
@@ -633,32 +643,43 @@ SplitUnixPath(
const char *path) /* Pointer to string containing a path. */
{
int length;
- const char *p, *elementStart;
+ const char *origPath = path, *elementStart;
Tcl_Obj *result = Tcl_NewObj();
/*
* Deal with the root directory as a special case.
*/
-#ifdef __QNX__
- /*
- * Check for QNX //<node id> prefix
- */
-
- if ((path[0] == '/') && (path[1] == '/')
- && isdigit(UCHAR(path[2]))) { /* INTL: digit */
- path += 3;
- while (isdigit(UCHAR(*path))) { /* INTL: digit */
- path++;
+ if (*path == '/') {
+ Tcl_Obj *rootElt;
+ ++path;
+#if defined(__CYGWIN__) || defined(__QNX__)
+ /*
+ * Check for "//" network path prefix
+ */
+ if ((*path == '/') && path[1] && (path[1] != '/')) {
+ path += 2;
+ while (*path && *path != '/') {
+ ++path;
+ }
+#if defined(__CYGWIN__)
+ /* UNC paths need to be followed by a share name */
+ if (*path++ && (*path && *path != '/')) {
+ ++path;
+ while (*path && *path != '/') {
+ ++path;
+ }
+ } else {
+ path = origPath + 1;
+ }
+#endif
}
- }
#endif
-
- if (path[0] == '/') {
- Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj("/",1));
- p = path+1;
- } else {
- p = path;
+ rootElt = Tcl_NewStringObj(origPath, path - origPath);
+ Tcl_ListObjAppendElement(NULL, result, rootElt);
+ while (*path == '/') {
+ ++path;
+ }
}
/*
@@ -667,14 +688,14 @@ SplitUnixPath(
*/
for (;;) {
- elementStart = p;
- while ((*p != '\0') && (*p != '/')) {
- p++;
+ elementStart = path;
+ while ((*path != '\0') && (*path != '/')) {
+ path++;
}
- length = p - elementStart;
+ length = path - elementStart;
if (length > 0) {
Tcl_Obj *nextElt;
- if ((elementStart[0] == '~') && (elementStart != path)) {
+ if ((elementStart[0] == '~') && (elementStart != origPath)) {
TclNewLiteralStringObj(nextElt, "./");
Tcl_AppendToObj(nextElt, elementStart, length);
} else {
@@ -682,7 +703,7 @@ SplitUnixPath(
}
Tcl_ListObjAppendElement(NULL, result, nextElt);
}
- if (*p++ == '\0') {
+ if (*path++ == '\0') {
break;
}
}
@@ -724,8 +745,7 @@ SplitWinPath(
*/
if (p != path) {
- Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(
- Tcl_DStringValue(&buf), Tcl_DStringLength(&buf)));
+ Tcl_ListObjAppendElement(NULL, result, TclDStringToObj(&buf));
}
Tcl_DStringFree(&buf);
@@ -787,32 +807,28 @@ Tcl_FSJoinToPath(
int objc, /* Number of array elements to join */
Tcl_Obj *const objv[]) /* Path elements to join. */
{
- int i;
- Tcl_Obj *lobj, *ret;
-
if (pathPtr == NULL) {
- lobj = Tcl_NewListObj(0, NULL);
- } else {
- lobj = Tcl_NewListObj(1, &pathPtr);
+ return TclJoinPath(objc, objv);
}
-
- for (i = 0; i<objc;i++) {
- Tcl_ListObjAppendElement(NULL, lobj, objv[i]);
+ if (objc == 0) {
+ return TclJoinPath(1, &pathPtr);
}
- ret = Tcl_FSJoinPath(lobj, -1);
+ if (objc == 1) {
+ Tcl_Obj *pair[2];
- /*
- * It is possible that 'ret' is just a member of the list and is therefore
- * going to be freed here. Therefore we must adjust the refCount manually.
- * (It would be better if we changed the documentation of this function
- * and Tcl_FSJoinPath so that the returned object already has a refCount
- * for the caller, hence avoiding these subtleties (and code ugliness)).
- */
-
- Tcl_IncrRefCount(ret);
- Tcl_DecrRefCount(lobj);
- ret->refCount--;
- return ret;
+ pair[0] = pathPtr;
+ pair[1] = objv[0];
+ return TclJoinPath(2, pair);
+ } else {
+ int elemc = objc + 1;
+ Tcl_Obj *ret, **elemv = ckalloc(elemc*sizeof(Tcl_Obj **));
+
+ elemv[0] = pathPtr;
+ memcpy(elemv+1, objv, objc*sizeof(Tcl_Obj **));
+ ret = TclJoinPath(elemc, elemv);
+ ckfree(elemv);
+ return ret;
+ }
}
/*
@@ -869,7 +885,7 @@ TclpNativeJoinPath(
if (length > 0 && (start[length-1] != '/')) {
Tcl_AppendToObj(prefix, "/", 1);
- length++;
+ Tcl_GetStringFromObj(prefix, &length);
}
needsSep = 0;
@@ -905,7 +921,7 @@ TclpNativeJoinPath(
if ((length > 0) &&
(start[length-1] != '/') && (start[length-1] != ':')) {
Tcl_AppendToObj(prefix, "/", 1);
- length++;
+ Tcl_GetStringFromObj(prefix, &length);
}
needsSep = 0;
@@ -1046,7 +1062,7 @@ Tcl_TranslateFileName(
}
Tcl_DStringInit(bufferPtr);
- Tcl_DStringAppend(bufferPtr, Tcl_GetString(transPtr), -1);
+ TclDStringAppendObj(bufferPtr, transPtr);
Tcl_DecrRefCount(path);
Tcl_DecrRefCount(transPtr);
@@ -1163,9 +1179,10 @@ DoTildeSubst(
dir = TclGetEnv("HOME", &dirString);
if (dir == NULL) {
if (interp) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "couldn't find HOME environment "
- "variable to expand path", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "couldn't find HOME environment "
+ "variable to expand path", -1));
+ Tcl_SetErrorCode(interp, "TCL", "FILENAME", "NO_HOME", NULL);
}
return NULL;
}
@@ -1174,8 +1191,9 @@ DoTildeSubst(
} else if (TclpGetUserHome(user, resultPtr) == NULL) {
if (interp) {
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "user \"", user, "\" doesn't exist",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "user \"%s\" doesn't exist", user));
+ Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "USER", user, NULL);
}
return NULL;
}
@@ -1318,9 +1336,9 @@ Tcl_GlobObjCmd(
endOfForLoop:
if ((globFlags & TCL_GLOBMODE_TAILS) && (pathOrDir == NULL)) {
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"\"-tails\" must be used with either "
- "\"-directory\" or \"-path\"", NULL);
+ "\"-directory\" or \"-path\"", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB",
"BADOPTIONCOMBINATION", NULL);
return TCL_ERROR;
@@ -1402,7 +1420,7 @@ Tcl_GlobObjCmd(
search = Tcl_DStringValue(&pref);
while ((find = (strpbrk(search, "\\[]*?{}"))) != NULL) {
Tcl_DStringAppend(&prefix, search, find-search);
- Tcl_DStringAppend(&prefix, "\\", 1);
+ TclDStringAppendLiteral(&prefix, "\\");
Tcl_DStringAppend(&prefix, find, 1);
search = find+1;
if (*search == '\0') {
@@ -1564,8 +1582,7 @@ Tcl_GlobObjCmd(
Tcl_DStringInit(&prefix);
}
for (i = 0; i < objc; i++) {
- string = Tcl_GetStringFromObj(objv[i], &length);
- Tcl_DStringAppend(&prefix, string, length);
+ TclDStringAppendObj(&prefix, objv[i]);
if (i != objc -1) {
Tcl_DStringAppend(&prefix, separators, 1);
}
@@ -1581,11 +1598,9 @@ Tcl_GlobObjCmd(
for (i = 0; i < objc; i++) {
Tcl_DStringInit(&str);
if (dir == PATH_GENERAL) {
- Tcl_DStringAppend(&str, Tcl_DStringValue(&prefix),
- Tcl_DStringLength(&prefix));
+ TclDStringAppendDString(&str, &prefix);
}
- string = Tcl_GetStringFromObj(objv[i], &length);
- Tcl_DStringAppend(&str, string, length);
+ TclDStringAppendObj(&str, objv[i]);
if (TclGlob(interp, Tcl_DStringValue(&str), pathOrDir, globFlags,
globTypes) != TCL_OK) {
result = TCL_ERROR;
@@ -1617,20 +1632,23 @@ Tcl_GlobObjCmd(
}
if (length == 0) {
- Tcl_AppendResult(interp, "no files matched glob pattern",
- (join || (objc == 1)) ? " \"" : "s \"", NULL);
+ Tcl_Obj *errorMsg =
+ Tcl_ObjPrintf("no files matched glob pattern%s \"",
+ (join || (objc == 1)) ? "" : "s");
+
if (join) {
- Tcl_AppendResult(interp, Tcl_DStringValue(&prefix), NULL);
+ Tcl_AppendToObj(errorMsg, Tcl_DStringValue(&prefix), -1);
} else {
const char *sep = "";
for (i = 0; i < objc; i++) {
- string = Tcl_GetString(objv[i]);
- Tcl_AppendResult(interp, sep, string, NULL);
+ Tcl_AppendPrintfToObj(errorMsg, "%s%s",
+ sep, Tcl_GetString(objv[i]));
sep = " ";
}
}
- Tcl_AppendResult(interp, "\"", NULL);
+ Tcl_AppendToObj(errorMsg, "\"", -1);
+ Tcl_SetObjResult(interp, errorMsg);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "NOMATCH",
NULL);
result = TCL_ERROR;
@@ -1755,8 +1773,7 @@ TclGlob(
if (head != Tcl_DStringValue(&buffer)) {
Tcl_DStringAppend(&buffer, head, -1);
}
- pathPrefix = Tcl_NewStringObj(Tcl_DStringValue(&buffer),
- Tcl_DStringLength(&buffer));
+ pathPrefix = TclDStringToObj(&buffer);
Tcl_IncrRefCount(pathPrefix);
globFlags |= TCL_GLOBMODE_DIR;
if (c != '\0') {
@@ -2164,67 +2181,6 @@ DoGlob(
}
/*
- * This block of code is not exercised by the Tcl test suite as of Tcl
- * 8.5a0. Simplifications to the calling paths suggest it may not be
- * necessary any more, since path separators are handled elsewhere. It is
- * left in place in case new bugs are reported.
- */
-
-#if 0 /* PROBABLY_OBSOLETE */
- /*
- * Deal with path separators.
- */
-
- if (pathPtr == NULL) {
- /*
- * Length used to be the length of the prefix, and lastChar the
- * lastChar of the prefix. But, none of this is used any more.
- */
-
- int length = 0;
- char lastChar = 0;
-
- switch (tclPlatform) {
- case TCL_PLATFORM_WINDOWS:
- /*
- * If this is a drive relative path, add the colon and the
- * trailing slash if needed. Otherwise add the slash if this is
- * the first absolute element, or a later relative element. Add an
- * extra slash if this is a UNC path.
- */
-
- if (*name == ':') {
- Tcl_DStringAppend(&append, ":", 1);
- if (count > 1) {
- Tcl_DStringAppend(&append, "/", 1);
- }
- } else if ((*pattern != '\0') && (((length > 0)
- && (strchr(separators, lastChar) == NULL))
- || ((length == 0) && (count > 0)))) {
- Tcl_DStringAppend(&append, "/", 1);
- if ((length == 0) && (count > 1)) {
- Tcl_DStringAppend(&append, "/", 1);
- }
- }
-
- break;
- case TCL_PLATFORM_UNIX:
- /*
- * Add a separator if this is the first absolute element, or a
- * later relative element.
- */
-
- if ((*pattern != '\0') && (((length > 0)
- && (strchr(separators, lastChar) == NULL))
- || ((length == 0) && (count > 0)))) {
- Tcl_DStringAppend(&append, "/", 1);
- }
- break;
- }
- }
-#endif /* PROBABLY_OBSOLETE */
-
- /*
* Look for the first matching pair of braces or the first directory
* separator that is not inside a pair of braces.
*/
@@ -2261,15 +2217,15 @@ DoGlob(
closeBrace = p;
break;
}
- Tcl_SetResult(interp, "unmatched open-brace in file name",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "unmatched open-brace in file name", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "BALANCE",
NULL);
return TCL_ERROR;
} else if (*p == '}') {
- Tcl_SetResult(interp, "unmatched close-brace in file name",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "unmatched close-brace in file name", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "BALANCE",
NULL);
return TCL_ERROR;
@@ -2282,8 +2238,8 @@ DoGlob(
if (openBrace != NULL) {
char *element;
-
Tcl_DString newName;
+
Tcl_DStringInit(&newName);
/*
@@ -2332,12 +2288,13 @@ DoGlob(
*/
if (*p != '\0') {
+ char savedChar = *p;
+
/*
* Note that we are modifying the string in place. This won't work if
* the string is a static.
*/
- char savedChar = *p;
*p = '\0';
firstSpecialChar = strpbrk(pattern, "*[]?\\");
*p = savedChar;
@@ -2402,6 +2359,7 @@ DoGlob(
const char *bytes;
int numBytes;
Tcl_Obj *fixme, *newObj;
+
Tcl_ListObjIndex(NULL, matchesObj, repair, &fixme);
bytes = Tcl_GetStringFromObj(fixme, &numBytes);
newObj = Tcl_NewStringObj(bytes+2, numBytes-2);
@@ -2422,6 +2380,9 @@ DoGlob(
*/
if (*p == '\0') {
+ int length;
+ Tcl_DString append;
+
/*
* This is the code path reached by a command like 'glob foo'.
*
@@ -2434,9 +2395,6 @@ DoGlob(
* approach).
*/
- int length;
- Tcl_DString append;
-
Tcl_DStringInit(&append);
Tcl_DStringAppend(&append, pattern, p-pattern);
@@ -2451,41 +2409,22 @@ DoGlob(
if (length == 0 && (Tcl_DStringLength(&append) == 0)) {
if (((*name == '\\') && (name[1] == '/' ||
name[1] == '\\')) || (*name == '/')) {
- Tcl_DStringAppend(&append, "/", 1);
+ TclDStringAppendLiteral(&append, "/");
} else {
- Tcl_DStringAppend(&append, ".", 1);
+ TclDStringAppendLiteral(&append, ".");
}
}
-#if defined(__CYGWIN__) && defined(__WIN32__)
- {
- char winbuf[MAX_PATH+1];
-
- cygwin_conv_to_win32_path(Tcl_DStringValue(&append), winbuf);
- Tcl_DStringFree(&append);
- Tcl_DStringAppend(&append, winbuf, -1);
- }
-#endif /* __CYGWIN__ && __WIN32__ */
break;
case TCL_PLATFORM_UNIX:
if (length == 0 && (Tcl_DStringLength(&append) == 0)) {
if ((*name == '\\' && name[1] == '/') || (*name == '/')) {
- Tcl_DStringAppend(&append, "/", 1);
+ TclDStringAppendLiteral(&append, "/");
} else {
- Tcl_DStringAppend(&append, ".", 1);
+ TclDStringAppendLiteral(&append, ".");
}
}
-#if defined(__CYGWIN__) && !defined(__WIN32__)
- DLLIMPORT extern int cygwin_conv_to_posix_path(const char *, char *);
- {
- char winbuf[MAXPATHLEN+1];
-
- cygwin_conv_to_posix_path(Tcl_DStringValue(&append), winbuf);
- Tcl_DStringFree(&append);
- Tcl_DStringAppend(&append, winbuf, -1);
- }
-#endif /* __CYGWIN__ && __WIN32__ */
break;
}
@@ -2494,8 +2433,7 @@ DoGlob(
*/
if (pathPtr == NULL) {
- joinedPtr = Tcl_NewStringObj(Tcl_DStringValue(&append),
- Tcl_DStringLength(&append));
+ joinedPtr = TclDStringToObj(&append);
} else if (flags) {
joinedPtr = TclNewFSPathObj(pathPtr, Tcl_DStringValue(&append),
Tcl_DStringLength(&append));
diff --git a/generic/tclFileSystem.h b/generic/tclFileSystem.h
index 5e48dec..6be3e03 100644
--- a/generic/tclFileSystem.h
+++ b/generic/tclFileSystem.h
@@ -16,45 +16,6 @@
#include "tcl.h"
/*
- * struct FilesystemRecord --
- *
- * A filesystem record is used to keep track of each filesystem currently
- * registered with the core, in a linked list. Pointers to these structures
- * are also kept by each "path" Tcl_Obj, and we must retain a refCount on the
- * number of such references.
- */
-
-typedef struct FilesystemRecord {
- ClientData clientData; /* Client specific data for the new filesystem
- * (can be NULL) */
- const Tcl_Filesystem *fsPtr; /* Pointer to filesystem dispatch table. */
- int fileRefCount; /* How many Tcl_Obj's use this filesystem. */
- struct FilesystemRecord *nextPtr;
- /* The next filesystem registered to Tcl, or
- * NULL if no more. */
- struct FilesystemRecord *prevPtr;
- /* The previous filesystem registered to Tcl,
- * or NULL if no more. */
-} FilesystemRecord;
-
-/*
- * This structure holds per-thread private copy of the current directory
- * maintained by the global cwdPathPtr. This structure holds per-thread
- * private copies of some global data. This way we avoid most of the
- * synchronization calls which boosts performance, at cost of having to update
- * this information each time the corresponding epoch counter changes.
- */
-
-typedef struct ThreadSpecificData {
- int initialized;
- int cwdPathEpoch;
- int filesystemEpoch;
- Tcl_Obj *cwdPathPtr;
- ClientData cwdClientData;
- FilesystemRecord *filesystemList;
-} ThreadSpecificData;
-
-/*
* The internal TclFS API provides routines for handling and manipulating
* paths efficiently, taking direct advantage of the "path" Tcl_Obj type.
*
@@ -62,31 +23,23 @@ typedef struct ThreadSpecificData {
*/
MODULE_SCOPE int TclFSCwdPointerEquals(Tcl_Obj **pathPtrPtr);
-MODULE_SCOPE int TclFSMakePathFromNormalized(Tcl_Interp *interp,
- Tcl_Obj *pathPtr, ClientData clientData);
MODULE_SCOPE int TclFSNormalizeToUniquePath(Tcl_Interp *interp,
- Tcl_Obj *pathPtr, int startAt,
- ClientData *clientDataPtr);
+ Tcl_Obj *pathPtr, int startAt);
MODULE_SCOPE Tcl_Obj * TclFSMakePathRelative(Tcl_Interp *interp,
Tcl_Obj *pathPtr, Tcl_Obj *cwdPtr);
-MODULE_SCOPE Tcl_Obj * TclFSInternalToNormalized(
- const Tcl_Filesystem *fromFilesystem,
- ClientData clientData,
- FilesystemRecord **fsRecPtrPtr);
MODULE_SCOPE int TclFSEnsureEpochOk(Tcl_Obj *pathPtr,
const Tcl_Filesystem **fsPtrPtr);
MODULE_SCOPE void TclFSSetPathDetails(Tcl_Obj *pathPtr,
- FilesystemRecord *fsRecPtr,
- ClientData clientData);
+ const Tcl_Filesystem *fsPtr, ClientData clientData);
MODULE_SCOPE Tcl_Obj * TclFSNormalizeAbsolutePath(Tcl_Interp *interp,
- Tcl_Obj *pathPtr, ClientData *clientDataPtr);
+ Tcl_Obj *pathPtr);
+MODULE_SCOPE int TclFSEpoch(void);
/*
* Private shared variables for use by tclIOUtil.c and tclPathObj.c
*/
MODULE_SCOPE const Tcl_Filesystem tclNativeFilesystem;
-MODULE_SCOPE Tcl_ThreadDataKey tclFsDataKey;
/*
* Private shared functions for use by tclIOUtil.c, tclPathObj.c and
diff --git a/generic/tclGet.c b/generic/tclGet.c
index b6089d3..97e8c7b 100644
--- a/generic/tclGet.c
+++ b/generic/tclGet.c
@@ -53,6 +53,7 @@ Tcl_GetInt(
if (obj.refCount > 1) {
Tcl_Panic("invalid sharing of Tcl_Obj on C stack");
}
+ TclFreeIntRep(&obj);
return code;
}
@@ -96,6 +97,7 @@ Tcl_GetDouble(
if (obj.refCount > 1) {
Tcl_Panic("invalid sharing of Tcl_Obj on C stack");
}
+ TclFreeIntRep(&obj);
return code;
}
@@ -135,7 +137,7 @@ Tcl_GetBoolean(
obj.length = strlen(src);
obj.typePtr = NULL;
- code = Tcl_ConvertToType(interp, &obj, &tclBooleanType);
+ code = TclSetBooleanFromAny(interp, &obj);
if (obj.refCount > 1) {
Tcl_Panic("invalid sharing of Tcl_Obj on C stack");
}
diff --git a/generic/tclHash.c b/generic/tclHash.c
index c8dc939..90be511 100644
--- a/generic/tclHash.c
+++ b/generic/tclHash.c
@@ -46,7 +46,9 @@ static int CompareArrayKeys(void *keyPtr, Tcl_HashEntry *hPtr);
static unsigned int HashArrayKey(Tcl_HashTable *tablePtr, void *keyPtr);
/*
- * Prototypes for the one word hash key methods.
+ * Prototypes for the one word hash key methods. Not actually declared because
+ * this is a critical path that is implemented in the core hash table access
+ * function.
*/
#if 0
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 78c1dc0..58c7b3c 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -16,6 +16,108 @@
#include <assert.h>
/*
+ * For each channel handler registered in a call to Tcl_CreateChannelHandler,
+ * there is one record of the following type. All of records for a specific
+ * channel are chained together in a singly linked list which is stored in
+ * the channel structure.
+ */
+
+typedef struct ChannelHandler {
+ Channel *chanPtr; /* The channel structure for this channel. */
+ int mask; /* Mask of desired events. */
+ Tcl_ChannelProc *proc; /* Procedure to call in the type of
+ * Tcl_CreateChannelHandler. */
+ ClientData clientData; /* Argument to pass to procedure. */
+ struct ChannelHandler *nextPtr;
+ /* Next one in list of registered handlers. */
+} ChannelHandler;
+
+/*
+ * This structure keeps track of the current ChannelHandler being invoked in
+ * the current invocation of ChannelHandlerEventProc. There is a potential
+ * problem if a ChannelHandler is deleted while it is the current one, since
+ * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this
+ * problem, structures of the type below indicate the next handler to be
+ * processed for any (recursively nested) dispatches in progress. The
+ * nextHandlerPtr field is updated if the handler being pointed to is deleted.
+ * The nextPtr field is used to chain together all recursive invocations, so
+ * that Tcl_DeleteChannelHandler can find all the recursively nested
+ * invocations of ChannelHandlerEventProc and compare the handler being
+ * deleted against the NEXT handler to be invoked in that invocation; when it
+ * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr
+ * field of the structure to the next handler.
+ */
+
+typedef struct NextChannelHandler {
+ ChannelHandler *nextHandlerPtr; /* The next handler to be invoked in
+ * this invocation. */
+ struct NextChannelHandler *nestedHandlerPtr;
+ /* Next nested invocation of
+ * ChannelHandlerEventProc. */
+} NextChannelHandler;
+
+/*
+ * The following structure describes the event that is added to the Tcl
+ * event queue by the channel handler check procedure.
+ */
+
+typedef struct ChannelHandlerEvent {
+ Tcl_Event header; /* Standard header for all events. */
+ Channel *chanPtr; /* The channel that is ready. */
+ int readyMask; /* Events that have occurred. */
+} ChannelHandlerEvent;
+
+/*
+ * The following structure is used by Tcl_GetsObj() to encapsulates the
+ * state for a "gets" operation.
+ */
+
+typedef struct GetsState {
+ Tcl_Obj *objPtr; /* The object to which UTF-8 characters
+ * will be appended. */
+ char **dstPtr; /* Pointer into objPtr's string rep where
+ * next character should be stored. */
+ Tcl_Encoding encoding; /* The encoding to use to convert raw bytes
+ * to UTF-8. */
+ ChannelBuffer *bufPtr; /* The current buffer of raw bytes being
+ * emptied. */
+ Tcl_EncodingState state; /* The encoding state just before the last
+ * external to UTF-8 conversion in
+ * FilterInputBytes(). */
+ int rawRead; /* The number of bytes removed from bufPtr
+ * in the last call to FilterInputBytes(). */
+ int bytesWrote; /* The number of bytes of UTF-8 data
+ * appended to objPtr during the last call to
+ * FilterInputBytes(). */
+ int charsWrote; /* The corresponding number of UTF-8
+ * characters appended to objPtr during the
+ * last call to FilterInputBytes(). */
+ int totalChars; /* The total number of UTF-8 characters
+ * appended to objPtr so far, just before the
+ * last call to FilterInputBytes(). */
+} GetsState;
+
+/*
+ * The following structure encapsulates the state for a background channel
+ * copy. Note that the data buffer for the copy will be appended to this
+ * structure.
+ */
+
+typedef struct CopyState {
+ struct Channel *readPtr; /* Pointer to input channel. */
+ struct Channel *writePtr; /* Pointer to output channel. */
+ int readFlags; /* Original read channel flags. */
+ int writeFlags; /* Original write channel flags. */
+ Tcl_WideInt toRead; /* Number of bytes to copy, or -1. */
+ Tcl_WideInt total; /* Total bytes transferred (written). */
+ Tcl_Interp *interp; /* Interp that started the copy. */
+ Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */
+ int bufSize; /* Size of appended buffer. */
+ char buffer[1]; /* Copy buffer, this must be the last
+ * field. */
+} CopyState;
+
+/*
* All static variables used in this file are collected into a single instance
* of the following structure. For multi-threaded implementations, there is
* one instance of this structure for each thread.
@@ -44,15 +146,28 @@ typedef struct ThreadSpecificData {
static Tcl_ThreadDataKey dataKey;
/*
+ * Structure to record a close callback. One such record exists for
+ * each close callback registered for a channel.
+ */
+
+typedef struct CloseCallback {
+ Tcl_CloseProc *proc; /* The procedure to call. */
+ ClientData clientData; /* Arbitrary one-word data to pass
+ * to the callback. */
+ struct CloseCallback *nextPtr; /* For chaining close callbacks. */
+} CloseCallback;
+
+/*
* Static functions in this file:
*/
static ChannelBuffer * AllocChannelBuffer(int length);
+static void PreserveChannelBuffer(ChannelBuffer *bufPtr);
+static void ReleaseChannelBuffer(ChannelBuffer *bufPtr);
+static int IsShared(ChannelBuffer *bufPtr);
static void ChannelTimerProc(ClientData clientData);
static int CheckChannelErrors(ChannelState *statePtr,
int direction);
-static int CheckFlush(Channel *chanPtr, ChannelBuffer *bufPtr,
- int newlineFlag);
static int CheckForDeadChannel(Tcl_Interp *interp,
ChannelState *statePtr);
static void CheckForStdChannelsBeingClosed(Tcl_Channel chan);
@@ -79,16 +194,15 @@ static int DetachChannel(Tcl_Interp *interp, Tcl_Channel chan);
static void DiscardInputQueued(ChannelState *statePtr,
int discardSavedBuffers);
static void DiscardOutputQueued(ChannelState *chanPtr);
-static int DoRead(Channel *chanPtr, char *srcPtr, int slen);
-static int DoWrite(Channel *chanPtr, const char *src, int srcLen);
+static int DoRead(Channel *chanPtr, char *srcPtr, int slen, int allowShortReads);
static int DoReadChars(Channel *chan, Tcl_Obj *objPtr, int toRead,
int appendFlag);
-static int DoWriteChars(Channel *chan, const char *src, int len);
static int FilterInputBytes(Channel *chanPtr,
GetsState *statePtr);
static int FlushChannel(Tcl_Interp *interp, Channel *chanPtr,
int calledFromAsyncFlush);
static int TclGetsObjBinary(Tcl_Channel chan, Tcl_Obj *objPtr);
+static Tcl_Encoding GetBinaryEncoding();
static void FreeBinaryEncoding(ClientData clientData);
static Tcl_HashTable * GetChannelTable(Tcl_Interp *interp);
static int GetInput(Channel *chanPtr);
@@ -108,18 +222,19 @@ static int SetBlockMode(Tcl_Interp *interp, Channel *chanPtr,
static void StopCopy(CopyState *csPtr);
static int TranslateInputEOL(ChannelState *statePtr, char *dst,
const char *src, int *dstLenPtr, int *srcLenPtr);
-static int TranslateOutputEOL(ChannelState *statePtr, char *dst,
- const char *src, int *dstLenPtr, int *srcLenPtr);
static void UpdateInterest(Channel *chanPtr);
-static int WriteBytes(Channel *chanPtr, const char *src,
- int srcLen);
-static int WriteChars(Channel *chanPtr, const char *src,
- int srcLen);
+static int Write(Channel *chanPtr, const char *src,
+ int srcLen, Tcl_Encoding encoding);
static Tcl_Obj * FixLevelCode(Tcl_Obj *msg);
static void SpliceChannel(Tcl_Channel chan);
static void CutChannel(Tcl_Channel chan);
static int WillRead(Channel *chanPtr);
+#define WriteChars(chanPtr, src, srcLen) \
+ Write(chanPtr, src, srcLen, chanPtr->state->encoding)
+#define WriteBytes(chanPtr, src, srcLen) \
+ Write(chanPtr, src, srcLen, tclIdentityEncoding)
+
/*
* Simplifying helper macros. All may use their argument(s) multiple times.
* The ANSI C "prototypes" for the macros are listed below, together with a
@@ -209,23 +324,22 @@ static int WillRead(Channel *chanPtr);
static void DupChannelIntRep(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
static int SetChannelFromAny(Tcl_Interp *interp,
Tcl_Obj *objPtr);
-static void UpdateStringOfChannel(Tcl_Obj *objPtr);
static void FreeChannelIntRep(Tcl_Obj *objPtr);
-static const Tcl_ObjType tclChannelType = {
+static const Tcl_ObjType chanObjType = {
"channel", /* name for this type */
FreeChannelIntRep, /* freeIntRepProc */
DupChannelIntRep, /* dupIntRepProc */
- NULL, /* updateStringProc UpdateStringOfChannel */
+ NULL, /* updateStringProc */
NULL /* setFromAnyProc SetChannelFromAny */
};
#define GET_CHANNELSTATE(objPtr) \
- ((ChannelState *) (objPtr)->internalRep.otherValuePtr)
+ ((ChannelState *) (objPtr)->internalRep.twoPtrValue.ptr1)
#define SET_CHANNELSTATE(objPtr, storePtr) \
- ((objPtr)->internalRep.otherValuePtr = (void *) (storePtr))
+ ((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (storePtr))
#define GET_CHANNELINTERP(objPtr) \
- ((Interp *) (objPtr)->internalRep.twoPtrValue.ptr2)
+ ((Tcl_Interp *) (objPtr)->internalRep.twoPtrValue.ptr2)
#define SET_CHANNELINTERP(objPtr, storePtr) \
((objPtr)->internalRep.twoPtrValue.ptr2 = (void *) (storePtr))
@@ -276,6 +390,7 @@ ChanRead(
int *errnoPtr)
{
if (WillRead(chanPtr) < 0) {
+ *errnoPtr = Tcl_GetErrno();
return -1;
}
@@ -396,6 +511,19 @@ TclFinalizeIOSubsystem(void)
Channel *chanPtr = NULL; /* Iterates over open channels. */
ChannelState *statePtr; /* State of channel stack */
int active = 1; /* Flag == 1 while there's still work to do */
+ int doflushnb;
+
+ /* Fetch the pre-TIP#398 compatibility flag */
+ {
+ const char *s;
+ Tcl_DString ds;
+
+ s = TclGetEnv("TCL_FLUSH_NONBLOCKING_ON_EXIT", &ds);
+ doflushnb = ((s != NULL) && strcmp(s, "0"));
+ if (s != NULL) {
+ Tcl_DStringFree(&ds);
+ }
+ }
/*
* Walk all channel state structures known to this thread and close
@@ -414,25 +542,37 @@ TclFinalizeIOSubsystem(void)
statePtr != NULL;
statePtr = statePtr->nextCSPtr) {
chanPtr = statePtr->topChanPtr;
- if (!GotFlag(statePtr, CHANNEL_INCLOSE | CHANNEL_CLOSED |
- CHANNEL_DEAD)) {
+ if (GotFlag(statePtr, CHANNEL_DEAD)) {
+ continue;
+ }
+ if (!GotFlag(statePtr, CHANNEL_INCLOSE | CHANNEL_CLOSED )
+ || GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
+ ResetFlag(statePtr, BG_FLUSH_SCHEDULED);
active = 1;
break;
}
}
/*
- * We've found a live channel. Close it.
+ * We've found a live (or bg-closing) channel. Close it.
*/
if (active) {
+
/*
- * Set the channel back into blocking mode to ensure that we wait
- * for all data to flush out.
+ * TIP #398: by default, we no longer set the channel back into
+ * blocking mode. To restore the old blocking behavior, the
+ * environment variable TCL_FLUSH_NONBLOCKING_ON_EXIT must be set
+ * and not be "0".
*/
-
- (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) chanPtr,
- "-blocking", "on");
+ if (doflushnb) {
+ /* Set the channel back into blocking mode to ensure that we wait
+ * for all data to flush out.
+ */
+
+ (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) chanPtr,
+ "-blocking", "on");
+ }
if ((chanPtr == (Channel *) tsdPtr->stdinChannel) ||
(chanPtr == (Channel *) tsdPtr->stdoutChannel) ||
@@ -670,6 +810,8 @@ Tcl_DeleteCloseHandler(
if ((cbPtr->proc == proc) && (cbPtr->clientData == clientData)) {
if (cbPrevPtr == NULL) {
statePtr->closeCbPtr = cbPtr->nextPtr;
+ } else {
+ cbPrevPtr->nextPtr = cbPtr->nextPtr;
}
ckfree(cbPtr);
break;
@@ -854,19 +996,25 @@ CheckForStdChannelsBeingClosed(
ChannelState *statePtr = ((Channel *) chan)->state;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- if ((chan == tsdPtr->stdinChannel) && tsdPtr->stdinInitialized) {
+ if (tsdPtr->stdinInitialized
+ && tsdPtr->stdinChannel != NULL
+ && statePtr == ((Channel *)tsdPtr->stdinChannel)->state) {
if (statePtr->refCount < 2) {
statePtr->refCount = 0;
tsdPtr->stdinChannel = NULL;
return;
}
- } else if ((chan == tsdPtr->stdoutChannel) && tsdPtr->stdoutInitialized) {
+ } else if (tsdPtr->stdoutInitialized
+ && tsdPtr->stdoutChannel != NULL
+ && statePtr == ((Channel *)tsdPtr->stdoutChannel)->state) {
if (statePtr->refCount < 2) {
statePtr->refCount = 0;
tsdPtr->stdoutChannel = NULL;
return;
}
- } else if ((chan == tsdPtr->stderrChannel) && tsdPtr->stderrInitialized) {
+ } else if (tsdPtr->stderrInitialized
+ && tsdPtr->stderrChannel != NULL
+ && statePtr == ((Channel *)tsdPtr->stderrChannel)->state) {
if (statePtr->refCount < 2) {
statePtr->refCount = 0;
tsdPtr->stderrChannel = NULL;
@@ -1002,8 +1150,9 @@ Tcl_UnregisterChannel(
if (GotFlag(statePtr, CHANNEL_INCLOSE)) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "Illegal recursive call to close "
- "through close-handler of channel", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "illegal recursive call to close through close-handler"
+ " of channel", -1));
}
return TCL_ERROR;
}
@@ -1238,8 +1387,8 @@ Tcl_GetChannel(
hTblPtr = GetChannelTable(interp);
hPtr = Tcl_FindHashEntry(hTblPtr, name);
if (hPtr == NULL) {
- Tcl_AppendResult(interp, "can not find channel named \"", chanName,
- "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can not find channel named \"%s\"", chanName));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CHANNEL", chanName, NULL);
return NULL;
}
@@ -1433,11 +1582,7 @@ Tcl_CreateChannel(
statePtr->timer = NULL;
statePtr->csPtrR = NULL;
statePtr->csPtrW = NULL;
-
statePtr->outputStage = NULL;
- if ((statePtr->encoding != NULL) && GotFlag(statePtr, TCL_WRITABLE)) {
- statePtr->outputStage = ckalloc(statePtr->bufSize + 2);
- }
/*
* As we are creating the channel, it is obviously the top for now.
@@ -1559,8 +1704,9 @@ Tcl_StackChannel(
if (statePtr == NULL) {
if (interp) {
- Tcl_AppendResult(interp, "couldn't find state for channel \"",
- Tcl_GetChannelName(prevChan), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't find state for channel \"%s\"",
+ Tcl_GetChannelName(prevChan)));
}
return NULL;
}
@@ -1580,9 +1726,9 @@ Tcl_StackChannel(
if ((mask & (statePtr->flags & (TCL_READABLE | TCL_WRITABLE))) == 0) {
if (interp) {
- Tcl_AppendResult(interp,
- "reading and writing both disallowed for channel \"",
- Tcl_GetChannelName(prevChan), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "reading and writing both disallowed for channel \"%s\"",
+ Tcl_GetChannelName(prevChan)));
}
return NULL;
}
@@ -1601,12 +1747,17 @@ Tcl_StackChannel(
statePtr->csPtrR = NULL;
statePtr->csPtrW = NULL;
+ /*
+ * TODO: Examine what can go wrong if Tcl_Flush() call disturbs
+ * the stacking state of this channel during its operations.
+ */
if (Tcl_Flush((Tcl_Channel) prevChanPtr) != TCL_OK) {
statePtr->csPtrR = csPtrR;
statePtr->csPtrW = csPtrW;
if (interp) {
- Tcl_AppendResult(interp, "could not flush channel \"",
- Tcl_GetChannelName(prevChan), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not flush channel \"%s\"",
+ Tcl_GetChannelName(prevChan)));
}
return NULL;
}
@@ -1729,6 +1880,13 @@ Tcl_UnstackChannel(
* into the old structure.
*/
+ /*
+ * TODO: Figure out how to handle the situation where the chan
+ * operations called below by this unstacking operation cause
+ * another unstacking recursively. In that case the downChanPtr
+ * value we're holding on to will not be the right thing.
+ */
+
Channel *downChanPtr = chanPtr->downChanPtr;
/*
@@ -1759,9 +1917,9 @@ Tcl_UnstackChannel(
*/
if (!TclChanCaughtErrorBypass(interp, chan) && interp) {
- Tcl_AppendResult(interp, "could not flush channel \"",
- Tcl_GetChannelName((Tcl_Channel) chanPtr), "\"",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not flush channel \"%s\"",
+ Tcl_GetChannelName((Tcl_Channel) chanPtr)));
}
return TCL_ERROR;
}
@@ -1833,7 +1991,7 @@ Tcl_UnstackChannel(
*/
Tcl_EventuallyFree(chanPtr, TCL_DYNAMIC);
- UpdateInterest(downChanPtr);
+ UpdateInterest(statePtr->topChanPtr);
if (result != 0) {
Tcl_SetErrno(result);
@@ -2145,8 +2303,33 @@ AllocChannelBuffer(
bufPtr->nextRemoved = BUFFER_PADDING;
bufPtr->bufLength = length + BUFFER_PADDING;
bufPtr->nextPtr = NULL;
+ bufPtr->refCount = 1;
return bufPtr;
}
+
+static void
+PreserveChannelBuffer(
+ ChannelBuffer *bufPtr)
+{
+ bufPtr->refCount++;
+}
+
+static void
+ReleaseChannelBuffer(
+ ChannelBuffer *bufPtr)
+{
+ if (--bufPtr->refCount) {
+ return;
+ }
+ ckfree(bufPtr);
+}
+
+static int
+IsShared(
+ ChannelBuffer *bufPtr)
+{
+ return bufPtr->refCount > 1;
+}
/*
*----------------------------------------------------------------------
@@ -2177,9 +2360,12 @@ RecycleBuffer(
/*
* Do we have to free the buffer to the OS?
*/
+ if (IsShared(bufPtr)) {
+ mustDiscard = 1;
+ }
if (mustDiscard) {
- ckfree(bufPtr);
+ ReleaseChannelBuffer(bufPtr);
return;
}
@@ -2190,7 +2376,7 @@ RecycleBuffer(
*/
if ((bufPtr->bufLength - BUFFER_PADDING) < statePtr->bufSize) {
- ckfree(bufPtr);
+ ReleaseChannelBuffer(bufPtr);
return;
}
@@ -2225,7 +2411,7 @@ RecycleBuffer(
* If we reached this code we return the buffer to the OS.
*/
- ckfree(bufPtr);
+ ReleaseChannelBuffer(bufPtr);
return;
keepBuffer:
@@ -2293,8 +2479,8 @@ CheckForDeadChannel(
Tcl_SetErrno(EINVAL);
if (interp) {
- Tcl_AppendResult(interp, "unable to access channel: invalid channel",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "unable to access channel: invalid channel", -1));
}
return 1;
}
@@ -2355,6 +2541,7 @@ FlushChannel(
* of the queued output to the channel.
*/
+ Tcl_Preserve(chanPtr);
while (1) {
/*
* If the queue is empty and there is a ready current buffer, OR if
@@ -2384,7 +2571,8 @@ FlushChannel(
*/
if (!calledFromAsyncFlush && GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
- return 0;
+ errorCode = 0;
+ goto done;
}
/*
@@ -2399,6 +2587,7 @@ FlushChannel(
* Produce the output on the channel.
*/
+ PreserveChannelBuffer(bufPtr);
toWrite = BytesLeft(bufPtr);
if (toWrite == 0) {
written = 0;
@@ -2436,7 +2625,7 @@ FlushChannel(
* it's a tty channel (dup'ed underneath)
*/
- if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
+ if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED) && !TclInExit()) {
SetFlag(statePtr, BG_FLUSH_SCHEDULED);
UpdateInterest(chanPtr);
}
@@ -2507,7 +2696,9 @@ FlushChannel(
wroteSome = 1;
}
- bufPtr->nextRemoved += written;
+ if (!IsBufferEmpty(bufPtr)) {
+ bufPtr->nextRemoved += written;
+ }
/*
* If this buffer is now empty, recycle it.
@@ -2520,6 +2711,7 @@ FlushChannel(
}
RecycleBuffer(statePtr, bufPtr, 0);
}
+ ReleaseChannelBuffer(bufPtr);
} /* Closes "while (1)". */
/*
@@ -2531,7 +2723,7 @@ FlushChannel(
if (GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
if (wroteSome) {
- return errorCode;
+ goto done;
} else if (statePtr->outQueueHead == NULL) {
ResetFlag(statePtr, BG_FLUSH_SCHEDULED);
ChanWatch(chanPtr, statePtr->interestMask);
@@ -2548,7 +2740,8 @@ FlushChannel(
(statePtr->outQueueHead == NULL) &&
((statePtr->curOutPtr == NULL) ||
IsBufferEmpty(statePtr->curOutPtr))) {
- return CloseChannel(interp, chanPtr, errorCode);
+ errorCode = CloseChannel(interp, chanPtr, errorCode);
+ goto done;
}
/*
@@ -2561,8 +2754,12 @@ FlushChannel(
(statePtr->outQueueHead == NULL) &&
((statePtr->curOutPtr == NULL) ||
IsBufferEmpty(statePtr->curOutPtr))) {
- return CloseChannelPart(interp, chanPtr, errorCode, TCL_CLOSE_WRITE);
+ errorCode = CloseChannelPart(interp, chanPtr, errorCode, TCL_CLOSE_WRITE);
+ goto done;
}
+
+ done:
+ Tcl_Release(chanPtr);
return errorCode;
}
@@ -2616,7 +2813,7 @@ CloseChannel(
*/
if (statePtr->curOutPtr != NULL) {
- ckfree(statePtr->curOutPtr);
+ ReleaseChannelBuffer(statePtr->curOutPtr);
statePtr->curOutPtr = NULL;
}
@@ -2679,10 +2876,6 @@ CloseChannel(
}
Tcl_FreeEncoding(statePtr->encoding);
- if (statePtr->outputStage != NULL) {
- ckfree(statePtr->outputStage);
- statePtr->outputStage = NULL;
- }
}
/*
@@ -3017,8 +3210,9 @@ Tcl_Close(
if (GotFlag(statePtr, CHANNEL_INCLOSE)) {
if (interp) {
- Tcl_AppendResult(interp, "Illegal recursive call to close "
- "through close-handler of channel", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "illegal recursive call to close through close-handler"
+ " of channel", -1));
}
return TCL_ERROR;
}
@@ -3031,7 +3225,8 @@ Tcl_Close(
stickyError = 0;
- if ((statePtr->encoding != NULL) && (statePtr->curOutPtr != NULL)
+ if ((statePtr->encoding != NULL)
+ && !(statePtr->outputEncodingFlags & TCL_ENCODING_START)
&& (CheckChannelErrors(statePtr, TCL_WRITABLE) == 0)) {
statePtr->outputEncodingFlags |= TCL_ENCODING_END;
if (WriteChars(chanPtr, "", 0) < 0) {
@@ -3121,7 +3316,17 @@ Tcl_Close(
Tcl_SetObjResult(interp,
Tcl_NewStringObj(Tcl_PosixError(interp), -1));
}
- flushcode = -1;
+ return TCL_ERROR;
+ }
+ /*
+ * Bug 97069ea11a: set error message if a flush code is set and no error
+ * message set up to now.
+ */
+ if (flushcode != 0 && interp != NULL
+ && 0 == Tcl_GetCharLength(Tcl_GetObjResult(interp)) ) {
+ Tcl_SetErrno(flushcode);
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj(Tcl_PosixError(interp), -1));
}
if ((flushcode != 0) || (result != 0)) {
return TCL_ERROR;
@@ -3176,8 +3381,9 @@ Tcl_CloseEx(
*/
if (!chanPtr->typePtr->close2Proc) {
- Tcl_AppendResult(interp, "Half-close of channels not supported by ",
- chanPtr->typePtr->typeName, "s", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "half-close of channels not supported by %ss",
+ chanPtr->typePtr->typeName));
return TCL_ERROR;
}
@@ -3186,9 +3392,8 @@ Tcl_CloseEx(
*/
if (chanPtr != statePtr->topChanPtr) {
- Tcl_AppendResult(interp,
- "Half-close not applicable to stack of transformations",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "half-close not applicable to stack of transformations", -1));
return TCL_ERROR;
}
@@ -3206,9 +3411,9 @@ Tcl_CloseEx(
} else {
msg = "write";
}
- Tcl_AppendResult(interp, "Half-close of ", msg,
- "-side not possible, side not opened or already closed",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "Half-close of %s-side not possible, side not opened or"
+ " already closed", msg));
return TCL_ERROR;
}
@@ -3219,8 +3424,9 @@ Tcl_CloseEx(
if (statePtr->flags & CHANNEL_INCLOSE) {
if (interp) {
- Tcl_AppendResult(interp, "Illegal recursive call to close "
- "through close-handler of channel", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "illegal recursive call to close through close-handler"
+ " of channel", -1));
}
return TCL_ERROR;
}
@@ -3617,7 +3823,7 @@ Tcl_Write(
if (srcLen < 0) {
srcLen = strlen(src);
}
- return DoWrite(chanPtr, src, srcLen);
+ return WriteBytes(chanPtr, src, srcLen);
}
/*
@@ -3708,82 +3914,40 @@ Tcl_WriteChars(
int len) /* Length of string in bytes, or < 0 for
* strlen(). */
{
- ChannelState *statePtr; /* State info for channel */
-
- statePtr = ((Channel *) chan)->state;
+ Channel *chanPtr = (Channel *) chan;
+ ChannelState *statePtr = chanPtr->state; /* State info for channel */
+ int result;
+ Tcl_Obj *objPtr;
if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) {
return -1;
}
- return DoWriteChars((Channel *) chan, src, len);
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * DoWriteChars --
- *
- * Takes a sequence of UTF-8 characters and converts them for output
- * using the channel's current encoding, may queue the buffer for output
- * if it gets full, and also remembers whether the current buffer is
- * ready e.g. if it contains a newline and we are in line buffering mode.
- * Compensates stacking, i.e. will redirect the data from the specified
- * channel to the topmost channel in a stack.
- *
- * Results:
- * The number of bytes written or -1 in case of error. If -1,
- * Tcl_GetErrno will return the error code.
- *
- * Side effects:
- * May buffer up output and may cause output to be produced on the
- * channel.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-DoWriteChars(
- Channel *chanPtr, /* The channel to buffer output for. */
- const char *src, /* UTF-8 characters to queue in output
- * buffer. */
- int len) /* Length of string in bytes, or < 0 for
- * strlen(). */
-{
- /*
- * Always use the topmost channel of the stack
- */
-
- ChannelState *statePtr; /* State info for channel */
-
- statePtr = chanPtr->state;
chanPtr = statePtr->topChanPtr;
if (len < 0) {
len = strlen(src);
}
- if (statePtr->encoding == NULL) {
- /*
- * Inefficient way to convert UTF-8 to byte-array, but the code
- * parallels the way it is done for objects.
- * Special case for 1-byte (used by eg [puts] for the \n) could
- * be extended to more efficient translation of the src string.
- */
-
- int result;
+ if (statePtr->encoding) {
+ return WriteChars(chanPtr, src, len);
+ }
- if ((len == 1) && (UCHAR(*src) < 0xC0)) {
- result = WriteBytes(chanPtr, src, len);
- } else {
- Tcl_Obj *objPtr = Tcl_NewStringObj(src, len);
+ /*
+ * Inefficient way to convert UTF-8 to byte-array, but the code
+ * parallels the way it is done for objects. Special case for 1-byte
+ * (used by eg [puts] for the \n) could be extended to more efficient
+ * translation of the src string.
+ */
- src = (char *) Tcl_GetByteArrayFromObj(objPtr, &len);
- result = WriteBytes(chanPtr, src, len);
- TclDecrRefCount(objPtr);
- }
- return result;
+ if ((len == 1) && (UCHAR(*src) < 0xC0)) {
+ return WriteBytes(chanPtr, src, len);
}
- return WriteChars(chanPtr, src, len);
+
+ objPtr = Tcl_NewStringObj(src, len);
+ src = (char *) Tcl_GetByteArrayFromObj(objPtr, &len);
+ result = WriteBytes(chanPtr, src, len);
+ TclDecrRefCount(objPtr);
+ return result;
}
/*
@@ -3859,6 +4023,11 @@ static int
WillRead(
Channel *chanPtr)
{
+ if (chanPtr->typePtr == NULL) {
+ /* Prevent read attempts on a closed channel */
+ Tcl_SetErrno(EINVAL);
+ return -1;
+ }
if ((chanPtr->typePtr->seekProc != NULL)
&& (Tcl_OutputBuffered((Tcl_Channel) chanPtr) > 0)) {
if ((chanPtr->state->curOutPtr != NULL)
@@ -3875,110 +4044,9 @@ WillRead(
/*
*----------------------------------------------------------------------
*
- * WriteBytes --
- *
- * Write a sequence of bytes into an output buffer, may queue the buffer
- * for output if it gets full, and also remembers whether the current
- * buffer is ready e.g. if it contains a newline and we are in line
- * buffering mode.
+ * Write --
*
- * Results:
- * The number of bytes written or -1 in case of error. If -1,
- * Tcl_GetErrno will return the error code.
- *
- * Side effects:
- * May buffer up output and may cause output to be produced on the
- * channel.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-WriteBytes(
- Channel *chanPtr, /* The channel to buffer output for. */
- const char *src, /* Bytes to write. */
- int srcLen) /* Number of bytes to write. */
-{
- ChannelState *statePtr = chanPtr->state;
- /* State info for channel */
- ChannelBuffer *bufPtr;
- char *dst;
- int dstMax, sawLF, savedLF, total, dstLen, toWrite, translate;
-
- if (srcLen) {
- WillWrite(chanPtr);
- }
-
- total = 0;
- sawLF = 0;
- savedLF = 0;
- translate = GotFlag(statePtr, CHANNEL_LINEBUFFERED)
- || (statePtr->outputTranslation != TCL_TRANSLATE_LF);
-
- /*
- * Loop over all bytes in src, storing them in output buffer with proper
- * EOL translation.
- */
-
- while (srcLen + savedLF > 0) {
- bufPtr = statePtr->curOutPtr;
- if (bufPtr == NULL) {
- bufPtr = AllocChannelBuffer(statePtr->bufSize);
- statePtr->curOutPtr = bufPtr;
- }
- dst = InsertPoint(bufPtr);
- dstMax = SpaceLeft(bufPtr);
- dstLen = dstMax;
-
- toWrite = dstLen;
- if (toWrite > srcLen) {
- toWrite = srcLen;
- }
-
- if (translate) {
- if (savedLF) {
- /*
- * A '\n' was left over from last call to TranslateOutputEOL()
- * and we need to store it in this buffer. If the channel is
- * line-based, we will need to flush it.
- */
-
- *dst++ = '\n';
- dstLen--;
- sawLF++;
- }
- if (TranslateOutputEOL(statePtr, dst, src, &dstLen, &toWrite)) {
- sawLF++;
- }
- dstLen += savedLF;
- savedLF = 0;
- if (dstLen > dstMax) {
- savedLF = 1;
- dstLen = dstMax;
- }
- } else {
- memcpy(dst, src, toWrite);
- dstLen = toWrite;
- }
-
- bufPtr->nextAdded += dstLen;
- if (CheckFlush(chanPtr, bufPtr, sawLF) != 0) {
- return -1;
- }
- total += dstLen;
- src += toWrite;
- srcLen -= toWrite;
- sawLF = 0;
- }
- return total;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * WriteChars --
- *
- * Convert UTF-8 bytes to the channel's external encoding and write the
+ * Convert srcLen bytes starting at src according to encoding and write
* produced bytes into an output buffer, may queue the buffer for output
* if it gets full, and also remembers whether the current buffer is
* ready e.g. if it contains a newline and we are in line buffering mode.
@@ -3995,381 +4063,166 @@ WriteBytes(
*/
static int
-WriteChars(
+Write(
Channel *chanPtr, /* The channel to buffer output for. */
const char *src, /* UTF-8 string to write. */
- int srcLen) /* Length of UTF-8 string in bytes. */
+ int srcLen, /* Length of UTF-8 string in bytes. */
+ Tcl_Encoding encoding)
{
ChannelState *statePtr = chanPtr->state;
/* State info for channel */
- ChannelBuffer *bufPtr;
- char *dst, *stage;
- int saved, savedLF, sawLF, total, dstLen, stageMax, dstWrote;
- int stageLen, toWrite, stageRead, endEncoding, result;
- int consumedSomething, translate;
- Tcl_Encoding encoding;
- char safe[BUFFER_PADDING];
+ char *nextNewLine = NULL;
+ int endEncoding, saved = 0, total = 0, flushed = 0, needNlFlush = 0;
if (srcLen) {
WillWrite(chanPtr);
}
- total = 0;
- sawLF = 0;
- savedLF = 0;
- saved = 0;
- encoding = statePtr->encoding;
-
/*
* Write the terminated escape sequence even if srcLen is 0.
*/
endEncoding = ((statePtr->outputEncodingFlags & TCL_ENCODING_END) != 0);
- translate = GotFlag(statePtr, CHANNEL_LINEBUFFERED)
- || (statePtr->outputTranslation != TCL_TRANSLATE_LF);
-
- /*
- * Loop over all UTF-8 characters in src, storing them in staging buffer
- * with proper EOL translation.
- */
+ if (GotFlag(statePtr, CHANNEL_LINEBUFFERED)
+ || (statePtr->outputTranslation != TCL_TRANSLATE_LF)) {
+ nextNewLine = memchr(src, '\n', srcLen);
+ }
- consumedSomething = 1;
- while (consumedSomething && (srcLen + savedLF + endEncoding > 0)) {
- consumedSomething = 0;
- stage = statePtr->outputStage;
- stageMax = statePtr->bufSize;
- stageLen = stageMax;
+ while (srcLen + saved + endEncoding > 0) {
+ ChannelBuffer *bufPtr;
+ char *dst, safe[BUFFER_PADDING];
+ int result, srcRead, dstLen, dstWrote, srcLimit = srcLen;
- toWrite = stageLen;
- if (toWrite > srcLen) {
- toWrite = srcLen;
+ if (nextNewLine) {
+ srcLimit = nextNewLine - src;
}
-
- if (translate) {
- if (savedLF) {
- /*
- * A '\n' was left over from last call to TranslateOutputEOL()
- * and we need to store it in the staging buffer. If the
- * channel is line-based, we will need to flush the output
- * buffer (after translating the staging buffer).
- */
-
- *stage++ = '\n';
- stageLen--;
- sawLF++;
- }
- if (TranslateOutputEOL(statePtr, stage, src, &stageLen,
- &toWrite)) {
- sawLF++;
- }
-
- stage -= savedLF;
- stageLen += savedLF;
- savedLF = 0;
-
- if (stageLen > stageMax) {
- savedLF = 1;
- stageLen = stageMax;
- }
- } else {
- memcpy(stage, src, toWrite);
- stageLen = toWrite;
+
+ /* Get space to write into */
+ bufPtr = statePtr->curOutPtr;
+ if (bufPtr == NULL) {
+ bufPtr = AllocChannelBuffer(statePtr->bufSize);
+ statePtr->curOutPtr = bufPtr;
}
- src += toWrite;
- srcLen -= toWrite;
-
- /*
- * Loop over all UTF-8 characters in staging buffer, converting them
- * to external encoding, storing them in output buffer.
- */
-
- while (stageLen + saved + endEncoding > 0) {
- bufPtr = statePtr->curOutPtr;
- if (bufPtr == NULL) {
- bufPtr = AllocChannelBuffer(statePtr->bufSize);
- statePtr->curOutPtr = bufPtr;
- }
- dst = InsertPoint(bufPtr);
- dstLen = SpaceLeft(bufPtr);
-
- if (saved != 0) {
- /*
- * Here's some translated bytes left over from the last buffer
- * that we need to stick at the beginning of this buffer.
- */
-
- memcpy(dst, safe, (size_t) saved);
- bufPtr->nextAdded += saved;
- dst += saved;
- dstLen -= saved;
- saved = 0;
- }
-
- result = Tcl_UtfToExternal(NULL, encoding, stage, stageLen,
- statePtr->outputEncodingFlags,
- &statePtr->outputEncodingState, dst,
- dstLen + BUFFER_PADDING, &stageRead, &dstWrote, NULL);
-
+ if (saved) {
/*
- * Fix for SF #506297, reported by Martin Forssen
- * <ruric@users.sourceforge.net>.
- *
- * The encoding chosen in the script exposing the bug writes out
- * three intro characters when TCL_ENCODING_START is set, but does
- * not consume any input as TCL_ENCODING_END is cleared. As some
- * output was generated the enclosing loop calls UtfToExternal
- * again, again with START set. Three more characters in the out
- * and still no use of input ... To break this infinite loop we
- * remove TCL_ENCODING_START from the set of flags after the first
- * call (no condition is required, the later calls remove an unset
- * flag, which is a no-op). This causes the subsequent calls to
- * UtfToExternal to consume and convert the actual input.
+ * Here's some translated bytes left over from the last buffer
+ * that we need to stick at the beginning of this buffer.
*/
- statePtr->outputEncodingFlags &= ~TCL_ENCODING_START;
+ memcpy(InsertPoint(bufPtr), safe, (size_t) saved);
+ bufPtr->nextAdded += saved;
+ saved = 0;
+ }
+ PreserveChannelBuffer(bufPtr);
+ dst = InsertPoint(bufPtr);
+ dstLen = SpaceLeft(bufPtr);
+
+ result = Tcl_UtfToExternal(NULL, encoding, src, srcLimit,
+ statePtr->outputEncodingFlags,
+ &statePtr->outputEncodingState, dst,
+ dstLen + BUFFER_PADDING, &srcRead, &dstWrote, NULL);
+
+ /* See chan-io-1.[89]. Tcl Bug 506297. */
+ statePtr->outputEncodingFlags &= ~TCL_ENCODING_START;
+
+ if ((result != TCL_OK) && (srcRead + dstWrote == 0)) {
+ /* We're reading from invalid/incomplete UTF-8 */
+ ReleaseChannelBuffer(bufPtr);
+ if (total == 0) {
+ Tcl_SetErrno(EINVAL);
+ return -1;
+ }
+ break;
+ }
- /*
- * The following code must be executed only when result is not 0.
- */
+ bufPtr->nextAdded += dstWrote;
+ src += srcRead;
+ srcLen -= srcRead;
+ total += dstWrote;
+ dst += dstWrote;
+ dstLen -= dstWrote;
- if ((result != 0) && (stageRead + dstWrote == 0)) {
- /*
- * We have an incomplete UTF-8 character at the end of the
- * staging buffer. It will get moved to the beginning of the
- * staging buffer followed by more bytes from src.
- */
+ if (src == nextNewLine && dstLen > 0) {
+ static char crln[3] = "\r\n";
+ char *nl = NULL;
+ int nlLen = 0;
- src -= stageLen;
- srcLen += stageLen;
- stageLen = 0;
- savedLF = 0;
+ switch (statePtr->outputTranslation) {
+ case TCL_TRANSLATE_LF:
+ nl = crln + 1;
+ nlLen = 1;
+ break;
+ case TCL_TRANSLATE_CR:
+ nl = crln;
+ nlLen = 1;
+ break;
+ case TCL_TRANSLATE_CRLF:
+ nl = crln;
+ nlLen = 2;
+ break;
+ default:
+ Tcl_Panic("unknown output translation requested");
break;
}
- bufPtr->nextAdded += dstWrote;
- if (IsBufferOverflowing(bufPtr)) {
- /*
- * When translating from UTF-8 to external encoding, we
- * allowed the translation to produce a character that crossed
- * the end of the output buffer, so that we would get a
- * completely full buffer before flushing it. The extra bytes
- * will be moved to the beginning of the next buffer.
- */
+
+ result |= Tcl_UtfToExternal(NULL, encoding, nl, nlLen,
+ statePtr->outputEncodingFlags,
+ &statePtr->outputEncodingState, dst,
+ dstLen + BUFFER_PADDING, &srcRead, &dstWrote, NULL);
- saved = -SpaceLeft(bufPtr);
- memcpy(safe, dst + dstLen, (size_t) saved);
- bufPtr->nextAdded = bufPtr->bufLength;
- }
- if (CheckFlush(chanPtr, bufPtr, sawLF) != 0) {
- return -1;
+ if (srcRead != nlLen) {
+ Tcl_Panic("Can This Happen?");
}
+ bufPtr->nextAdded += dstWrote;
+ src++;
+ srcLen--;
total += dstWrote;
- stage += stageRead;
- stageLen -= stageRead;
- sawLF = 0;
-
- consumedSomething = 1;
+ dst += dstWrote;
+ dstLen -= dstWrote;
+ nextNewLine = memchr(src, '\n', srcLen);
+ needNlFlush = 1;
+ }
+ if (IsBufferOverflowing(bufPtr)) {
/*
- * If all translated characters are written to the buffer,
- * endEncoding is set to 0 because the escape sequence may be
- * output.
+ * When translating from UTF-8 to external encoding, we
+ * allowed the translation to produce a character that crossed
+ * the end of the output buffer, so that we would get a
+ * completely full buffer before flushing it. The extra bytes
+ * will be moved to the beginning of the next buffer.
*/
- if ((stageLen + saved == 0) && (result == 0)) {
- endEncoding = 0;
- }
+ saved = -SpaceLeft(bufPtr);
+ memcpy(safe, dst + dstLen, (size_t) saved);
+ bufPtr->nextAdded = bufPtr->bufLength;
}
- }
- /*
- * If nothing was written and it happened because there was no progress in
- * the UTF conversion, we throw an error.
- */
-
- if (!consumedSomething && (total == 0)) {
- Tcl_SetErrno(EINVAL);
- return -1;
- }
- return total;
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * TranslateOutputEOL --
- *
- * Helper function for WriteBytes() and WriteChars(). Converts the '\n'
- * characters in the source buffer into the appropriate EOL form
- * specified by the output translation mode.
- *
- * EOL translation stops either when the source buffer is empty or the
- * output buffer is full.
- *
- * When converting to CRLF mode and there is only 1 byte left in the
- * output buffer, this routine stores the '\r' in the last byte and then
- * stores the '\n' in the byte just past the end of the buffer. The
- * caller is responsible for passing in a buffer that is large enough to
- * hold the extra byte.
- *
- * Results:
- * The return value is 1 if a '\n' was translated from the source buffer,
- * or 0 otherwise -- this can be used by the caller to decide to flush a
- * line-based channel even though the channel buffer is not full.
- *
- * *dstLenPtr is filled with how many bytes of the output buffer were
- * used. As mentioned above, this can be one more that the output
- * buffer's specified length if a CRLF was stored.
- *
- * *srcLenPtr is filled with how many bytes of the source buffer were
- * consumed.
- *
- * Side effects:
- * It may be obvious, but bears mentioning that when converting in CRLF
- * mode (which requires two bytes of storage in the output buffer), the
- * number of bytes consumed from the source buffer will be less than the
- * number of bytes stored in the output buffer.
- *
- *---------------------------------------------------------------------------
- */
-
-static int
-TranslateOutputEOL(
- ChannelState *statePtr, /* Channel being read, for translation and
- * buffering modes. */
- char *dst, /* Output buffer filled with UTF-8 chars by
- * applying appropriate EOL translation to
- * source characters. */
- const char *src, /* Source UTF-8 characters. */
- int *dstLenPtr, /* On entry, the maximum length of output
- * buffer in bytes. On exit, the number of
- * bytes actually used in output buffer. */
- int *srcLenPtr) /* On entry, the length of source buffer. On
- * exit, the number of bytes read from the
- * source buffer. */
-{
- char *dstEnd;
- int srcLen, newlineFound;
-
- newlineFound = 0;
- srcLen = *srcLenPtr;
-
- switch (statePtr->outputTranslation) {
- case TCL_TRANSLATE_LF:
- for (dstEnd = dst + srcLen; dst < dstEnd; ) {
- if (*src == '\n') {
- newlineFound = 1;
- }
- *dst++ = *src++;
- }
- *dstLenPtr = srcLen;
- break;
- case TCL_TRANSLATE_CR:
- for (dstEnd = dst + srcLen; dst < dstEnd;) {
- if (*src == '\n') {
- *dst++ = '\r';
- newlineFound = 1;
- src++;
- } else {
- *dst++ = *src++;
- }
- }
- *dstLenPtr = srcLen;
- break;
- case TCL_TRANSLATE_CRLF: {
- /*
- * Since this causes the number of bytes to grow, we start off trying
- * to put 'srcLen' bytes into the output buffer, but allow it to store
- * more bytes, as long as there's still source bytes and room in the
- * output buffer.
- */
-
- char *dstStart, *dstMax;
- const char *srcStart;
-
- dstStart = dst;
- dstMax = dst + *dstLenPtr;
-
- srcStart = src;
-
- if (srcLen < *dstLenPtr) {
- dstEnd = dst + srcLen;
- } else {
- dstEnd = dst + *dstLenPtr;
+ if ((srcLen + saved == 0) && (result == TCL_OK)) {
+ endEncoding = 0;
}
- while (dst < dstEnd) {
- if (*src == '\n') {
- if (dstEnd < dstMax) {
- dstEnd++;
- }
- *dst++ = '\r';
- newlineFound = 1;
- }
- *dst++ = *src++;
- }
- *srcLenPtr = src - srcStart;
- *dstLenPtr = dst - dstStart;
- break;
- }
- default:
- break;
- }
- return newlineFound;
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * CheckFlush --
- *
- * Helper function for WriteBytes() and WriteChars(). If the channel
- * buffer is ready to be flushed, flush it.
- *
- * Results:
- * The return value is -1 if there was a problem flushing the channel
- * buffer, or 0 otherwise.
- *
- * Side effects:
- * The buffer will be recycled if it is flushed.
- *
- *---------------------------------------------------------------------------
- */
-static int
-CheckFlush(
- Channel *chanPtr, /* Channel being read, for buffering mode. */
- ChannelBuffer *bufPtr, /* Channel buffer to possibly flush. */
- int newlineFlag) /* Non-zero if a the channel buffer contains a
- * newline. */
-{
- ChannelState *statePtr = chanPtr->state;
- /* State info for channel */
-
- /*
- * The current buffer is ready for output:
- * 1. if it is full.
- * 2. if it contains a newline and this channel is line-buffered.
- * 3. if it contains any output and this channel is unbuffered.
- */
-
- if (!GotFlag(statePtr, BUFFER_READY)) {
if (IsBufferFull(bufPtr)) {
- SetFlag(statePtr, BUFFER_READY);
- } else if (GotFlag(statePtr, CHANNEL_LINEBUFFERED)) {
- if (newlineFlag != 0) {
- SetFlag(statePtr, BUFFER_READY);
+ if (FlushChannel(NULL, chanPtr, 0) != 0) {
+ return -1;
+ }
+ flushed += statePtr->bufSize;
+ if (saved == 0 || src[-1] != '\n') {
+ needNlFlush = 0;
}
- } else if (GotFlag(statePtr, CHANNEL_UNBUFFERED)) {
- SetFlag(statePtr, BUFFER_READY);
}
+ ReleaseChannelBuffer(bufPtr);
}
- if (GotFlag(statePtr, BUFFER_READY)) {
+ if ((flushed < total) && (GotFlag(statePtr, CHANNEL_UNBUFFERED) ||
+ (needNlFlush && GotFlag(statePtr, CHANNEL_LINEBUFFERED)))) {
+ SetFlag(statePtr, BUFFER_READY);
if (FlushChannel(NULL, chanPtr, 0) != 0) {
return -1;
}
}
- return 0;
+
+ return total;
}
/*
@@ -4400,14 +4253,12 @@ Tcl_Gets(
* for managing the storage. */
{
Tcl_Obj *objPtr;
- int charsStored, length;
- const char *string;
+ int charsStored;
TclNewObj(objPtr);
charsStored = Tcl_GetsObj(chan, objPtr);
if (charsStored > 0) {
- string = TclGetStringFromObj(objPtr, &length);
- Tcl_DStringAppend(lineRead, string, length);
+ TclDStringAppendObj(lineRead, objPtr);
}
TclDecrRefCount(objPtr);
return charsStored;
@@ -4474,6 +4325,7 @@ Tcl_GetsObj(
*/
chanPtr = statePtr->topChanPtr;
+ Tcl_Preserve(chanPtr);
bufPtr = statePtr->inQueueHead;
encoding = statePtr->encoding;
@@ -4497,16 +4349,7 @@ Tcl_GetsObj(
*/
if (encoding == NULL) {
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
-
- if (tsdPtr->binaryEncoding == NULL) {
- tsdPtr->binaryEncoding = Tcl_GetEncoding(NULL, "iso8859-1");
- Tcl_CreateThreadExitHandler(FreeBinaryEncoding, NULL);
- }
- encoding = tsdPtr->binaryEncoding;
- if (encoding == NULL) {
- Tcl_Panic("attempted gets on binary channel where no iso8859-1 encoding available");
- }
+ encoding = GetBinaryEncoding();
}
/*
@@ -4716,7 +4559,11 @@ Tcl_GetsObj(
* self-modifying reflected transforms.
*/
- chanPtr = statePtr->topChanPtr;
+ if (chanPtr != statePtr->topChanPtr) {
+ Tcl_Release(chanPtr);
+ chanPtr = statePtr->topChanPtr;
+ Tcl_Preserve(chanPtr);
+ }
bufPtr = gs.bufPtr;
if (bufPtr == NULL) {
@@ -4750,16 +4597,18 @@ Tcl_GetsObj(
* Regenerate the top channel, in case it was changed due to
* self-modifying reflected transforms.
*/
-
- chanPtr = statePtr->topChanPtr;
-
+ if (chanPtr != statePtr->topChanPtr) {
+ Tcl_Release(chanPtr);
+ chanPtr = statePtr->topChanPtr;
+ Tcl_Preserve(chanPtr);
+ }
bufPtr = statePtr->inQueueHead;
- if (bufPtr == NULL) {
- Tcl_Panic("Tcl_GetsObj: restore reached with bufPtr==NULL");
+ if (bufPtr != NULL) {
+ bufPtr->nextRemoved = oldRemoved;
+ bufPtr = bufPtr->nextPtr;
}
- bufPtr->nextRemoved = oldRemoved;
- for (bufPtr = bufPtr->nextPtr; bufPtr != NULL; bufPtr = bufPtr->nextPtr) {
+ for ( ; bufPtr != NULL; bufPtr = bufPtr->nextPtr) {
bufPtr->nextRemoved = BUFFER_PADDING;
}
CommonGetsCleanup(chanPtr);
@@ -4792,10 +4641,13 @@ Tcl_GetsObj(
* Regenerate the top channel, in case it was changed due to
* self-modifying reflected transforms.
*/
-
- chanPtr = statePtr->topChanPtr;
-
+ if (chanPtr != statePtr->topChanPtr) {
+ Tcl_Release(chanPtr);
+ chanPtr = statePtr->topChanPtr;
+ Tcl_Preserve(chanPtr);
+ }
UpdateInterest(chanPtr);
+ Tcl_Release(chanPtr);
return copiedTotal;
}
@@ -4841,6 +4693,7 @@ TclGetsObjBinary(
*/
chanPtr = statePtr->topChanPtr;
+ Tcl_Preserve(chanPtr);
bufPtr = statePtr->inQueueHead;
@@ -4898,6 +4751,9 @@ TclGetsObjBinary(
goto restore;
}
bufPtr = statePtr->inQueueTail;
+ if (bufPtr == NULL) {
+ goto restore;
+ }
}
dst = (unsigned char *) RemovePoint(bufPtr);
@@ -5010,12 +4866,12 @@ TclGetsObjBinary(
restore:
bufPtr = statePtr->inQueueHead;
- if (bufPtr == NULL) {
- Tcl_Panic("TclGetsObjBinary: restore reached with bufPtr==NULL");
+ if (bufPtr) {
+ bufPtr->nextRemoved = oldRemoved;
+ bufPtr = bufPtr->nextPtr;
}
- bufPtr->nextRemoved = oldRemoved;
- for (bufPtr = bufPtr->nextPtr; bufPtr != NULL; bufPtr = bufPtr->nextPtr) {
+ for ( ; bufPtr != NULL; bufPtr = bufPtr->nextPtr) {
bufPtr->nextRemoved = BUFFER_PADDING;
}
CommonGetsCleanup(chanPtr);
@@ -5044,6 +4900,7 @@ TclGetsObjBinary(
done:
UpdateInterest(chanPtr);
+ Tcl_Release(chanPtr);
return copiedTotal;
}
@@ -5072,6 +4929,21 @@ FreeBinaryEncoding(
tsdPtr->binaryEncoding = NULL;
}
}
+
+static Tcl_Encoding
+GetBinaryEncoding()
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+ if (tsdPtr->binaryEncoding == NULL) {
+ tsdPtr->binaryEncoding = Tcl_GetEncoding(NULL, "iso8859-1");
+ Tcl_CreateThreadExitHandler(FreeBinaryEncoding, NULL);
+ }
+ if (tsdPtr->binaryEncoding == NULL) {
+ Tcl_Panic("binary encoding is not available");
+ }
+ return tsdPtr->binaryEncoding;
+}
/*
*---------------------------------------------------------------------------
@@ -5154,6 +5026,11 @@ FilterInputBytes(
}
bufPtr = statePtr->inQueueTail;
gsPtr->bufPtr = bufPtr;
+ if (bufPtr == NULL) {
+ gsPtr->charsWrote = 0;
+ gsPtr->rawRead = 0;
+ return -1;
+ }
}
/*
@@ -5443,7 +5320,7 @@ Tcl_Read(
return -1;
}
- return DoRead(chanPtr, dst, bytesToRead);
+ return DoRead(chanPtr, dst, bytesToRead, 0);
}
/*
@@ -5501,6 +5378,7 @@ Tcl_ReadRaw(
* requests more bytes.
*/
+ Tcl_Preserve(chanPtr);
for (copied = 0; copied < bytesToRead; copied += copiedNow) {
copiedNow = CopyBuffer(chanPtr, bufPtr + copied,
bytesToRead - copied);
@@ -5583,7 +5461,7 @@ Tcl_ReadRaw(
* over EAGAIN/WOULDBLOCK handling.
*/
- return copied;
+ goto done;
}
SetFlag(statePtr, CHANNEL_BLOCKED);
@@ -5591,14 +5469,17 @@ Tcl_ReadRaw(
}
Tcl_SetErrno(result);
- return -1;
+ copied = -1;
+ goto done;
}
- return copied + nread;
+ copied += nread;
+ goto done;
}
}
done:
+ Tcl_Release(chanPtr);
return copied;
}
@@ -5706,6 +5587,7 @@ DoReadChars(
chanPtr = statePtr->topChanPtr;
encoding = statePtr->encoding;
factor = UTF_EXPANSION_FACTOR;
+ Tcl_Preserve(chanPtr);
if (appendFlag == 0) {
if (encoding == NULL) {
@@ -5767,6 +5649,11 @@ DoReadChars(
ResetFlag(statePtr, CHANNEL_BLOCKED);
}
result = GetInput(chanPtr);
+ if (chanPtr != statePtr->topChanPtr) {
+ Tcl_Release(chanPtr);
+ chanPtr = statePtr->topChanPtr;
+ Tcl_Preserve(chanPtr);
+ }
if (result != 0) {
if (result == EAGAIN) {
break;
@@ -5797,10 +5684,13 @@ DoReadChars(
* Regenerate the top channel, in case it was changed due to
* self-modifying reflected transforms.
*/
-
- chanPtr = statePtr->topChanPtr;
-
+ if (chanPtr != statePtr->topChanPtr) {
+ Tcl_Release(chanPtr);
+ chanPtr = statePtr->topChanPtr;
+ Tcl_Preserve(chanPtr);
+ }
UpdateInterest(chanPtr);
+ Tcl_Release(chanPtr);
return copied;
}
@@ -6556,7 +6446,7 @@ DiscardInputQueued(
*/
if (discardSavedBuffers && statePtr->saveInBufPtr != NULL) {
- ckfree(statePtr->saveInBufPtr);
+ ReleaseChannelBuffer(statePtr->saveInBufPtr);
statePtr->saveInBufPtr = NULL;
}
}
@@ -6649,7 +6539,7 @@ GetInput(
if ((bufPtr != NULL)
&& (bufPtr->bufLength - BUFFER_PADDING < statePtr->bufSize)) {
- ckfree(bufPtr);
+ ReleaseChannelBuffer(bufPtr);
bufPtr = NULL;
}
@@ -6711,10 +6601,12 @@ GetInput(
} else
#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
{
+ PreserveChannelBuffer(bufPtr);
nread = ChanRead(chanPtr, InsertPoint(bufPtr), toRead, &result);
}
if (nread > 0) {
+ result = 0;
bufPtr->nextAdded += nread;
/*
@@ -6738,6 +6630,7 @@ GetInput(
}
#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
} else if (nread == 0) {
+ result = 0;
SetFlag(statePtr, CHANNEL_EOF);
statePtr->inputEncodingFlags |= TCL_ENCODING_END;
} else if (nread < 0) {
@@ -6746,9 +6639,9 @@ GetInput(
result = EAGAIN;
}
Tcl_SetErrno(result);
- return result;
}
- return 0;
+ ReleaseChannelBuffer(bufPtr);
+ return result;
}
/*
@@ -7435,14 +7328,6 @@ Tcl_SetChannelBufferSize(
statePtr = ((Channel *) chan)->state;
statePtr->bufSize = sz;
-
- if (statePtr->outputStage != NULL) {
- ckfree(statePtr->outputStage);
- statePtr->outputStage = NULL;
- }
- if ((statePtr->encoding != NULL) && GotFlag(statePtr, TCL_WRITABLE)) {
- statePtr->outputStage = ckalloc(statePtr->bufSize + 2);
- }
}
/*
@@ -7515,11 +7400,12 @@ Tcl_BadChannelOption(
const char **argv;
int argc, i;
Tcl_DString ds;
+ Tcl_Obj *errObj;
Tcl_DStringInit(&ds);
Tcl_DStringAppend(&ds, genericopt, -1);
if (optionList && (*optionList)) {
- Tcl_DStringAppend(&ds, " ", 1);
+ TclDStringAppendLiteral(&ds, " ");
Tcl_DStringAppend(&ds, optionList, -1);
}
if (Tcl_SplitList(interp, Tcl_DStringValue(&ds),
@@ -7527,13 +7413,14 @@ Tcl_BadChannelOption(
Tcl_Panic("malformed option list in channel driver");
}
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad option \"", optionName,
- "\": should be one of ", NULL);
+ errObj = Tcl_ObjPrintf("bad option \"%s\": should be one of ",
+ optionName);
argc--;
for (i = 0; i < argc; i++) {
- Tcl_AppendResult(interp, "-", argv[i], ", ", NULL);
+ Tcl_AppendPrintfToObj(errObj, "-%s, ", argv[i]);
}
- Tcl_AppendResult(interp, "or -", argv[i], NULL);
+ Tcl_AppendPrintfToObj(errObj, "or -%s", argv[i]);
+ Tcl_SetObjResult(interp, errObj);
Tcl_DStringFree(&ds);
ckfree(argv);
}
@@ -7811,8 +7698,9 @@ Tcl_SetChannelOption(
if (statePtr->csPtrR || statePtr->csPtrW) {
if (interp) {
- Tcl_AppendResult(interp, "unable to set channel options: "
- "background copy in progress", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "unable to set channel options: background copy in"
+ " progress", -1));
}
return TCL_ERROR;
}
@@ -7861,8 +7749,9 @@ Tcl_SetChannelOption(
ResetFlag(statePtr, CHANNEL_LINEBUFFERED);
SetFlag(statePtr, CHANNEL_UNBUFFERED);
} else if (interp) {
- Tcl_AppendResult(interp, "bad value for -buffering: "
- "must be one of full, line, or none", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "bad value for -buffering: must be one of"
+ " full, line, or none", -1));
return TCL_ERROR;
}
return TCL_OK;
@@ -7890,7 +7779,8 @@ Tcl_SetChannelOption(
* iso2022, the terminated escape sequence must write to the buffer.
*/
- if ((statePtr->encoding != NULL) && (statePtr->curOutPtr != NULL)
+ if ((statePtr->encoding != NULL)
+ && !(statePtr->outputEncodingFlags & TCL_ENCODING_START)
&& (CheckChannelErrors(statePtr, TCL_WRITABLE) == 0)) {
statePtr->outputEncodingFlags |= TCL_ENCODING_END;
WriteChars(chanPtr, "", 0);
@@ -7917,8 +7807,9 @@ Tcl_SetChannelOption(
if (inValue & 0x80 || outValue & 0x80) {
if (interp) {
- Tcl_AppendResult(interp, "bad value for -eofchar: ",
- "must be non-NUL ASCII character", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "bad value for -eofchar: must be non-NUL ASCII"
+ " character", -1));
}
ckfree(argv);
return TCL_ERROR;
@@ -7931,9 +7822,9 @@ Tcl_SetChannelOption(
}
} else {
if (interp) {
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"bad value for -eofchar: should be a list of zero,"
- " one, or two elements", NULL);
+ " one, or two elements", -1));
}
ckfree(argv);
return TCL_ERROR;
@@ -7965,9 +7856,9 @@ Tcl_SetChannelOption(
writeMode = GotFlag(statePtr, TCL_WRITABLE) ? argv[1] : NULL;
} else {
if (interp) {
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"bad value for -translation: must be a one or two"
- " element list", NULL);
+ " element list", -1));
}
ckfree(argv);
return TCL_ERROR;
@@ -7995,10 +7886,9 @@ Tcl_SetChannelOption(
translation = TCL_PLATFORM_TRANSLATION;
} else {
if (interp) {
- Tcl_AppendResult(interp,
- "bad value for -translation: "
- "must be one of auto, binary, cr, lf, crlf,"
- " or platform", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "bad value for -translation: must be one of "
+ "auto, binary, cr, lf, crlf, or platform", -1));
}
ckfree(argv);
return TCL_ERROR;
@@ -8046,10 +7936,9 @@ Tcl_SetChannelOption(
statePtr->outputTranslation = TCL_PLATFORM_TRANSLATION;
} else {
if (interp) {
- Tcl_AppendResult(interp,
- "bad value for -translation: "
- "must be one of auto, binary, cr, lf, crlf,"
- " or platform", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "bad value for -translation: must be one of "
+ "auto, binary, cr, lf, crlf, or platform", -1));
}
ckfree(argv);
return TCL_ERROR;
@@ -8080,17 +7969,6 @@ Tcl_SetChannelOption(
statePtr->inQueueTail = NULL;
}
- /*
- * If encoding or bufsize changes, need to update output staging buffer.
- */
-
- if (statePtr->outputStage != NULL) {
- ckfree(statePtr->outputStage);
- statePtr->outputStage = NULL;
- }
- if ((statePtr->encoding != NULL) && GotFlag(statePtr, TCL_WRITABLE)) {
- statePtr->outputStage = ckalloc(statePtr->bufSize + 2);
- }
return TCL_OK;
}
@@ -8325,6 +8203,11 @@ UpdateInterest(
/* State info for channel */
int mask = statePtr->interestMask;
+ if (chanPtr->typePtr == NULL) {
+ /* Do not update interest on a closed channel */
+ return;
+ }
+
/*
* If there are flushed buffers waiting to be written, then we need to
* watch for the channel to become writable.
@@ -8388,8 +8271,8 @@ UpdateInterest(
mask &= ~TCL_EXCEPTION;
if (!statePtr->timer) {
- statePtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc,
- chanPtr);
+ statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
+ ChannelTimerProc, chanPtr);
}
}
}
@@ -8430,7 +8313,8 @@ ChannelTimerProc(
* before UpdateInterest gets called by Tcl_NotifyChannel.
*/
- statePtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc,chanPtr);
+ statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
+ ChannelTimerProc,chanPtr);
#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
/*
@@ -8729,7 +8613,7 @@ CreateScriptRecord(
/*
* Initialize the structure before calling Tcl_CreateChannelHandler,
- * because a reflected channel caling 'chan postevent' aka
+ * because a reflected channel calling 'chan postevent' aka
* 'Tcl_NotifyChannel' in its 'watch'Proc will invoke
* 'TclChannelEventScriptInvoker' immediately, and we do not wish it to
* see uninitialized memory and crash. See [Bug 2918110].
@@ -8792,6 +8676,7 @@ TclChannelEventScriptInvoker(
*/
Tcl_Preserve(interp);
+ Tcl_Preserve(chanPtr);
result = Tcl_EvalObjEx(interp, esPtr->scriptPtr, TCL_EVAL_GLOBAL);
/*
@@ -8808,6 +8693,7 @@ TclChannelEventScriptInvoker(
}
Tcl_BackgroundException(interp, result);
}
+ Tcl_Release(chanPtr);
Tcl_Release(interp);
}
@@ -8846,7 +8732,7 @@ Tcl_FileEventObjCmd(
int modeIndex; /* Index of mode argument. */
int mask;
static const char *const modeOptions[] = {"readable", "writable", NULL};
- static int maskArray[] = {TCL_READABLE, TCL_WRITABLE};
+ static const int maskArray[] = {TCL_READABLE, TCL_WRITABLE};
if ((objc != 3) && (objc != 4)) {
Tcl_WrongNumArgs(interp, 1, objv, "channelId event ?script?");
@@ -8866,8 +8752,8 @@ Tcl_FileEventObjCmd(
chanPtr = (Channel *) chan;
statePtr = chanPtr->state;
if ((statePtr->flags & mask) == 0) {
- Tcl_AppendResult(interp, "channel is not ",
- (mask == TCL_READABLE) ? "readable" : "writable", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("channel is not %s",
+ (mask == TCL_READABLE) ? "readable" : "writable"));
return TCL_ERROR;
}
@@ -8988,15 +8874,15 @@ TclCopyChannel(
if (BUSY_STATE(inStatePtr, TCL_READABLE)) {
if (interp) {
- Tcl_AppendResult(interp, "channel \"",
- Tcl_GetChannelName(inChan), "\" is busy", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "channel \"%s\" is busy", Tcl_GetChannelName(inChan)));
}
return TCL_ERROR;
}
if (BUSY_STATE(outStatePtr, TCL_WRITABLE)) {
if (interp) {
- Tcl_AppendResult(interp, "channel \"",
- Tcl_GetChannelName(outChan), "\" is busy", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "channel \"%s\" is busy", Tcl_GetChannelName(outChan)));
}
return TCL_ERROR;
}
@@ -9168,7 +9054,8 @@ CopyData(
}
if (inBinary || sameEncoding) {
- size = DoRead(inStatePtr->topChanPtr, csPtr->buffer, sizeb);
+ size = DoRead(inStatePtr->topChanPtr, csPtr->buffer, sizeb,
+ !GotFlag(inStatePtr, CHANNEL_NONBLOCKING));
} else {
size = DoReadChars(inStatePtr->topChanPtr, bufObj, sizeb,
0 /* No append */);
@@ -9204,8 +9091,8 @@ CopyData(
if ((size == 0) && Tcl_Eof(inChan) && !(cmdPtr && (mask == 0))) {
break;
}
- if (((!Tcl_Eof(inChan)) || (cmdPtr && (mask == 0))) &&
- !(mask & TCL_READABLE)) {
+ if (cmdPtr && (!Tcl_Eof(inChan) || (mask == 0)) &&
+ !(mask & TCL_READABLE)) {
if (mask & TCL_WRITABLE) {
Tcl_DeleteChannelHandler(outChan, CopyEventProc, csPtr);
}
@@ -9233,9 +9120,9 @@ CopyData(
}
if (outBinary || sameEncoding) {
- sizeb = DoWrite(outStatePtr->topChanPtr, buffer, sizeb);
+ sizeb = WriteBytes(outStatePtr->topChanPtr, buffer, sizeb);
} else {
- sizeb = DoWriteChars(outStatePtr->topChanPtr, buffer, sizeb);
+ sizeb = WriteChars(outStatePtr->topChanPtr, buffer, sizeb);
}
/*
@@ -9407,7 +9294,8 @@ static int
DoRead(
Channel *chanPtr, /* The channel from which to read. */
char *bufPtr, /* Where to store input read. */
- int toRead) /* Maximum number of bytes to read. */
+ int toRead, /* Maximum number of bytes to read. */
+ int allowShortReads) /* Allow half-blocking (pipes,sockets) */
{
ChannelState *statePtr = chanPtr->state;
/* State info for channel */
@@ -9423,6 +9311,7 @@ DoRead(
* operation.
*/
+ Tcl_Preserve(chanPtr);
if (!GotFlag(statePtr, CHANNEL_STICKY_EOF)) {
ResetFlag(statePtr, CHANNEL_EOF);
}
@@ -9448,7 +9337,10 @@ DoRead(
}
goto done;
}
- }
+ } else if (allowShortReads) {
+ copied += copiedNow;
+ break;
+ }
}
ResetFlag(statePtr, CHANNEL_BLOCKED);
@@ -9460,6 +9352,7 @@ DoRead(
done:
UpdateInterest(chanPtr);
+ Tcl_Release(chanPtr);
return copied;
}
@@ -9783,162 +9676,6 @@ CopyBuffer(
/*
*----------------------------------------------------------------------
*
- * DoWrite --
- *
- * Puts a sequence of characters into an output buffer, may queue the
- * buffer for output if it gets full, and also remembers whether the
- * current buffer is ready e.g. if it contains a newline and we are in
- * line buffering mode.
- *
- * Results:
- * The number of bytes written or -1 in case of error. If -1,
- * Tcl_GetErrno will return the error code.
- *
- * Side effects:
- * May buffer up output and may cause output to be produced on the
- * channel.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-DoWrite(
- Channel *chanPtr, /* The channel to buffer output for. */
- const char *src, /* Data to write. */
- int srcLen) /* Number of bytes to write. */
-{
- ChannelState *statePtr = chanPtr->state;
- /* State info for channel */
- ChannelBuffer *outBufPtr; /* Current output buffer. */
- int foundNewline; /* Did we find a newline in output? */
- char *dPtr;
- const char *sPtr; /* Search variables for newline. */
- int crsent; /* In CRLF eol translation mode, remember the
- * fact that a CR was output to the channel
- * without its following NL. */
- int i; /* Loop index for newline search. */
- int destCopied; /* How many bytes were used in this
- * destination buffer to hold the output? */
- int totalDestCopied; /* How many bytes total were copied to the
- * channel buffer? */
- int srcCopied; /* How many bytes were copied from the source
- * string? */
- char *destPtr; /* Where in line to copy to? */
-
- /*
- * If we are in network (or windows) translation mode, record the fact
- * that we have not yet sent a CR to the channel.
- */
-
- crsent = 0;
-
- /*
- * Loop filling buffers and flushing them until all output has been
- * consumed.
- */
-
- srcCopied = 0;
- totalDestCopied = 0;
-
- while (srcLen > 0) {
- /*
- * Make sure there is a current output buffer to accept output.
- */
-
- if (statePtr->curOutPtr == NULL) {
- statePtr->curOutPtr = AllocChannelBuffer(statePtr->bufSize);
- }
-
- outBufPtr = statePtr->curOutPtr;
-
- destCopied = SpaceLeft(outBufPtr);
- if (destCopied > srcLen) {
- destCopied = srcLen;
- }
-
- destPtr = InsertPoint(outBufPtr);
- switch (statePtr->outputTranslation) {
- case TCL_TRANSLATE_LF:
- srcCopied = destCopied;
- memcpy(destPtr, src, (size_t) destCopied);
- break;
- case TCL_TRANSLATE_CR:
- srcCopied = destCopied;
- memcpy(destPtr, src, (size_t) destCopied);
- for (dPtr = destPtr; dPtr < destPtr + destCopied; dPtr++) {
- if (*dPtr == '\n') {
- *dPtr = '\r';
- }
- }
- break;
- case TCL_TRANSLATE_CRLF:
- for (srcCopied = 0, dPtr = destPtr, sPtr = src;
- dPtr < destPtr + destCopied;
- dPtr++, sPtr++, srcCopied++) {
- if (*sPtr == '\n') {
- if (crsent) {
- *dPtr = '\n';
- crsent = 0;
- } else {
- *dPtr = '\r';
- crsent = 1;
- sPtr--, srcCopied--;
- }
- } else {
- *dPtr = *sPtr;
- }
- }
- break;
- case TCL_TRANSLATE_AUTO:
- Tcl_Panic("Tcl_Write: AUTO output translation mode not supported");
- default:
- Tcl_Panic("Tcl_Write: unknown output translation mode");
- }
-
- /*
- * The current buffer is ready for output if it is full, or if it
- * contains a newline and this channel is line-buffered, or if it
- * contains any output and this channel is unbuffered.
- */
-
- outBufPtr->nextAdded += destCopied;
- if (!GotFlag(statePtr, BUFFER_READY)) {
- if (IsBufferFull(outBufPtr)) {
- SetFlag(statePtr, BUFFER_READY);
- } else if (GotFlag(statePtr, CHANNEL_LINEBUFFERED)) {
- for (sPtr = src, i = 0, foundNewline = 0;
- (i < srcCopied) && (!foundNewline);
- i++, sPtr++) {
- if (*sPtr == '\n') {
- foundNewline = 1;
- break;
- }
- }
- if (foundNewline) {
- SetFlag(statePtr, BUFFER_READY);
- }
- } else if (GotFlag(statePtr, CHANNEL_UNBUFFERED)) {
- SetFlag(statePtr, BUFFER_READY);
- }
- }
-
- totalDestCopied += srcCopied;
- src += srcCopied;
- srcLen -= srcCopied;
-
- if (GotFlag(statePtr, BUFFER_READY)) {
- if (FlushChannel(NULL, chanPtr, 0) != 0) {
- return -1;
- }
- }
- } /* Closes "while" */
-
- return totalDestCopied;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* CopyEventProc --
*
* This routine is invoked as a channel event handler for the background
@@ -10053,12 +9790,15 @@ StackSetBlockMode(
{
int result = 0;
Tcl_DriverBlockModeProc *blockModeProc;
+ ChannelState *statePtr = chanPtr->state;
/*
* Start at the top of the channel stack
+ * TODO: Examine what can go wrong when blockModeProc calls
+ * disturb the stacking state of the channel.
*/
- chanPtr = chanPtr->state->topChanPtr;
+ chanPtr = statePtr->topChanPtr;
while (chanPtr != NULL) {
blockModeProc = Tcl_ChannelBlockModeProc(chanPtr->typePtr);
if (blockModeProc != NULL) {
@@ -10117,8 +9857,9 @@ SetBlockMode(
*/
if (!TclChanCaughtErrorBypass(interp, (Tcl_Channel) chanPtr)) {
- Tcl_AppendResult(interp, "error setting blocking mode: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error setting blocking mode: %s",
+ Tcl_PosixError(interp)));
}
} else {
/*
@@ -11160,12 +10901,11 @@ DupChannelIntRep(
* currently have an internal rep.*/
{
ChannelState *statePtr = GET_CHANNELSTATE(srcPtr);
- Interp *interpPtr = GET_CHANNELINTERP(srcPtr);
SET_CHANNELSTATE(copyPtr, statePtr);
- SET_CHANNELINTERP(copyPtr, interpPtr);
+ SET_CHANNELINTERP(copyPtr, GET_CHANNELINTERP(srcPtr));
Tcl_Preserve(statePtr);
- copyPtr->typePtr = &tclChannelType;
+ copyPtr->typePtr = srcPtr->typePtr;
}
/*
@@ -11191,43 +10931,29 @@ SetChannelFromAny(
register Tcl_Obj *objPtr) /* The object to convert. */
{
ChannelState *statePtr;
- Interp *interpPtr;
if (interp == NULL) {
return TCL_ERROR;
}
- if (objPtr->typePtr == &tclChannelType) {
+ if (objPtr->typePtr == &chanObjType) {
/*
* The channel is valid until any call to DetachChannel occurs.
* Ensure consistency checks are done.
*/
statePtr = GET_CHANNELSTATE(objPtr);
- interpPtr = GET_CHANNELINTERP(objPtr);
if (GotFlag(statePtr, CHANNEL_TAINTED|CHANNEL_CLOSED)) {
ResetFlag(statePtr, CHANNEL_TAINTED);
Tcl_Release(statePtr);
- UpdateStringOfChannel(objPtr);
objPtr->typePtr = NULL;
- } else if (interpPtr != (Interp*) interp) {
+ } else if (interp != GET_CHANNELINTERP(objPtr)) {
Tcl_Release(statePtr);
- UpdateStringOfChannel(objPtr);
objPtr->typePtr = NULL;
}
}
- if (objPtr->typePtr != &tclChannelType) {
- Tcl_Channel chan;
-
- /*
- * We need a valid string with which to check for a valid channel, but
- * make sure not to free internal rep until validated. [Bug 1847044]
- */
-
- if ((objPtr->typePtr != NULL) && (objPtr->bytes == NULL)) {
- objPtr->typePtr->updateStringProc(objPtr);
- }
+ if (objPtr->typePtr != &chanObjType) {
+ Tcl_Channel chan = Tcl_GetChannel(interp, TclGetString(objPtr), NULL);
- chan = Tcl_GetChannel(interp, objPtr->bytes, NULL);
if (chan == NULL) {
return TCL_ERROR;
}
@@ -11237,7 +10963,7 @@ SetChannelFromAny(
Tcl_Preserve(statePtr);
SET_CHANNELSTATE(objPtr, statePtr);
SET_CHANNELINTERP(objPtr, interp);
- objPtr->typePtr = &tclChannelType;
+ objPtr->typePtr = &chanObjType;
}
return TCL_OK;
}
@@ -11245,45 +10971,6 @@ SetChannelFromAny(
/*
*----------------------------------------------------------------------
*
- * UpdateStringOfChannel --
- *
- * Update the string representation for an object whose internal
- * representation is "Channel".
- *
- * Results:
- * None.
- *
- * Side effects:
- * The object's string may be set by converting its Unicode represention
- * to UTF format.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-UpdateStringOfChannel(
- Tcl_Obj *objPtr) /* Object with string rep to update. */
-{
- if (objPtr->bytes == NULL) {
- ChannelState *statePtr = GET_CHANNELSTATE(objPtr);
- const char *name = statePtr->channelName;
-
- if (name) {
- size_t len = strlen(name);
-
- objPtr->bytes = ckalloc(len + 1);
- objPtr->length = len;
- memcpy(objPtr->bytes, name, len);
- } else {
- objPtr->bytes = tclEmptyStringRep;
- objPtr->length = 0;
- }
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
* FreeChannelIntRep --
*
* Release statePtr storage.
diff --git a/generic/tclIO.h b/generic/tclIO.h
index 3283c3e..1e02749 100644
--- a/generic/tclIO.h
+++ b/generic/tclIO.h
@@ -30,32 +30,13 @@
#endif
/*
- * The following structure encapsulates the state for a background channel
- * copy. Note that the data buffer for the copy will be appended to this
- * structure.
- */
-
-typedef struct CopyState {
- struct Channel *readPtr; /* Pointer to input channel. */
- struct Channel *writePtr; /* Pointer to output channel. */
- int readFlags; /* Original read channel flags. */
- int writeFlags; /* Original write channel flags. */
- Tcl_WideInt toRead; /* Number of bytes to copy, or -1. */
- Tcl_WideInt total; /* Total bytes transferred (written). */
- Tcl_Interp *interp; /* Interp that started the copy. */
- Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */
- int bufSize; /* Size of appended buffer. */
- char buffer[1]; /* Copy buffer, this must be the last
- * field. */
-} CopyState;
-
-/*
* struct ChannelBuffer:
*
* Buffers data being sent to or from a channel.
*/
typedef struct ChannelBuffer {
+ int refCount; /* Current uses count */
int nextAdded; /* The next position into which a character
* will be put in the buffer. */
int nextRemoved; /* Position of next byte to be removed from
@@ -86,19 +67,6 @@ typedef struct ChannelBuffer {
#define CHANNELBUFFER_DEFAULT_SIZE (1024 * 4)
/*
- * Structure to record a close callback. One such record exists for each close
- * callback registered for a channel.
- */
-
-typedef struct CloseCallback {
- Tcl_CloseProc *proc; /* The procedure to call. */
- ClientData clientData; /* Arbitrary one-word data to pass to the
- * callback. */
- struct CloseCallback *nextPtr;
- /* For chaining close callbacks. */
-} CloseCallback;
-
-/*
* The following structure describes the information saved from a call to
* "fileevent". This is used later when the event being waited for to invoke
* the saved script in the interpreter designed in this record.
@@ -195,7 +163,8 @@ typedef struct ChannelState {
* value is the POSIX error code. */
int refCount; /* How many interpreters hold references to
* this IO channel? */
- CloseCallback *closeCbPtr; /* Callbacks registered to be called when the
+ struct CloseCallback *closeCbPtr;
+ /* Callbacks registered to be called when the
* channel is closed. */
char *outputStage; /* Temporary staging buffer used when
* translating EOL before converting from
@@ -217,8 +186,10 @@ typedef struct ChannelState {
* handlers ("fileevent") on this channel. */
int bufSize; /* What size buffers to allocate? */
Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */
- CopyState *csPtrR; /* State of background copy for which channel is input, or NULL. */
- CopyState *csPtrW; /* State of background copy for which channel is output, or NULL. */
+ struct CopyState *csPtrR; /* State of background copy for which channel
+ * is input, or NULL. */
+ struct CopyState *csPtrW; /* State of background copy for which channel
+ * is output, or NULL. */
Channel *topChanPtr; /* Refers to topmost channel in a stack. Never
* NULL. */
Channel *bottomChanPtr; /* Refers to bottommost channel in a stack.
@@ -342,87 +313,11 @@ typedef struct ChannelState {
* the channel is allowed. */
/*
- * For each channel handler registered in a call to Tcl_CreateChannelHandler,
- * there is one record of the following type. All of records for a specific
- * channel are chained together in a singly linked list which is stored in the
- * channel structure.
- */
-
-typedef struct ChannelHandler {
- Channel *chanPtr; /* The channel structure for this channel. */
- int mask; /* Mask of desired events. */
- Tcl_ChannelProc *proc; /* Procedure to call in the type of
- * Tcl_CreateChannelHandler. */
- ClientData clientData; /* Argument to pass to procedure. */
- struct ChannelHandler *nextPtr;
- /* Next one in list of registered handlers. */
-} ChannelHandler;
-
-/*
- * This structure keeps track of the current ChannelHandler being invoked in
- * the current invocation of ChannelHandlerEventProc. There is a potential
- * problem if a ChannelHandler is deleted while it is the current one, since
- * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this
- * problem, structures of the type below indicate the next handler to be
- * processed for any (recursively nested) dispatches in progress. The
- * nextHandlerPtr field is updated if the handler being pointed to is deleted.
- * The nextPtr field is used to chain together all recursive invocations, so
- * that Tcl_DeleteChannelHandler can find all the recursively nested
- * invocations of ChannelHandlerEventProc and compare the handler being
- * deleted against the NEXT handler to be invoked in that invocation; when it
- * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr
- * field of the structure to the next handler.
- */
-
-typedef struct NextChannelHandler {
- ChannelHandler *nextHandlerPtr;
- /* The next handler to be invoked in this
- * invocation. */
- struct NextChannelHandler *nestedHandlerPtr;
- /* Next nested invocation of
- * ChannelHandlerEventProc. */
-} NextChannelHandler;
-
-/*
- * The following structure describes the event that is added to the Tcl event
- * queue by the channel handler check procedure.
- */
-
-typedef struct ChannelHandlerEvent {
- Tcl_Event header; /* Standard header for all events. */
- Channel *chanPtr; /* The channel that is ready. */
- int readyMask; /* Events that have occurred. */
-} ChannelHandlerEvent;
-
-/*
- * The following structure is used by Tcl_GetsObj() to encapsulates the state
- * for a "gets" operation.
+ * The length of time to wait between synthetic timer events. Must be zero or
+ * bad things tend to happen.
*/
-typedef struct GetsState {
- Tcl_Obj *objPtr; /* The object to which UTF-8 characters will
- * be appended. */
- char **dstPtr; /* Pointer into objPtr's string rep where next
- * character should be stored. */
- Tcl_Encoding encoding; /* The encoding to use to convert raw bytes to
- * UTF-8. */
- ChannelBuffer *bufPtr; /* The current buffer of raw bytes being
- * emptied. */
- Tcl_EncodingState state; /* The encoding state just before the last
- * external to UTF-8 conversion in
- * FilterInputBytes(). */
- int rawRead; /* The number of bytes removed from bufPtr in
- * the last call to FilterInputBytes(). */
- int bytesWrote; /* The number of bytes of UTF-8 data appended
- * to objPtr during the last call to
- * FilterInputBytes(). */
- int charsWrote; /* The corresponding number of UTF-8
- * characters appended to objPtr during the
- * last call to FilterInputBytes(). */
- int totalChars; /* The total number of UTF-8 characters
- * appended to objPtr so far, just before the
- * last call to FilterInputBytes(). */
-} GetsState;
+#define SYNTHETIC_EVENT_TIME 0
/*
* Local Variables:
diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c
index 349814a..14910d7 100644
--- a/generic/tclIOCmd.c
+++ b/generic/tclIOCmd.c
@@ -174,12 +174,14 @@ Tcl_PutsObjCmd(
if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
return TCL_ERROR;
}
- if ((mode & TCL_WRITABLE) == 0) {
- Tcl_AppendResult(interp, "channel \"", TclGetString(chanObjPtr),
- "\" wasn't opened for writing", NULL);
+ if (!(mode & TCL_WRITABLE)) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "channel \"%s\" wasn't opened for writing",
+ TclGetString(chanObjPtr)));
return TCL_ERROR;
}
+ Tcl_Preserve(chan);
result = Tcl_WriteObj(chan, string);
if (result < 0) {
goto error;
@@ -190,6 +192,7 @@ Tcl_PutsObjCmd(
goto error;
}
}
+ Tcl_Release(chan);
return TCL_OK;
/*
@@ -201,9 +204,10 @@ Tcl_PutsObjCmd(
error:
if (!TclChanCaughtErrorBypass(interp, chan)) {
- Tcl_AppendResult(interp, "error writing \"", TclGetString(chanObjPtr),
- "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("error writing \"%s\": %s",
+ TclGetString(chanObjPtr), Tcl_PosixError(interp)));
}
+ Tcl_Release(chan);
return TCL_ERROR;
}
@@ -244,12 +248,14 @@ Tcl_FlushObjCmd(
if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
return TCL_ERROR;
}
- if ((mode & TCL_WRITABLE) == 0) {
- Tcl_AppendResult(interp, "channel \"", TclGetString(chanObjPtr),
- "\" wasn't opened for writing", NULL);
+ if (!(mode & TCL_WRITABLE)) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "channel \"%s\" wasn't opened for writing",
+ TclGetString(chanObjPtr)));
return TCL_ERROR;
}
+ Tcl_Preserve(chan);
if (Tcl_Flush(chan) != TCL_OK) {
/*
* TIP #219.
@@ -259,12 +265,14 @@ Tcl_FlushObjCmd(
*/
if (!TclChanCaughtErrorBypass(interp, chan)) {
- Tcl_AppendResult(interp, "error flushing \"",
- TclGetString(chanObjPtr), "\": ", Tcl_PosixError(interp),
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error flushing \"%s\": %s",
+ TclGetString(chanObjPtr), Tcl_PosixError(interp)));
}
+ Tcl_Release(chan);
return TCL_ERROR;
}
+ Tcl_Release(chan);
return TCL_OK;
}
@@ -297,6 +305,7 @@ Tcl_GetsObjCmd(
int lineLen; /* Length of line just read. */
int mode; /* Mode in which channel is opened. */
Tcl_Obj *linePtr, *chanObjPtr;
+ int code = TCL_OK;
if ((objc != 2) && (objc != 3)) {
Tcl_WrongNumArgs(interp, 1, objv, "channelId ?varName?");
@@ -306,12 +315,14 @@ Tcl_GetsObjCmd(
if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
return TCL_ERROR;
}
- if ((mode & TCL_READABLE) == 0) {
- Tcl_AppendResult(interp, "channel \"", TclGetString(chanObjPtr),
- "\" wasn't opened for reading", NULL);
+ if (!(mode & TCL_READABLE)) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "channel \"%s\" wasn't opened for reading",
+ TclGetString(chanObjPtr)));
return TCL_ERROR;
}
+ Tcl_Preserve(chan);
linePtr = Tcl_NewObj();
lineLen = Tcl_GetsObj(chan, linePtr);
if (lineLen < 0) {
@@ -326,12 +337,12 @@ Tcl_GetsObjCmd(
*/
if (!TclChanCaughtErrorBypass(interp, chan)) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "error reading \"",
- TclGetString(chanObjPtr), "\": ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error reading \"%s\": %s",
+ TclGetString(chanObjPtr), Tcl_PosixError(interp)));
}
- return TCL_ERROR;
+ code = TCL_ERROR;
+ goto done;
}
lineLen = -1;
}
@@ -344,7 +355,9 @@ Tcl_GetsObjCmd(
} else {
Tcl_SetObjResult(interp, linePtr);
}
- return TCL_OK;
+ done:
+ Tcl_Release(chan);
+ return code;
}
/*
@@ -411,9 +424,10 @@ Tcl_ReadObjCmd(
if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
return TCL_ERROR;
}
- if ((mode & TCL_READABLE) == 0) {
- Tcl_AppendResult(interp, "channel \"", TclGetString(chanObjPtr),
- "\" wasn't opened for reading", NULL);
+ if (!(mode & TCL_READABLE)) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "channel \"%s\" wasn't opened for reading",
+ TclGetString(chanObjPtr)));
return TCL_ERROR;
}
i++; /* Consumed channel name. */
@@ -436,11 +450,11 @@ Tcl_ReadObjCmd(
if (strcmp(TclGetString(objv[i]), "nonewline") != 0) {
#endif
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "expected non-negative integer but got \"",
- TclGetString(objv[i]), "\"", NULL);
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "NUMBER", NULL);
- return TCL_ERROR;
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "expected non-negative integer but got \"%s\"",
+ TclGetString(objv[i])));
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "NUMBER", NULL);
+ return TCL_ERROR;
#if TCL_MAJOR_VERSION < 9
}
newline = 1;
@@ -450,6 +464,7 @@ Tcl_ReadObjCmd(
resultPtr = Tcl_NewObj();
Tcl_IncrRefCount(resultPtr);
+ Tcl_Preserve(chan);
charactersRead = Tcl_ReadChars(chan, resultPtr, toRead, 0);
if (charactersRead < 0) {
/*
@@ -460,11 +475,11 @@ Tcl_ReadObjCmd(
*/
if (!TclChanCaughtErrorBypass(interp, chan)) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "error reading \"",
- TclGetString(chanObjPtr), "\": ", Tcl_PosixError(interp),
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error reading \"%s\": %s",
+ TclGetString(chanObjPtr), Tcl_PosixError(interp)));
}
+ Tcl_Release(chan);
Tcl_DecrRefCount(resultPtr);
return TCL_ERROR;
}
@@ -483,6 +498,7 @@ Tcl_ReadObjCmd(
}
}
Tcl_SetObjResult(interp, resultPtr);
+ Tcl_Release(chan);
Tcl_DecrRefCount(resultPtr);
return TCL_OK;
}
@@ -521,7 +537,7 @@ Tcl_SeekObjCmd(
static const char *const originOptions[] = {
"start", "current", "end", NULL
};
- static int modeArray[] = {SEEK_SET, SEEK_CUR, SEEK_END};
+ static const int modeArray[] = {SEEK_SET, SEEK_CUR, SEEK_END};
if ((objc != 3) && (objc != 4)) {
Tcl_WrongNumArgs(interp, 1, objv, "channelId offset ?origin?");
@@ -542,6 +558,7 @@ Tcl_SeekObjCmd(
mode = modeArray[optionIndex];
}
+ Tcl_Preserve(chan);
result = Tcl_Seek(chan, offset, mode);
if (result == Tcl_LongAsWide(-1)) {
/*
@@ -552,12 +569,14 @@ Tcl_SeekObjCmd(
*/
if (!TclChanCaughtErrorBypass(interp, chan)) {
- Tcl_AppendResult(interp, "error during seek on \"",
- TclGetString(objv[1]), "\": ", Tcl_PosixError(interp),
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error during seek on \"%s\": %s",
+ TclGetString(objv[1]), Tcl_PosixError(interp)));
}
+ Tcl_Release(chan);
return TCL_ERROR;
}
+ Tcl_Release(chan);
return TCL_OK;
}
@@ -588,6 +607,7 @@ Tcl_TellObjCmd(
{
Tcl_Channel chan; /* The channel to tell on. */
Tcl_WideInt newLoc;
+ int code;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "channelId");
@@ -603,6 +623,7 @@ Tcl_TellObjCmd(
return TCL_ERROR;
}
+ Tcl_Preserve(chan);
newLoc = Tcl_Tell(chan);
/*
@@ -611,7 +632,10 @@ Tcl_TellObjCmd(
* them into the regular interpreter result.
*/
- if (TclChanCaughtErrorBypass(interp, chan)) {
+
+ code = TclChanCaughtErrorBypass(interp, chan);
+ Tcl_Release(chan);
+ if (code) {
return TCL_ERROR;
}
@@ -648,7 +672,7 @@ Tcl_CloseObjCmd(
static const char *const dirOptions[] = {
"read", "write", NULL
};
- static int dirArray[] = {TCL_CLOSE_READ, TCL_CLOSE_WRITE};
+ static const int dirArray[] = {TCL_CLOSE_READ, TCL_CLOSE_WRITE};
if ((objc != 2) && (objc != 3)) {
Tcl_WrongNumArgs(interp, 1, objv, "channelId ?direction?");
@@ -679,9 +703,9 @@ Tcl_CloseObjCmd(
*/
if (!(dir & Tcl_GetChannelMode(chan))) {
- Tcl_AppendResult(interp, "Half-close of ", dirOptions[index],
- "-side not possible, side not opened or already closed",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "Half-close of %s-side not possible, side not opened"
+ " or already closed", dirOptions[index]));
return TCL_ERROR;
}
@@ -977,9 +1001,9 @@ Tcl_ExecObjCmd(
*/
if (!TclChanCaughtErrorBypass(interp, chan)) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "error reading output from command: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error reading output from command: %s",
+ Tcl_PosixError(interp)));
Tcl_DecrRefCount(resultPtr);
}
return TCL_ERROR;
@@ -1048,9 +1072,10 @@ Tcl_FblockedObjCmd(
if (TclGetChannelFromObj(interp, objv[1], &chan, &mode, 0) != TCL_OK) {
return TCL_ERROR;
}
- if ((mode & TCL_READABLE) == 0) {
- Tcl_AppendResult(interp, "channel \"", TclGetString(objv[1]),
- "\" wasn't opened for reading", NULL);
+ if (!(mode & TCL_READABLE)) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "channel \"%s\" wasn't opened for reading",
+ TclGetString(objv[1])));
return TCL_ERROR;
}
@@ -1174,7 +1199,7 @@ Tcl_OpenObjCmd(
return TCL_ERROR;
}
Tcl_RegisterChannel(interp, chan);
- Tcl_AppendResult(interp, Tcl_GetChannelName(chan), NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1));
return TCL_OK;
}
@@ -1479,8 +1504,8 @@ Tcl_SocketObjCmd(
switch ((enum socketOptions) optionIndex) {
case SKT_ASYNC:
if (server == 1) {
- Tcl_AppendResult(interp,
- "cannot set -async option for server sockets", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "cannot set -async option for server sockets", -1));
return TCL_ERROR;
}
async = 1;
@@ -1488,8 +1513,8 @@ Tcl_SocketObjCmd(
case SKT_MYADDR:
a++;
if (a >= objc) {
- Tcl_AppendResult(interp,
- "no argument given for -myaddr option", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "no argument given for -myaddr option", -1));
return TCL_ERROR;
}
myaddr = TclGetString(objv[a]);
@@ -1499,8 +1524,8 @@ Tcl_SocketObjCmd(
a++;
if (a >= objc) {
- Tcl_AppendResult(interp,
- "no argument given for -myport option", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "no argument given for -myport option", -1));
return TCL_ERROR;
}
myPortName = TclGetString(objv[a]);
@@ -1511,15 +1536,15 @@ Tcl_SocketObjCmd(
}
case SKT_SERVER:
if (async == 1) {
- Tcl_AppendResult(interp,
- "cannot set -async option for server sockets", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "cannot set -async option for server sockets", -1));
return TCL_ERROR;
}
server = 1;
a++;
if (a >= objc) {
- Tcl_AppendResult(interp,
- "no argument given for -server option", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "no argument given for -server option", -1));
return TCL_ERROR;
}
script = TclGetString(objv[a]);
@@ -1531,8 +1556,8 @@ Tcl_SocketObjCmd(
if (server) {
host = myaddr; /* NULL implies INADDR_ANY */
if (myport != 0) {
- Tcl_AppendResult(interp, "option -myport is not valid for servers",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "option -myport is not valid for servers", -1));
return TCL_ERROR;
}
} else if (a < objc) {
@@ -1599,9 +1624,9 @@ Tcl_SocketObjCmd(
return TCL_ERROR;
}
}
- Tcl_RegisterChannel(interp, chan);
- Tcl_AppendResult(interp, Tcl_GetChannelName(chan), NULL);
+ Tcl_RegisterChannel(interp, chan);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1));
return TCL_OK;
}
@@ -1651,17 +1676,19 @@ Tcl_FcopyObjCmd(
if (TclGetChannelFromObj(interp, objv[1], &inChan, &mode, 0) != TCL_OK) {
return TCL_ERROR;
}
- if ((mode & TCL_READABLE) == 0) {
- Tcl_AppendResult(interp, "channel \"", TclGetString(objv[1]),
- "\" wasn't opened for reading", NULL);
+ if (!(mode & TCL_READABLE)) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "channel \"%s\" wasn't opened for reading",
+ TclGetString(objv[1])));
return TCL_ERROR;
}
if (TclGetChannelFromObj(interp, objv[2], &outChan, &mode, 0) != TCL_OK) {
return TCL_ERROR;
}
- if ((mode & TCL_WRITABLE) == 0) {
- Tcl_AppendResult(interp, "channel \"", TclGetString(objv[2]),
- "\" wasn't opened for writing", NULL);
+ if (!(mode & TCL_WRITABLE)) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "channel \"%s\" wasn't opened for writing",
+ TclGetString(objv[2])));
return TCL_ERROR;
}
@@ -1745,14 +1772,14 @@ ChanPendingObjCmd(
switch ((enum options) index) {
case PENDING_INPUT:
- if ((mode & TCL_READABLE) == 0) {
+ if (!(mode & TCL_READABLE)) {
Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
} else {
Tcl_SetObjResult(interp, Tcl_NewIntObj(Tcl_InputBuffered(chan)));
}
break;
case PENDING_OUTPUT:
- if ((mode & TCL_WRITABLE) == 0) {
+ if (!(mode & TCL_WRITABLE)) {
Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
} else {
Tcl_SetObjResult(interp, Tcl_NewIntObj(Tcl_OutputBuffered(chan)));
@@ -1806,8 +1833,8 @@ ChanTruncateObjCmd(
return TCL_ERROR;
}
if (length < 0) {
- Tcl_AppendResult(interp,
- "cannot truncate to negative length of file", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "cannot truncate to negative length of file", -1));
return TCL_ERROR;
}
} else {
@@ -1817,18 +1844,17 @@ ChanTruncateObjCmd(
length = Tcl_Tell(chan);
if (length == Tcl_WideAsLong(-1)) {
- Tcl_AppendResult(interp,
- "could not determine current location in \"",
- TclGetString(objv[1]), "\": ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not determine current location in \"%s\": %s",
+ TclGetString(objv[1]), Tcl_PosixError(interp)));
return TCL_ERROR;
}
}
if (Tcl_TruncateChannel(chan, length) != TCL_OK) {
- Tcl_AppendResult(interp, "error during truncate on \"",
- TclGetString(objv[1]), "\": ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error during truncate on \"%s\": %s",
+ TclGetString(objv[1]), Tcl_PosixError(interp)));
return TCL_ERROR;
}
@@ -1948,25 +1974,25 @@ TclInitChanCmd(
* function at the moment.
*/
static const EnsembleImplMap initMap[] = {
- {"blocked", Tcl_FblockedObjCmd, NULL, NULL, NULL, 0},
- {"close", Tcl_CloseObjCmd, NULL, NULL, NULL, 0},
- {"copy", Tcl_FcopyObjCmd, NULL, NULL, NULL, 0},
- {"create", TclChanCreateObjCmd, NULL, NULL, NULL, 0}, /* TIP #219 */
- {"eof", Tcl_EofObjCmd, NULL, NULL, NULL, 0},
- {"event", Tcl_FileEventObjCmd, NULL, NULL, NULL, 0},
- {"flush", Tcl_FlushObjCmd, NULL, NULL, NULL, 0},
- {"gets", Tcl_GetsObjCmd, NULL, NULL, NULL, 0},
- {"names", TclChannelNamesCmd, NULL, NULL, NULL, 0},
- {"pending", ChanPendingObjCmd, NULL, NULL, NULL, 0}, /* TIP #287 */
- {"pop", TclChanPopObjCmd, NULL, NULL, NULL, 0}, /* TIP #230 */
- {"postevent", TclChanPostEventObjCmd, NULL, NULL, NULL, 0}, /* TIP #219 */
- {"push", TclChanPushObjCmd, NULL, NULL, NULL, 0}, /* TIP #230 */
- {"puts", Tcl_PutsObjCmd, NULL, NULL, NULL, 0},
- {"read", Tcl_ReadObjCmd, NULL, NULL, NULL, 0},
- {"seek", Tcl_SeekObjCmd, NULL, NULL, NULL, 0},
- {"pipe", ChanPipeObjCmd, NULL, NULL, NULL, 0}, /* TIP #304 */
- {"tell", Tcl_TellObjCmd, NULL, NULL, NULL, 0},
- {"truncate", ChanTruncateObjCmd, NULL, NULL, NULL, 0}, /* TIP #208 */
+ {"blocked", Tcl_FblockedObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"close", Tcl_CloseObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+ {"copy", Tcl_FcopyObjCmd, NULL, NULL, NULL, 0},
+ {"create", TclChanCreateObjCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, /* TIP #219 */
+ {"eof", Tcl_EofObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"event", Tcl_FileEventObjCmd, TclCompileBasic2Or3ArgCmd, NULL, NULL, 0},
+ {"flush", Tcl_FlushObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"gets", Tcl_GetsObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+ {"names", TclChannelNamesCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+ {"pending", ChanPendingObjCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, /* TIP #287 */
+ {"pipe", ChanPipeObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, /* TIP #304 */
+ {"pop", TclChanPopObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, /* TIP #230 */
+ {"postevent", TclChanPostEventObjCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, /* TIP #219 */
+ {"push", TclChanPushObjCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, /* TIP #230 */
+ {"puts", Tcl_PutsObjCmd, NULL, NULL, NULL, 0},
+ {"read", Tcl_ReadObjCmd, NULL, NULL, NULL, 0},
+ {"seek", Tcl_SeekObjCmd, TclCompileBasic2Or3ArgCmd, NULL, NULL, 0},
+ {"tell", Tcl_TellObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"truncate", ChanTruncateObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, /* TIP #208 */
{NULL, NULL, NULL, NULL, NULL, 0}
};
static const char *const extras[] = {
diff --git a/generic/tclIOGT.c b/generic/tclIOGT.c
index 6f80c25..29996ea 100644
--- a/generic/tclIOGT.c
+++ b/generic/tclIOGT.c
@@ -210,7 +210,27 @@ struct TransformChannelData {
* a transformation of incoming data. Also
* serves as buffer of all data not yet
* consumed by the reader. */
+ int refCount;
};
+
+static void
+PreserveData(
+ TransformChannelData *dataPtr)
+{
+ dataPtr->refCount++;
+}
+
+static void
+ReleaseData(
+ TransformChannelData *dataPtr)
+{
+ if (--dataPtr->refCount) {
+ return;
+ }
+ ResultClear(&dataPtr->result);
+ Tcl_DecrRefCount(dataPtr->command);
+ ckfree(dataPtr);
+}
/*
*----------------------------------------------------------------------
@@ -240,6 +260,7 @@ TclChannelTransform(
Channel *chanPtr; /* The actual channel. */
ChannelState *statePtr; /* State info for channel. */
int mode; /* Read/write mode of the channel. */
+ int objc;
TransformChannelData *dataPtr;
Tcl_DString ds;
@@ -247,6 +268,12 @@ TclChannelTransform(
return TCL_ERROR;
}
+ if (TCL_OK != Tcl_ListObjLength(interp, cmdObjPtr, &objc)) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj("-command value is not a list", -1));
+ return TCL_ERROR;
+ }
+
chanPtr = (Channel *) chan;
statePtr = chanPtr->state;
chanPtr = statePtr->topChanPtr;
@@ -261,6 +288,7 @@ TclChannelTransform(
dataPtr = ckalloc(sizeof(TransformChannelData));
+ dataPtr->refCount = 1;
Tcl_DStringInit(&ds);
Tcl_GetChannelOption(interp, chan, "-blocking", &ds);
dataPtr->readIsFlushed = 0;
@@ -284,11 +312,9 @@ TclChannelTransform(
dataPtr->self = Tcl_StackChannel(interp, &transformChannelType, dataPtr,
mode, chan);
if (dataPtr->self == NULL) {
- Tcl_AppendResult(interp, "\nfailed to stack channel \"",
- Tcl_GetChannelName(chan), "\"", NULL);
- Tcl_DecrRefCount(dataPtr->command);
- ResultClear(&dataPtr->result);
- ckfree(dataPtr);
+ Tcl_AppendPrintfToObj(Tcl_GetObjResult(interp),
+ "\nfailed to stack channel \"%s\"", Tcl_GetChannelName(chan));
+ ReleaseData(dataPtr);
return TCL_ERROR;
}
@@ -296,9 +322,11 @@ TclChannelTransform(
* At last initialize the transformation at the script level.
*/
+ PreserveData(dataPtr);
if ((dataPtr->mode & TCL_WRITABLE) && ExecuteCallback(dataPtr, NULL,
A_CREATE_WRITE, NULL, 0, TRANSMIT_DONT, P_NO_PRESERVE) != TCL_OK){
Tcl_UnstackChannel(interp, chan);
+ ReleaseData(dataPtr);
return TCL_ERROR;
}
@@ -307,9 +335,11 @@ TclChannelTransform(
ExecuteCallback(dataPtr, NULL, A_DELETE_WRITE, NULL, 0, TRANSMIT_DONT,
P_NO_PRESERVE);
Tcl_UnstackChannel(interp, chan);
+ ReleaseData(dataPtr);
return TCL_ERROR;
}
+ ReleaseData(dataPtr);
return TCL_OK;
}
@@ -350,7 +380,10 @@ ExecuteCallback(
unsigned char *resBuf;
Tcl_InterpState state = NULL;
int res = TCL_OK;
- Tcl_Obj *command = Tcl_DuplicateObj(dataPtr->command);
+ Tcl_Obj *command = TclListObjCopy(NULL, dataPtr->command);
+ Tcl_Interp *eval = dataPtr->interp;
+
+ Tcl_Preserve(eval);
/*
* Step 1, create the complete command to execute. Do this by appending
@@ -361,26 +394,18 @@ ExecuteCallback(
*/
if (preserve == P_PRESERVE) {
- state = Tcl_SaveInterpState(dataPtr->interp, res);
+ state = Tcl_SaveInterpState(eval, res);
}
Tcl_IncrRefCount(command);
- res = Tcl_ListObjAppendElement(dataPtr->interp, command,
- Tcl_NewStringObj((char *) op, -1));
- if (res != TCL_OK) {
- goto cleanup;
- }
+ Tcl_ListObjAppendElement(NULL, command, Tcl_NewStringObj((char *) op, -1));
/*
* Use a byte-array to prevent the misinterpretation of binary data coming
* through as UTF while at the tcl level.
*/
- res = Tcl_ListObjAppendElement(dataPtr->interp, command,
- Tcl_NewByteArrayObj(buf, bufLen));
- if (res != TCL_OK) {
- goto cleanup;
- }
+ Tcl_ListObjAppendElement(NULL, command, Tcl_NewByteArrayObj(buf, bufLen));
/*
* Step 2, execute the command at the global level of the interpreter used
@@ -390,13 +415,14 @@ ExecuteCallback(
* current interpreter. Don't copy if in preservation mode.
*/
- res = Tcl_EvalObjEx(dataPtr->interp, command, TCL_EVAL_GLOBAL);
+ res = Tcl_EvalObjEx(eval, command, TCL_EVAL_GLOBAL);
Tcl_DecrRefCount(command);
command = NULL;
- if ((res != TCL_OK) && (interp != NULL) && (dataPtr->interp != interp)
+ if ((res != TCL_OK) && (interp != NULL) && (eval != interp)
&& (preserve == P_NO_PRESERVE)) {
- Tcl_SetObjResult(interp, Tcl_GetObjResult(dataPtr->interp));
+ Tcl_SetObjResult(interp, Tcl_GetObjResult(eval));
+ Tcl_Release(eval);
return res;
}
@@ -411,20 +437,20 @@ ExecuteCallback(
break;
case TRANSMIT_DOWN:
- resObj = Tcl_GetObjResult(dataPtr->interp);
+ resObj = Tcl_GetObjResult(eval);
resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
Tcl_WriteRaw(Tcl_GetStackedChannel(dataPtr->self), (char *) resBuf,
resLen);
break;
case TRANSMIT_SELF:
- resObj = Tcl_GetObjResult(dataPtr->interp);
+ resObj = Tcl_GetObjResult(eval);
resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
Tcl_WriteRaw(dataPtr->self, (char *) resBuf, resLen);
break;
case TRANSMIT_IBUF:
- resObj = Tcl_GetObjResult(dataPtr->interp);
+ resObj = Tcl_GetObjResult(eval);
resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
ResultAdd(&dataPtr->result, resBuf, resLen);
break;
@@ -434,24 +460,16 @@ ExecuteCallback(
* Interpret result as integer number.
*/
- resObj = Tcl_GetObjResult(dataPtr->interp);
- TclGetIntFromObj(dataPtr->interp, resObj, &dataPtr->maxRead);
+ resObj = Tcl_GetObjResult(eval);
+ TclGetIntFromObj(eval, resObj, &dataPtr->maxRead);
break;
}
- Tcl_ResetResult(dataPtr->interp);
- if (preserve == P_PRESERVE) {
- (void) Tcl_RestoreInterpState(dataPtr->interp, state);
- }
- return res;
-
- cleanup:
+ Tcl_ResetResult(eval);
if (preserve == P_PRESERVE) {
- (void) Tcl_RestoreInterpState(dataPtr->interp, state);
- }
- if (command != NULL) {
- Tcl_DecrRefCount(command);
+ (void) Tcl_RestoreInterpState(eval, state);
}
+ Tcl_Release(eval);
return res;
}
@@ -535,6 +553,7 @@ TransformCloseProc(
* system rely on (f.e. signaling the close to interested parties).
*/
+ PreserveData(dataPtr);
if (dataPtr->mode & TCL_WRITABLE) {
ExecuteCallback(dataPtr, interp, A_FLUSH_WRITE, NULL, 0,
TRANSMIT_DOWN, P_PRESERVE);
@@ -554,14 +573,13 @@ TransformCloseProc(
ExecuteCallback(dataPtr, interp, A_DELETE_READ, NULL, 0,
TRANSMIT_DONT, P_PRESERVE);
}
+ ReleaseData(dataPtr);
/*
* General cleanup.
*/
- ResultClear(&dataPtr->result);
- Tcl_DecrRefCount(dataPtr->command);
- ckfree(dataPtr);
+ ReleaseData(dataPtr);
return TCL_OK;
}
@@ -606,6 +624,7 @@ TransformInputProc(
gotBytes = 0;
downChan = Tcl_GetStackedChannel(dataPtr->self);
+ PreserveData(dataPtr);
while (toRead > 0) {
/*
* Loop until the request is satisfied (or no data is available from
@@ -623,7 +642,7 @@ TransformInputProc(
* break out of the loop and return to the caller.
*/
- return gotBytes;
+ break;
}
/*
@@ -647,7 +666,7 @@ TransformInputProc(
}
} /* else: 'maxRead < 0' == Accept the current value of toRead. */
if (toRead <= 0) {
- return gotBytes;
+ break;
}
/*
@@ -661,13 +680,15 @@ TransformInputProc(
* had some data before we report that instead of the request to
* re-try.
*/
+ int error = Tcl_GetErrno();
- if ((Tcl_GetErrno() == EAGAIN) && (gotBytes > 0)) {
- return gotBytes;
+ if ((error == EAGAIN) && (gotBytes > 0)) {
+ break;
}
- *errorCodePtr = Tcl_GetErrno();
- return -1;
+ *errorCodePtr = error;
+ gotBytes = -1;
+ break;
} else if (read == 0) {
/*
* Check wether we hit on EOF in the underlying channel or not. If
@@ -682,9 +703,9 @@ TransformInputProc(
if (!Tcl_Eof(downChan)) {
if ((gotBytes == 0) && (dataPtr->flags & CHANNEL_ASYNC)) {
*errorCodePtr = EWOULDBLOCK;
- return -1;
+ gotBytes = -1;
}
- return gotBytes;
+ break;
}
if (dataPtr->readIsFlushed) {
@@ -692,7 +713,7 @@ TransformInputProc(
* Already flushed, nothing to do anymore.
*/
- return gotBytes;
+ break;
}
dataPtr->readIsFlushed = 1;
@@ -704,7 +725,7 @@ TransformInputProc(
* We had nothing to flush.
*/
- return gotBytes;
+ break;
}
continue; /* at: while (toRead > 0) */
@@ -718,9 +739,11 @@ TransformInputProc(
if (ExecuteCallback(dataPtr, NULL, A_READ, UCHARP(buf), read,
TRANSMIT_IBUF, P_PRESERVE) != TCL_OK) {
*errorCodePtr = EINVAL;
- return -1;
+ gotBytes = -1;
+ break;
}
} /* while toRead > 0 */
+ ReleaseData(dataPtr);
return gotBytes;
}
@@ -762,11 +785,13 @@ TransformOutputProc(
return 0;
}
+ PreserveData(dataPtr);
if (ExecuteCallback(dataPtr, NULL, A_WRITE, UCHARP(buf), toWrite,
TRANSMIT_DOWN, P_NO_PRESERVE) != TCL_OK) {
*errorCodePtr = EINVAL;
- return -1;
+ toWrite = -1;
}
+ ReleaseData(dataPtr);
return toWrite;
}
@@ -819,6 +844,7 @@ TransformSeekProc(
* request down, unchanged.
*/
+ PreserveData(dataPtr);
if (dataPtr->mode & TCL_WRITABLE) {
ExecuteCallback(dataPtr, NULL, A_FLUSH_WRITE, NULL, 0, TRANSMIT_DOWN,
P_NO_PRESERVE);
@@ -830,6 +856,7 @@ TransformSeekProc(
ResultClear(&dataPtr->result);
dataPtr->readIsFlushed = 0;
}
+ ReleaseData(dataPtr);
return parentSeekProc(Tcl_GetChannelInstanceData(parent), offset, mode,
errorCodePtr);
@@ -890,6 +917,7 @@ TransformWideSeekProc(
* request down, unchanged.
*/
+ PreserveData(dataPtr);
if (dataPtr->mode & TCL_WRITABLE) {
ExecuteCallback(dataPtr, NULL, A_FLUSH_WRITE, NULL, 0, TRANSMIT_DOWN,
P_NO_PRESERVE);
@@ -901,6 +929,7 @@ TransformWideSeekProc(
ResultClear(&dataPtr->result);
dataPtr->readIsFlushed = 0;
}
+ ReleaseData(dataPtr);
/*
* If we have a wide seek capability, we should stick with that.
diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c
index 9ba42ef..94428bb 100644
--- a/generic/tclIORChan.c
+++ b/generic/tclIORChan.c
@@ -39,6 +39,9 @@ static int ReflectOutput(ClientData clientData, const char *buf,
int toWrite, int *errorCodePtr);
static void ReflectWatch(ClientData clientData, int mask);
static int ReflectBlock(ClientData clientData, int mode);
+#ifdef TCL_THREADS
+static void ReflectThread(ClientData clientData, int action);
+#endif
static Tcl_WideInt ReflectSeekWide(ClientData clientData,
Tcl_WideInt offset, int mode, int *errorCodePtr);
static int ReflectSeek(ClientData clientData, long offset,
@@ -71,7 +74,11 @@ static const Tcl_ChannelType tclRChannelType = {
NULL, /* Flush channel. Not used by core. NULL'able */
NULL, /* Handle events. NULL'able */
ReflectSeekWide, /* Move access point (64 bit). NULL'able */
+#ifdef TCL_THREADS
+ ReflectThread, /* thread action, tracking owner */
+#else
NULL, /* thread action */
+#endif
NULL /* truncate */
};
@@ -89,38 +96,20 @@ typedef struct {
* command is gone.
*/
#ifdef TCL_THREADS
- Tcl_ThreadId thread; /* Thread the 'interp' belongs to. */
+ Tcl_ThreadId thread; /* Thread the 'interp' belongs to. == Handler thread */
+ Tcl_ThreadId owner; /* Thread owning the structure. == Channel thread */
#endif
-
- /* See [==] as well.
- * Storage for the command prefix and the additional words required for
- * the invocation of methods in the command handler.
- *
- * argv [0] ... [.] | [argc-2] [argc-1] | [argc] [argc+2]
- * cmd ... pfx | method chan | detail1 detail2
- * ~~~~ CT ~~~ ~~ CT ~~
- *
- * CT = Belongs to the 'Command handler Thread'.
- */
-
- int argc; /* Number of preallocated words - 2 */
- Tcl_Obj **argv; /* Preallocated array for calling the handler.
- * args[0] is placeholder for cmd word.
- * Followed by the arguments in the prefix,
- * plus 4 placeholders for method, channel,
- * and at most two varying (method specific)
- * words. */
- int methods; /* Bitmask of supported methods */
-
- /*
- * NOTE (9): Should we have predefined shared literals for the method
- * names?
- */
+ Tcl_Obj *cmd; /* Callback command prefix */
+ Tcl_Obj *methods; /* Methods to append to command prefix */
+ Tcl_Obj *name; /* Name of the channel as created */
int mode; /* Mask of R/W mode */
int interest; /* Mask of events the channel is interested
* in. */
+ int dead; /* Boolean signal that some operations
+ * should no longer be attempted. */
+
/*
* Note regarding the usage of timers.
*
@@ -387,31 +376,31 @@ TCL_DECLARE_MUTEX(rcForwardMutex)
* leak resources when threads go away.
*/
-static void ForwardOpToOwnerThread(ReflectedChannel *rcPtr,
+static void ForwardOpToHandlerThread(ReflectedChannel *rcPtr,
ForwardedOperation op, const void *param);
static int ForwardProc(Tcl_Event *evPtr, int mask);
static void SrcExitProc(ClientData clientData);
#define FreeReceivedError(p) \
- if ((p)->base.mustFree) { \
- ckfree((p)->base.msgStr); \
+ if ((p)->base.mustFree) { \
+ ckfree((p)->base.msgStr); \
}
#define PassReceivedErrorInterp(i,p) \
- if ((i) != NULL) { \
- Tcl_SetChannelErrorInterp((i), \
- Tcl_NewStringObj((p)->base.msgStr, -1)); \
- } \
+ if ((i) != NULL) { \
+ Tcl_SetChannelErrorInterp((i), \
+ Tcl_NewStringObj((p)->base.msgStr, -1)); \
+ } \
FreeReceivedError(p)
#define PassReceivedError(c,p) \
Tcl_SetChannelError((c), Tcl_NewStringObj((p)->base.msgStr, -1)); \
FreeReceivedError(p)
#define ForwardSetStaticError(p,emsg) \
- (p)->base.code = TCL_ERROR; \
- (p)->base.mustFree = 0; \
+ (p)->base.code = TCL_ERROR; \
+ (p)->base.mustFree = 0; \
(p)->base.msgStr = (char *) (emsg)
#define ForwardSetDynamicError(p,emsg) \
- (p)->base.code = TCL_ERROR; \
- (p)->base.mustFree = 1; \
+ (p)->base.code = TCL_ERROR; \
+ (p)->base.mustFree = 1; \
(p)->base.msgStr = (char *) (emsg)
static void ForwardSetObjError(ForwardParam *p, Tcl_Obj *objPtr);
@@ -440,7 +429,7 @@ static ReflectedChannel * NewReflectedChannel(Tcl_Interp *interp,
static Tcl_Obj * NextHandle(void);
static void FreeReflectedChannel(ReflectedChannel *rcPtr);
static int InvokeTclMethod(ReflectedChannel *rcPtr,
- const char *method, Tcl_Obj *argOneObj,
+ MethodName method, Tcl_Obj *argOneObj,
Tcl_Obj *argTwoObj, Tcl_Obj **resultObjPtr);
static ReflectedChannelMap * GetReflectedChannelMap(Tcl_Interp *interp);
@@ -455,9 +444,7 @@ static int ErrnoReturn(ReflectedChannel *rcPtr, Tcl_Obj *resObj);
* list-quoting to keep the words of the message together. See also [x].
*/
-static const char *msg_read_unsup = "{read not supported by Tcl driver}";
static const char *msg_read_toomuch = "{read delivered more than requested}";
-static const char *msg_write_unsup = "{write not supported by Tcl driver}";
static const char *msg_write_toomuch = "{write wrote more than requested}";
static const char *msg_write_nothing = "{write wrote nothing}";
static const char *msg_seek_beforestart = "{Tried to seek before origin}";
@@ -571,10 +558,6 @@ TclChanCreateObjCmd(
rcId = NextHandle();
rcPtr = NewReflectedChannel(interp, cmdObj, mode, rcId);
- chan = Tcl_CreateChannel(&tclRChannelType, TclGetString(rcId), rcPtr,
- mode);
- rcPtr->chan = chan;
- chanPtr = (Channel *) chan;
/*
* Invoke 'initialize' and validate that the handler is present and ok.
@@ -588,7 +571,7 @@ TclChanCreateObjCmd(
modeObj = DecodeEventMask(mode);
/* assert modeObj.refCount == 1 */
- result = InvokeTclMethod(rcPtr, "initialize", modeObj, NULL, &resObj);
+ result = InvokeTclMethod(rcPtr, METH_INIT, modeObj, NULL, &resObj);
Tcl_DecrRefCount(modeObj);
if (result != TCL_OK) {
@@ -671,7 +654,11 @@ TclChanCreateObjCmd(
* Everything is fine now.
*/
- rcPtr->methods = methods;
+ chan = Tcl_CreateChannel(&tclRChannelType, TclGetString(rcId), rcPtr,
+ mode);
+ rcPtr->chan = chan;
+ Tcl_Preserve(chan);
+ chanPtr = (Channel *) chan;
if ((methods & NULLABLE_METHODS) != NULLABLE_METHODS) {
/*
@@ -727,16 +714,15 @@ TclChanCreateObjCmd(
* Return handle as result of command.
*/
- Tcl_SetResult(interp, (char *)chanPtr->state->channelName, TCL_VOLATILE);
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj(chanPtr->state->channelName, -1));
return TCL_OK;
error:
- /*
- * Signal to ReflectClose to not call 'finalize'.
- */
-
- rcPtr->methods = 0;
- Tcl_Close(interp, chan);
+ Tcl_DecrRefCount(rcPtr->name);
+ Tcl_DecrRefCount(rcPtr->methods);
+ Tcl_DecrRefCount(rcPtr->cmd);
+ ckfree((char*) rcPtr);
return TCL_ERROR;
#undef MODE
@@ -761,6 +747,50 @@ TclChanCreateObjCmd(
*----------------------------------------------------------------------
*/
+typedef struct ReflectEvent {
+ Tcl_Event header;
+ ReflectedChannel *rcPtr;
+ int events;
+} ReflectEvent;
+
+static int
+ReflectEventRun(
+ Tcl_Event *ev,
+ int flags)
+{
+ /* OWNER thread
+ *
+ * Note: When the channel is closed any pending events of this type are
+ * deleted. See ReflectClose() for the Tcl_DeleteEvents() calls
+ * accomplishing that.
+ */
+
+ ReflectEvent *e = (ReflectEvent *) ev;
+
+ Tcl_NotifyChannel(e->rcPtr->chan, e->events);
+ return 1;
+}
+
+static int
+ReflectEventDelete(
+ Tcl_Event *ev,
+ ClientData cd)
+{
+ /* OWNER thread
+ *
+ * Invoked by DeleteThreadReflectedChannelMap() and ReflectClose(). The
+ * latter ensures that no pending events of this type are run on an
+ * invalid channel.
+ */
+
+ ReflectEvent *e = (ReflectEvent *) ev;
+
+ if ((ev->proc != ReflectEventRun) || ((cd != NULL) && (cd != e->rcPtr))) {
+ return 0;
+ }
+ return 1;
+}
+
int
TclChanPostEventObjCmd(
ClientData clientData,
@@ -769,6 +799,8 @@ TclChanPostEventObjCmd(
Tcl_Obj *const *objv)
{
/*
+ * Ensure -> HANDLER thread
+ *
* Syntax: chan postevent CHANNEL EVENTSPEC
* [0] [1] [2] [3]
*
@@ -811,8 +843,8 @@ TclChanPostEventObjCmd(
hPtr = Tcl_FindHashEntry(&rcmPtr->map, chanId);
if (hPtr == NULL) {
- Tcl_AppendResult(interp, "can not find reflected channel named \"",
- chanId, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can not find reflected channel named \"%s\"", chanId));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CHANNEL", chanId, NULL);
return TCL_ERROR;
}
@@ -869,8 +901,9 @@ TclChanPostEventObjCmd(
*/
if (events & ~rcPtr->interest) {
- Tcl_AppendResult(interp, "tried to post events channel \"", chanId,
- "\" is not interested in", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "tried to post events channel \"%s\" is not interested in",
+ chanId));
return TCL_ERROR;
}
@@ -878,7 +911,44 @@ TclChanPostEventObjCmd(
* We have the channel and the events to post.
*/
- Tcl_NotifyChannel(chan, events);
+#ifdef TCL_THREADS
+ if (rcPtr->owner == rcPtr->thread) {
+#endif
+ Tcl_NotifyChannel(chan, events);
+#ifdef TCL_THREADS
+ } else {
+ ReflectEvent *ev = ckalloc(sizeof(ReflectEvent));
+
+ ev->header.proc = ReflectEventRun;
+ ev->events = events;
+ ev->rcPtr = rcPtr;
+
+ /*
+ * We are not preserving the structure here. When the channel is
+ * closed any pending events are deleted, see ReflectClose(), and
+ * ReflectEventDelete(). Trying to preserve and later release when the
+ * event is run may generate a situation where the channel structure
+ * is deleted but not our structure, crashing in
+ * FreeReflectedChannel().
+ *
+ * Force creation of the RCM, for proper cleanup on thread teardown.
+ * The teardown of unprocessed events is currently coupled to the
+ * thread reflected channel map
+ */
+
+ (void) GetThreadReflectedChannelMap();
+
+ /* XXX Race condition !!
+ * XXX The destination thread may not exist anymore already.
+ * XXX (Delayed postevent executed after channel got removed).
+ * XXX Can we detect this ? (check the validity of the owner threadid ?)
+ * XXX Actually, in that case the channel should be dead also !
+ */
+
+ Tcl_ThreadQueueEvent(rcPtr->owner, (Tcl_Event *) ev, TCL_QUEUE_TAIL);
+ Tcl_ThreadAlert(rcPtr->owner);
+ }
+#endif
/*
* Squash interp results left by the event script.
@@ -1063,13 +1133,14 @@ ReflectClose(
if (rcPtr->thread != Tcl_GetCurrentThread()) {
ForwardParam p;
- ForwardOpToOwnerThread(rcPtr, ForwardedClose, &p);
+ ForwardOpToHandlerThread(rcPtr, ForwardedClose, &p);
result = p.base.code;
- /*
- * FreeReflectedChannel is done in the forwarded operation!, in
- * the other thread. rcPtr here is gone!
- */
+ /*
+ * Now squash the pending reflection events for this channel.
+ */
+
+ Tcl_DeleteEvents(ReflectEventDelete, rcPtr);
if (result != TCL_OK) {
FreeReceivedError(&p);
@@ -1078,19 +1149,7 @@ ReflectClose(
}
#endif
- Tcl_EventuallyFree (rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
- return EOK;
- }
-
- /*
- * -- No -- ASSERT rcPtr->methods & FLAG(METH_FINAL)
- *
- * A cleaned method mask here implies that the channel creation was
- * aborted, and "finalize" must not be called.
- */
-
- if (rcPtr->methods == 0) {
- Tcl_EventuallyFree (rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
+ Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
return EOK;
}
@@ -1102,20 +1161,21 @@ ReflectClose(
if (rcPtr->thread != Tcl_GetCurrentThread()) {
ForwardParam p;
- ForwardOpToOwnerThread(rcPtr, ForwardedClose, &p);
+ ForwardOpToHandlerThread(rcPtr, ForwardedClose, &p);
result = p.base.code;
- /*
- * FreeReflectedChannel is done in the forwarded operation!, in the
- * other thread. rcPtr here is gone!
- */
+ /*
+ * Now squash the pending reflection events for this channel.
+ */
+
+ Tcl_DeleteEvents(ReflectEventDelete, rcPtr);
if (result != TCL_OK) {
PassReceivedErrorInterp(interp, &p);
}
} else {
#endif
- result = InvokeTclMethod(rcPtr, "finalize", NULL, NULL, &resObj);
+ result = InvokeTclMethod(rcPtr, METH_FINAL, NULL, NULL, &resObj);
if ((result != TCL_OK) && (interp != NULL)) {
Tcl_SetChannelErrorInterp(interp, resObj);
}
@@ -1136,7 +1196,7 @@ ReflectClose(
* the per-interp DeleteReflectedChannelMap exit-handler.
*/
- if (rcPtr->interp) {
+ if (!rcPtr->dead) {
rcmPtr = GetReflectedChannelMap(rcPtr->interp);
hPtr = Tcl_FindHashEntry(&rcmPtr->map,
Tcl_GetChannelName(rcPtr->chan));
@@ -1153,7 +1213,7 @@ ReflectClose(
}
#endif
- Tcl_EventuallyFree (rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
+ Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
#ifdef TCL_THREADS
}
#endif
@@ -1190,18 +1250,6 @@ ReflectInput(
Tcl_Obj *resObj; /* Result data for 'read' */
/*
- * The following check can be done before thread redirection, because we
- * are reading from an item which is readonly, i.e. will never change
- * during the lifetime of the channel.
- */
-
- if (!(rcPtr->methods & FLAG(METH_READ))) {
- SetChannelErrorStr(rcPtr->chan, msg_read_unsup);
- *errorCodePtr = EINVAL;
- return -1;
- }
-
- /*
* Are we in the correct thread?
*/
@@ -1212,7 +1260,7 @@ ReflectInput(
p.input.buf = buf;
p.input.toRead = toRead;
- ForwardOpToOwnerThread(rcPtr, ForwardedInput, &p);
+ ForwardOpToHandlerThread(rcPtr, ForwardedInput, &p);
if (p.base.code != TCL_OK) {
if (p.base.code < 0) {
@@ -1239,7 +1287,7 @@ ReflectInput(
toReadObj = Tcl_NewIntObj(toRead);
Tcl_IncrRefCount(toReadObj);
- if (InvokeTclMethod(rcPtr, "read", toReadObj, NULL, &resObj)!=TCL_OK) {
+ if (InvokeTclMethod(rcPtr, METH_READ, toReadObj, NULL, &resObj)!=TCL_OK) {
int code = ErrnoReturn(rcPtr, resObj);
if (code < 0) {
@@ -1261,7 +1309,7 @@ ReflectInput(
*errorCodePtr = EOK;
if (bytec > 0) {
- memcpy(buf, bytev, (size_t)bytec);
+ memcpy(buf, bytev, (size_t) bytec);
}
stop:
@@ -1305,18 +1353,6 @@ ReflectOutput(
int written;
/*
- * The following check can be done before thread redirection, because we
- * are reading from an item which is readonly, i.e. will never change
- * during the lifetime of the channel.
- */
-
- if (!(rcPtr->methods & FLAG(METH_WRITE))) {
- SetChannelErrorStr(rcPtr->chan, msg_write_unsup);
- *errorCodePtr = EINVAL;
- return -1;
- }
-
- /*
* Are we in the correct thread?
*/
@@ -1327,7 +1363,7 @@ ReflectOutput(
p.output.buf = buf;
p.output.toWrite = toWrite;
- ForwardOpToOwnerThread(rcPtr, ForwardedOutput, &p);
+ ForwardOpToHandlerThread(rcPtr, ForwardedOutput, &p);
if (p.base.code != TCL_OK) {
if (p.base.code < 0) {
@@ -1354,7 +1390,7 @@ ReflectOutput(
bufObj = Tcl_NewByteArrayObj((unsigned char *) buf, toWrite);
Tcl_IncrRefCount(bufObj);
- if (InvokeTclMethod(rcPtr, "write", bufObj, NULL, &resObj) != TCL_OK) {
+ if (InvokeTclMethod(rcPtr, METH_WRITE, bufObj, NULL, &resObj) != TCL_OK) {
int code = ErrnoReturn(rcPtr, resObj);
if (code < 0) {
@@ -1443,7 +1479,7 @@ ReflectSeekWide(
p.seek.seekMode = seekMode;
p.seek.offset = offset;
- ForwardOpToOwnerThread(rcPtr, ForwardedSeek, &p);
+ ForwardOpToHandlerThread(rcPtr, ForwardedSeek, &p);
if (p.base.code != TCL_OK) {
PassReceivedError(rcPtr->chan, &p);
@@ -1462,12 +1498,13 @@ ReflectSeekWide(
Tcl_Preserve(rcPtr);
offObj = Tcl_NewWideIntObj(offset);
- baseObj = Tcl_NewStringObj((seekMode == SEEK_SET) ? "start" :
- ((seekMode == SEEK_CUR) ? "current" : "end"), -1);
+ baseObj = Tcl_NewStringObj(
+ (seekMode == SEEK_SET) ? "start" :
+ (seekMode == SEEK_CUR) ? "current" : "end", -1);
Tcl_IncrRefCount(offObj);
Tcl_IncrRefCount(baseObj);
- if (InvokeTclMethod(rcPtr, "seek", offObj, baseObj, &resObj)!=TCL_OK) {
+ if (InvokeTclMethod(rcPtr, METH_SEEK, offObj, baseObj, &resObj)!=TCL_OK) {
Tcl_SetChannelError(rcPtr->chan, resObj);
goto invalid;
}
@@ -1538,8 +1575,6 @@ ReflectWatch(
ReflectedChannel *rcPtr = clientData;
Tcl_Obj *maskObj;
- /* ASSERT rcPtr->methods & FLAG(METH_WATCH) */
-
/*
* We restrict the interest to what the channel can support. IOW there
* will never be write events for a channel which is not writable.
@@ -1567,7 +1602,7 @@ ReflectWatch(
ForwardParam p;
p.watch.mask = mask;
- ForwardOpToOwnerThread(rcPtr, ForwardedWatch, &p);
+ ForwardOpToHandlerThread(rcPtr, ForwardedWatch, &p);
/*
* Any failure from the forward is ignored. We have no place to put
@@ -1582,7 +1617,7 @@ ReflectWatch(
maskObj = DecodeEventMask(mask);
/* assert maskObj.refCount == 1 */
- (void) InvokeTclMethod(rcPtr, "watch", maskObj, NULL, NULL);
+ (void) InvokeTclMethod(rcPtr, METH_WATCH, maskObj, NULL, NULL);
Tcl_DecrRefCount(maskObj);
Tcl_Release(rcPtr);
@@ -1625,7 +1660,7 @@ ReflectBlock(
p.block.nonblocking = nonblocking;
- ForwardOpToOwnerThread(rcPtr, ForwardedBlock, &p);
+ ForwardOpToHandlerThread(rcPtr, ForwardedBlock, &p);
if (p.base.code != TCL_OK) {
PassReceivedError(rcPtr->chan, &p);
@@ -1641,7 +1676,7 @@ ReflectBlock(
Tcl_Preserve(rcPtr);
- if (InvokeTclMethod(rcPtr, "blocking", blockObj, NULL, &resObj)!=TCL_OK) {
+ if (InvokeTclMethod(rcPtr,METH_BLOCKING,blockObj,NULL,&resObj)!=TCL_OK) {
Tcl_SetChannelError(rcPtr->chan, resObj);
errorNum = EINVAL;
} else {
@@ -1655,6 +1690,44 @@ ReflectBlock(
return errorNum;
}
+#ifdef TCL_THREADS
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectThread --
+ *
+ * This function is invoked to tell the channel about thread movements.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Allocates memory. Arbitrary, as it calls upon a script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ReflectThread(
+ ClientData clientData,
+ int action)
+{
+ ReflectedChannel *rcPtr = clientData;
+
+ switch (action) {
+ case TCL_CHANNEL_THREAD_INSERT:
+ rcPtr->owner = Tcl_GetCurrentThread();
+ break;
+ case TCL_CHANNEL_THREAD_REMOVE:
+ rcPtr->owner = NULL;
+ break;
+ default:
+ Tcl_Panic("Unknown thread action code.");
+ break;
+ }
+}
+
+#endif
/*
*----------------------------------------------------------------------
*
@@ -1694,7 +1767,7 @@ ReflectSetOption(
p.setOpt.name = optionName;
p.setOpt.value = newValue;
- ForwardOpToOwnerThread(rcPtr, ForwardedSetOpt, &p);
+ ForwardOpToHandlerThread(rcPtr, ForwardedSetOpt, &p);
if (p.base.code != TCL_OK) {
Tcl_Obj *err = Tcl_NewStringObj(p.base.msgStr, -1);
@@ -1715,7 +1788,7 @@ ReflectSetOption(
Tcl_IncrRefCount(optionObj);
Tcl_IncrRefCount(valueObj);
- result = InvokeTclMethod(rcPtr, "configure",optionObj,valueObj, &resObj);
+ result = InvokeTclMethod(rcPtr, METH_CONFIGURE,optionObj,valueObj, &resObj);
if (result != TCL_OK) {
UnmarshallErrorResult(interp, resObj);
}
@@ -1760,7 +1833,7 @@ ReflectGetOption(
Tcl_Obj *resObj; /* Result data for 'configure' */
int listc, result = TCL_OK;
Tcl_Obj **listv;
- const char *method;
+ MethodName method;
/*
* Are we in the correct thread?
@@ -1780,7 +1853,7 @@ ReflectGetOption(
opcode = ForwardedGetOpt;
}
- ForwardOpToOwnerThread(rcPtr, opcode, &p);
+ ForwardOpToHandlerThread(rcPtr, opcode, &p);
if (p.base.code != TCL_OK) {
Tcl_Obj *err = Tcl_NewStringObj(p.base.msgStr, -1);
@@ -1799,14 +1872,14 @@ ReflectGetOption(
* Retrieve all options.
*/
- method = "cgetall";
+ method = METH_CGETALL;
optionObj = NULL;
} else {
/*
* Retrieve the value of one option.
*/
- method = "cget";
+ method = METH_CGET;
optionObj = Tcl_NewStringObj(optionName, -1);
Tcl_IncrRefCount(optionObj);
}
@@ -1824,7 +1897,7 @@ ReflectGetOption(
*/
if (optionObj != NULL) {
- Tcl_DStringAppend(dsPtr, TclGetString(resObj), -1);
+ TclDStringAppendObj(dsPtr, resObj);
goto ok;
}
@@ -1859,7 +1932,7 @@ ReflectGetOption(
const char *str = Tcl_GetStringFromObj(resObj, &len);
if (len) {
- Tcl_DStringAppend(dsPtr, " ", 1);
+ TclDStringAppendLiteral(dsPtr, " ");
Tcl_DStringAppend(dsPtr, str, len);
}
goto ok;
@@ -1923,7 +1996,8 @@ EncodeEventMask(
}
if (listc < 1) {
- Tcl_AppendResult(interp, "bad ", objName, " list: is empty", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad %s list: is empty", objName));
return TCL_ERROR;
}
@@ -2019,71 +2093,32 @@ NewReflectedChannel(
Tcl_Obj *handleObj)
{
ReflectedChannel *rcPtr;
- int i, listc;
- Tcl_Obj **listv;
+ MethodName mn = METH_BLOCKING;
rcPtr = ckalloc(sizeof(ReflectedChannel));
/* rcPtr->chan: Assigned by caller. Dummy data here. */
- /* rcPtr->methods: Assigned by caller. Dummy data here. */
rcPtr->chan = NULL;
- rcPtr->methods = 0;
rcPtr->interp = interp;
+ rcPtr->dead = 0;
#ifdef TCL_THREADS
rcPtr->thread = Tcl_GetCurrentThread();
#endif
rcPtr->mode = mode;
rcPtr->interest = 0; /* Initially no interest registered */
- /*
- * Method placeholder.
- */
-
/* ASSERT: cmdpfxObj is a Tcl List */
-
- Tcl_ListObjGetElements(interp, cmdpfxObj, &listc, &listv);
-
- /*
- * See [==] as well.
- * Storage for the command prefix and the additional words required for
- * the invocation of methods in the command handler.
- *
- * listv [0] [listc-1] | [listc] [listc+1] |
- * argv [0] ... [.] | [argc-2] [argc-1] | [argc] [argc+2]
- * cmd ... pfx | method chan | detail1 detail2
- */
-
- rcPtr->argc = listc + 2;
- rcPtr->argv = ckalloc(sizeof(Tcl_Obj *) * (listc+4));
-
- /*
- * Duplicate object references.
- */
-
- for (i=0; i<listc ; i++) {
- Tcl_Obj *word = rcPtr->argv[i] = listv[i];
-
- Tcl_IncrRefCount(word);
- }
-
- i++; /* Skip placeholder for method */
-
- /*
- * [Bug 1667990]: See [x] in FreeReflectedChannel for release
- */
-
- rcPtr->argv[i] = handleObj;
- Tcl_IncrRefCount(handleObj);
-
- /*
- * The next two objects are kept empty, varying arguments.
- */
-
- /*
- * Initialization complete.
- */
-
+ rcPtr->cmd = TclListObjCopy(NULL, cmdpfxObj);
+ Tcl_IncrRefCount(rcPtr->cmd);
+ rcPtr->methods = Tcl_NewListObj(METH_WRITE + 1, NULL);
+ while (mn <= METH_WRITE) {
+ Tcl_ListObjAppendElement(NULL, rcPtr->methods,
+ Tcl_NewStringObj(methodNames[mn++], -1));
+ }
+ Tcl_IncrRefCount(rcPtr->methods);
+ rcPtr->name = handleObj;
+ Tcl_IncrRefCount(rcPtr->name);
return rcPtr;
}
@@ -2134,7 +2169,6 @@ FreeReflectedChannel(
ReflectedChannel *rcPtr)
{
Channel *chanPtr = (Channel *) rcPtr->chan;
- int i, n;
if (chanPtr->typePtr != &tclRChannelType) {
/*
@@ -2142,20 +2176,12 @@ FreeReflectedChannel(
*/
ckfree(chanPtr->typePtr);
+ chanPtr->typePtr = NULL;
}
-
- n = rcPtr->argc - 2;
- for (i=0; i<n; i++) {
- Tcl_DecrRefCount(rcPtr->argv[i]);
- }
-
- /*
- * [Bug 1667990]: See [x] in NewReflectedChannel for lock. n+1 = argc-1.
- */
-
- Tcl_DecrRefCount(rcPtr->argv[n+1]);
-
- ckfree(rcPtr->argv);
+ Tcl_Release(chanPtr);
+ Tcl_DecrRefCount(rcPtr->name);
+ Tcl_DecrRefCount(rcPtr->methods);
+ Tcl_DecrRefCount(rcPtr->cmd);
ckfree(rcPtr);
}
@@ -2186,18 +2212,18 @@ FreeReflectedChannel(
static int
InvokeTclMethod(
ReflectedChannel *rcPtr,
- const char *method,
+ MethodName method,
Tcl_Obj *argOneObj, /* NULL'able */
Tcl_Obj *argTwoObj, /* NULL'able */
Tcl_Obj **resultObjPtr) /* NULL'able */
{
- int cmdc; /* #words in constructed command */
Tcl_Obj *methObj = NULL; /* Method name in object form */
Tcl_InterpState sr; /* State of handler interp */
int result; /* Result code of method invokation */
Tcl_Obj *resObj = NULL; /* Result of method invokation. */
+ Tcl_Obj *cmd;
- if (!rcPtr->interp) {
+ if (rcPtr->dead) {
/*
* The channel is marked as dead. Bail out immediately, with an
* appropriate error.
@@ -2218,19 +2244,15 @@ InvokeTclMethod(
}
/*
- * NOTE (5): Decide impl. issue: Cache objects with method names? Needs
- * TSD data as reflections can be created in many different threads.
- * NO: Caching of command resolutions means storage per channel.
- */
-
- /*
- * Insert method into the pre-allocated area, after the command prefix,
+ * Insert method into the callback command, after the command prefix,
* before the channel id.
*/
- methObj = Tcl_NewStringObj(method, -1);
- Tcl_IncrRefCount(methObj);
- rcPtr->argv[rcPtr->argc - 2] = methObj;
+ cmd = TclListObjCopy(NULL, rcPtr->cmd);
+
+ Tcl_ListObjIndex(NULL, rcPtr->methods, method, &methObj);
+ Tcl_ListObjAppendElement(NULL, cmd, methObj);
+ Tcl_ListObjAppendElement(NULL, cmd, rcPtr->name);
/*
* Append the additional argument containing method specific details
@@ -2240,13 +2262,10 @@ InvokeTclMethod(
* The objects will survive the Tcl_EvalObjv without change.
*/
- cmdc = rcPtr->argc;
if (argOneObj) {
- rcPtr->argv[cmdc] = argOneObj;
- cmdc++;
+ Tcl_ListObjAppendElement(NULL, cmd, argOneObj);
if (argTwoObj) {
- rcPtr->argv[cmdc] = argTwoObj;
- cmdc++;
+ Tcl_ListObjAppendElement(NULL, cmd, argTwoObj);
}
}
@@ -2255,9 +2274,10 @@ InvokeTclMethod(
* existing state intact.
*/
+ Tcl_IncrRefCount(cmd);
sr = Tcl_SaveInterpState(rcPtr->interp, 0 /* Dummy */);
Tcl_Preserve(rcPtr->interp);
- result = Tcl_EvalObjv(rcPtr->interp, cmdc, rcPtr->argv, TCL_EVAL_GLOBAL);
+ result = Tcl_EvalObjEx(rcPtr->interp, cmd, TCL_EVAL_GLOBAL);
/*
* We do not try to extract the result information if the caller has no
@@ -2283,7 +2303,6 @@ InvokeTclMethod(
*/
if (result != TCL_ERROR) {
- Tcl_Obj *cmd = Tcl_NewListObj(cmdc, rcPtr->argv);
int cmdLen;
const char *cmdString = Tcl_GetStringFromObj(cmd, &cmdLen);
@@ -2297,25 +2316,17 @@ InvokeTclMethod(
result = TCL_ERROR;
}
Tcl_AppendObjToErrorInfo(rcPtr->interp, Tcl_ObjPrintf(
- "\n (chan handler subcommand \"%s\")", method));
+ "\n (chan handler subcommand \"%s\")",
+ methodNames[method]));
resObj = MarshallError(rcPtr->interp);
}
Tcl_IncrRefCount(resObj);
}
+ Tcl_DecrRefCount(cmd);
Tcl_RestoreInterpState(rcPtr->interp, sr);
Tcl_Release(rcPtr->interp);
/*
- * Cleanup of the dynamic parts of the command.
- *
- * The detail objects survived the Tcl_EvalObjv without change because of
- * the contract. Therefore there is no need to decrement the refcounts. Only
- * the internal method object has to be disposed of.
- */
-
- Tcl_DecrRefCount(methObj);
-
- /*
* The resObj has a ref count of 1 at this location. This means that the
* caller of InvokeTclMethod has to dispose of it (but only if it was
* returned to it).
@@ -2361,7 +2372,7 @@ ErrnoReturn(
int code;
Tcl_InterpState sr; /* State of handler interp */
- if (!rcPtr->interp) {
+ if (rcPtr->dead) {
return 0;
}
@@ -2470,7 +2481,7 @@ DeleteReflectedChannelMap(
chan = Tcl_GetHashValue(hPtr);
rcPtr = Tcl_GetChannelInstanceData(chan);
- rcPtr->interp = NULL;
+ rcPtr->dead = 1;
Tcl_DeleteHashEntry(hPtr);
}
Tcl_DeleteHashTable(&rcmPtr->map);
@@ -2506,6 +2517,11 @@ DeleteReflectedChannelMap(
*/
evPtr = resultPtr->evPtr;
+
+ /* Basic crash safety until this routine can get revised [3411310] */
+ if (evPtr == NULL) {
+ continue;
+ }
paramPtr = evPtr->param;
evPtr->resultPtr = NULL;
@@ -2516,6 +2532,7 @@ DeleteReflectedChannelMap(
Tcl_ConditionNotify(&resultPtr->done);
}
+ Tcl_MutexUnlock(&rcForwardMutex);
/*
* Get the map of all channels handled by the current thread. This is a
@@ -2539,10 +2556,9 @@ DeleteReflectedChannelMap(
continue;
}
+ rcPtr->dead = 1;
Tcl_DeleteHashEntry(hPtr);
}
-
- Tcl_MutexUnlock(&rcForwardMutex);
#endif
}
@@ -2640,6 +2656,11 @@ DeleteThreadReflectedChannelMap(
*/
evPtr = resultPtr->evPtr;
+
+ /* Basic crash safety until this routine can get revised [3411310] */
+ if (evPtr == NULL ) {
+ continue;
+ }
paramPtr = evPtr->param;
evPtr->resultPtr = NULL;
@@ -2650,6 +2671,16 @@ DeleteThreadReflectedChannelMap(
Tcl_ConditionNotify(&resultPtr->done);
}
+ Tcl_MutexUnlock(&rcForwardMutex);
+
+ /*
+ * Run over the event queue of this thread and remove all ReflectEvent's
+ * still pending. These are inbound events for reflected channels this
+ * thread owns but doesn't handle. The inverse of the channel map
+ * actually.
+ */
+
+ Tcl_DeleteEvents(ReflectEventDelete, NULL);
/*
* Get the map of all channels handled by the current thread. This is a
@@ -2664,19 +2695,23 @@ DeleteThreadReflectedChannelMap(
Tcl_Channel chan = Tcl_GetHashValue(hPtr);
ReflectedChannel *rcPtr = Tcl_GetChannelInstanceData(chan);
- rcPtr->interp = NULL;
+ rcPtr->dead = 1;
Tcl_DeleteHashEntry(hPtr);
}
-
- Tcl_MutexUnlock(&rcForwardMutex);
+ ckfree(rcmPtr);
}
static void
-ForwardOpToOwnerThread(
+ForwardOpToHandlerThread(
ReflectedChannel *rcPtr, /* Channel instance */
ForwardedOperation op, /* Forwarded driver operation */
const void *param) /* Arguments */
{
+ /*
+ * Core of the communication from OWNER to HANDLER thread.
+ * The receiver is ForwardProc() below.
+ */
+
Tcl_ThreadId dst = rcPtr->thread;
ForwardingEvent *evPtr;
ForwardingResult *resultPtr;
@@ -2688,7 +2723,7 @@ ForwardOpToOwnerThread(
Tcl_MutexLock(&rcForwardMutex);
- if (rcPtr->interp == NULL) {
+ if (rcPtr->dead) {
/*
* The channel is marked as dead. Bail out immediately, with an
* appropriate error. Do not forget to unlock the mutex on this path.
@@ -2729,7 +2764,7 @@ ForwardOpToOwnerThread(
/*
* Ensure cleanup of the event if the origin thread exits while this event
* is pending or in progress. Exit of the destination thread is handled by
- * DeleteThreadReflectionChannelMap(), this is set up by
+ * DeleteThreadReflectedChannelMap(), this is set up by
* GetThreadReflectedChannelMap(). This is what we use the 'forwardList'
* (see above) for.
*/
@@ -2744,7 +2779,7 @@ ForwardOpToOwnerThread(
Tcl_ThreadAlert(dst);
/*
- * (*) Block until the other thread has either processed the transfer or
+ * (*) Block until the handler thread has either processed the transfer or
* rejected it.
*/
@@ -2792,6 +2827,11 @@ ForwardProc(
int mask)
{
/*
+ * HANDLER thread.
+
+ * The receiver part for the operations coming from the OWNER thread.
+ * See ForwardOpToHandlerThread() for the transmitter.
+ *
* Notes regarding access to the referenced data.
*
* In principle the data belongs to the originating thread (see
@@ -2810,9 +2850,8 @@ ForwardProc(
Tcl_Interp *interp = rcPtr->interp;
ForwardParam *paramPtr = evPtr->param;
Tcl_Obj *resObj = NULL; /* Interp result of InvokeTclMethod */
- ReflectedChannelMap *rcmPtr;
- /* Map of reflected channels with handlers in
- * this interp. */
+ ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in
+ * this interp. */
Tcl_HashEntry *hPtr; /* Entry in the above map */
/*
@@ -2839,12 +2878,12 @@ ForwardProc(
* No parameters/results.
*/
- if (InvokeTclMethod(rcPtr, "finalize", NULL, NULL, &resObj)!=TCL_OK) {
+ if (InvokeTclMethod(rcPtr, METH_FINAL, NULL, NULL, &resObj)!=TCL_OK) {
ForwardSetObjError(paramPtr, resObj);
}
/*
- * Freeing is done here, in the origin thread, because the argv[]
+ * Freeing is done here, in the origin thread, callback command
* objects belong to this thread. Deallocating them in a different
* thread is not allowed
*
@@ -2855,15 +2894,15 @@ ForwardProc(
rcmPtr = GetReflectedChannelMap(interp);
hPtr = Tcl_FindHashEntry(&rcmPtr->map,
- Tcl_GetChannelName(rcPtr->chan));
+ Tcl_GetChannelName(rcPtr->chan));
Tcl_DeleteHashEntry(hPtr);
rcmPtr = GetThreadReflectedChannelMap();
hPtr = Tcl_FindHashEntry(&rcmPtr->map,
- Tcl_GetChannelName(rcPtr->chan));
+ Tcl_GetChannelName(rcPtr->chan));
Tcl_DeleteHashEntry(hPtr);
- Tcl_EventuallyFree (rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
+ Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
break;
case ForwardedInput: {
@@ -2871,7 +2910,7 @@ ForwardProc(
Tcl_IncrRefCount(toReadObj);
Tcl_Preserve(rcPtr);
- if (InvokeTclMethod(rcPtr, "read", toReadObj, NULL, &resObj)!=TCL_OK){
+ if (InvokeTclMethod(rcPtr, METH_READ, toReadObj, NULL, &resObj)!=TCL_OK){
int code = ErrnoReturn(rcPtr, resObj);
if (code < 0) {
@@ -2895,7 +2934,7 @@ ForwardProc(
paramPtr->input.toRead = -1;
} else {
if (bytec > 0) {
- memcpy(paramPtr->input.buf, bytev, (size_t)bytec);
+ memcpy(paramPtr->input.buf, bytev, (size_t) bytec);
}
paramPtr->input.toRead = bytec;
}
@@ -2907,11 +2946,11 @@ ForwardProc(
case ForwardedOutput: {
Tcl_Obj *bufObj = Tcl_NewByteArrayObj((unsigned char *)
- paramPtr->output.buf, paramPtr->output.toWrite);
+ paramPtr->output.buf, paramPtr->output.toWrite);
Tcl_IncrRefCount(bufObj);
Tcl_Preserve(rcPtr);
- if (InvokeTclMethod(rcPtr, "write", bufObj, NULL, &resObj) != TCL_OK) {
+ if (InvokeTclMethod(rcPtr, METH_WRITE, bufObj, NULL, &resObj) != TCL_OK) {
int code = ErrnoReturn(rcPtr, resObj);
if (code < 0) {
@@ -2928,7 +2967,9 @@ ForwardProc(
int written;
if (Tcl_GetIntFromObj(interp, resObj, &written) != TCL_OK) {
- ForwardSetObjError(paramPtr, MarshallError(interp));
+ Tcl_DecrRefCount(resObj);
+ resObj = MarshallError(interp);
+ ForwardSetObjError(paramPtr, resObj);
paramPtr->output.toWrite = -1;
} else if (written==0 || paramPtr->output.toWrite<written) {
ForwardSetStaticError(paramPtr, msg_write_toomuch);
@@ -2945,14 +2986,14 @@ ForwardProc(
case ForwardedSeek: {
Tcl_Obj *offObj = Tcl_NewWideIntObj(paramPtr->seek.offset);
Tcl_Obj *baseObj = Tcl_NewStringObj(
- (paramPtr->seek.seekMode==SEEK_SET) ? "start" :
- (paramPtr->seek.seekMode==SEEK_CUR) ? "current" : "end", -1);
+ (paramPtr->seek.seekMode==SEEK_SET) ? "start" :
+ (paramPtr->seek.seekMode==SEEK_CUR) ? "current" : "end", -1);
Tcl_IncrRefCount(offObj);
Tcl_IncrRefCount(baseObj);
Tcl_Preserve(rcPtr);
- if (InvokeTclMethod(rcPtr, "seek", offObj, baseObj, &resObj)!=TCL_OK){
+ if (InvokeTclMethod(rcPtr, METH_SEEK, offObj, baseObj, &resObj)!=TCL_OK){
ForwardSetObjError(paramPtr, resObj);
paramPtr->seek.offset = -1;
} else {
@@ -2971,7 +3012,9 @@ ForwardProc(
paramPtr->seek.offset = newLoc;
}
} else {
- ForwardSetObjError(paramPtr, MarshallError(interp));
+ Tcl_DecrRefCount(resObj);
+ resObj = MarshallError(interp);
+ ForwardSetObjError(paramPtr, resObj);
paramPtr->seek.offset = -1;
}
}
@@ -2986,7 +3029,7 @@ ForwardProc(
/* assert maskObj.refCount == 1 */
Tcl_Preserve(rcPtr);
- (void) InvokeTclMethod(rcPtr, "watch", maskObj, NULL, NULL);
+ (void) InvokeTclMethod(rcPtr, METH_WATCH, maskObj, NULL, NULL);
Tcl_DecrRefCount(maskObj);
Tcl_Release(rcPtr);
break;
@@ -2994,11 +3037,11 @@ ForwardProc(
case ForwardedBlock: {
Tcl_Obj *blockObj = Tcl_NewBooleanObj(!paramPtr->block.nonblocking);
- Tcl_IncrRefCount(blockObj);
+ Tcl_IncrRefCount(blockObj);
Tcl_Preserve(rcPtr);
- if (InvokeTclMethod(rcPtr, "blocking", blockObj, NULL,
- &resObj) != TCL_OK) {
+ if (InvokeTclMethod(rcPtr, METH_BLOCKING, blockObj, NULL,
+ &resObj) != TCL_OK) {
ForwardSetObjError(paramPtr, resObj);
}
Tcl_Release(rcPtr);
@@ -3013,8 +3056,8 @@ ForwardProc(
Tcl_IncrRefCount(optionObj);
Tcl_IncrRefCount(valueObj);
Tcl_Preserve(rcPtr);
- if (InvokeTclMethod(rcPtr, "configure", optionObj, valueObj,
- &resObj) != TCL_OK) {
+ if (InvokeTclMethod(rcPtr, METH_CONFIGURE, optionObj, valueObj,
+ &resObj) != TCL_OK) {
ForwardSetObjError(paramPtr, resObj);
}
Tcl_Release(rcPtr);
@@ -3029,14 +3072,13 @@ ForwardProc(
*/
Tcl_Obj *optionObj = Tcl_NewStringObj(paramPtr->getOpt.name, -1);
- Tcl_IncrRefCount(optionObj);
+ Tcl_IncrRefCount(optionObj);
Tcl_Preserve(rcPtr);
- if (InvokeTclMethod(rcPtr, "cget", optionObj, NULL, &resObj)!=TCL_OK){
+ if (InvokeTclMethod(rcPtr, METH_CGET, optionObj, NULL, &resObj)!=TCL_OK){
ForwardSetObjError(paramPtr, resObj);
} else {
- Tcl_DStringAppend(paramPtr->getOpt.value,
- TclGetString(resObj), -1);
+ TclDStringAppendObj(paramPtr->getOpt.value, resObj);
}
Tcl_Release(rcPtr);
Tcl_DecrRefCount(optionObj);
@@ -3049,7 +3091,7 @@ ForwardProc(
*/
Tcl_Preserve(rcPtr);
- if (InvokeTclMethod(rcPtr, "cgetall", NULL, NULL, &resObj) != TCL_OK){
+ if (InvokeTclMethod(rcPtr, METH_CGETALL, NULL, NULL, &resObj) != TCL_OK){
ForwardSetObjError(paramPtr, resObj);
} else {
/*
@@ -3061,8 +3103,10 @@ ForwardProc(
Tcl_Obj **listv;
if (Tcl_ListObjGetElements(interp, resObj, &listc,
- &listv) != TCL_OK) {
- ForwardSetObjError(paramPtr, MarshallError(interp));
+ &listv) != TCL_OK) {
+ Tcl_DecrRefCount(resObj);
+ resObj = MarshallError(interp);
+ ForwardSetObjError(paramPtr, resObj);
} else if ((listc % 2) == 1) {
/*
* Odd number of elements is wrong. [x].
@@ -3079,7 +3123,7 @@ ForwardProc(
const char *str = Tcl_GetStringFromObj(resObj, &len);
if (len) {
- Tcl_DStringAppend(paramPtr->getOpt.value, " ", 1);
+ TclDStringAppendLiteral(paramPtr->getOpt.value, " ");
Tcl_DStringAppend(paramPtr->getOpt.value, str, len);
}
}
diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c
index 272306b..1de635f 100644
--- a/generic/tclIORTrans.c
+++ b/generic/tclIORTrans.c
@@ -161,6 +161,8 @@ typedef struct {
int mode; /* Mask of R/W mode */
int nonblocking; /* Flag: Channel is blocking or not. */
int readIsDrained; /* Flag: Read buffers are flushed. */
+ int dead; /* Boolean signal that some operations
+ * should no longer be attempted. */
ResultBuffer result;
} ReflectedTransform;
@@ -361,33 +363,43 @@ static int ForwardProc(Tcl_Event *evPtr, int mask);
static void SrcExitProc(ClientData clientData);
#define FreeReceivedError(p) \
- if ((p)->base.mustFree) { \
- ckfree((p)->base.msgStr); \
- }
+ do { \
+ if ((p)->base.mustFree) { \
+ ckfree((p)->base.msgStr); \
+ } \
+ } while (0)
#define PassReceivedErrorInterp(i,p) \
- if ((i) != NULL) { \
- Tcl_SetChannelErrorInterp((i), \
- Tcl_NewStringObj((p)->base.msgStr, -1)); \
- } \
- FreeReceivedError(p)
+ do { \
+ if ((i) != NULL) { \
+ Tcl_SetChannelErrorInterp((i), \
+ Tcl_NewStringObj((p)->base.msgStr, -1)); \
+ } \
+ FreeReceivedError(p); \
+ } while (0)
#define PassReceivedError(c,p) \
- Tcl_SetChannelError((c), Tcl_NewStringObj((p)->base.msgStr, -1)); \
- FreeReceivedError(p)
+ do { \
+ Tcl_SetChannelError((c), \
+ Tcl_NewStringObj((p)->base.msgStr, -1)); \
+ FreeReceivedError(p); \
+ } while (0)
#define ForwardSetStaticError(p,emsg) \
- (p)->base.code = TCL_ERROR; \
- (p)->base.mustFree = 0; \
- (p)->base.msgStr = (char *) (emsg)
+ do { \
+ (p)->base.code = TCL_ERROR; \
+ (p)->base.mustFree = 0; \
+ (p)->base.msgStr = (char *) (emsg); \
+ } while (0)
#define ForwardSetDynamicError(p,emsg) \
- (p)->base.code = TCL_ERROR; \
- (p)->base.mustFree = 1; \
- (p)->base.msgStr = (char *) (emsg)
+ do { \
+ (p)->base.code = TCL_ERROR; \
+ (p)->base.mustFree = 1; \
+ (p)->base.msgStr = (char *) (emsg); \
+ } while (0)
static void ForwardSetObjError(ForwardParam *p,
Tcl_Obj *objPtr);
-
static ReflectedTransformMap * GetThreadReflectedTransformMap(void);
-static void DeleteThreadReflectedTransformMap(ClientData clientData);
-
+static void DeleteThreadReflectedTransformMap(
+ ClientData clientData);
#endif /* TCL_THREADS */
#define SetChannelErrorStr(c,msgStr) \
@@ -407,6 +419,7 @@ static ReflectedTransform * NewReflectedTransform(Tcl_Interp *interp,
Tcl_Channel parentChan);
static Tcl_Obj * NextHandle(void);
static void FreeReflectedTransform(ReflectedTransform *rtPtr);
+static void FreeReflectedTransformArgs(ReflectedTransform *rtPtr);
static int InvokeTclMethod(ReflectedTransform *rtPtr,
const char *method, Tcl_Obj *argOneObj,
Tcl_Obj *argTwoObj, Tcl_Obj **resultObjPtr);
@@ -436,13 +449,6 @@ static const char *msg_dstlost =
*/
/*
- * Number of milliseconds to wait before firing an event to try to flush out
- * information waiting in buffers (fileevent support).
- */
-
-#define FLUSH_DELAY (5)
-
-/*
* Helper functions encapsulating some of the thread forwarding to make the
* control flow in callers easier.
*/
@@ -517,7 +523,6 @@ TclChanPushObjCmd(
int result; /* Result code for 'initialize' */
Tcl_Obj *resObj; /* Result data for 'initialize' */
int methods; /* Bitmask for supported methods. */
- Tcl_Obj *err; /* Error message */
ReflectedTransformMap *rtmPtr;
/* Map of reflected transforms with handlers
* in this interp. */
@@ -612,11 +617,10 @@ TclChanPushObjCmd(
while (listc > 0) {
if (Tcl_GetIndexFromObj(interp, listv[listc-1], methodNames,
"method", TCL_EXACT, &methIndex) != TCL_OK) {
- TclNewLiteralStringObj(err, "chan handler \"");
- Tcl_AppendObjToObj(err, cmdObj);
- Tcl_AppendToObj(err, " initialize\" returned ", -1);
- Tcl_AppendObjToObj(err, Tcl_GetObjResult(interp));
- Tcl_SetObjResult(interp, err);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "chan handler \"%s initialize\" returned %s",
+ Tcl_GetString(cmdObj),
+ Tcl_GetString(Tcl_GetObjResult(interp))));
Tcl_DecrRefCount(resObj);
goto error;
}
@@ -699,13 +703,14 @@ TclChanPushObjCmd(
rtmPtr = GetThreadReflectedTransformMap();
hPtr = Tcl_CreateHashEntry(&rtmPtr->map, Tcl_GetString(rtId), &isNew);
Tcl_SetHashValue(hPtr, rtPtr);
-#endif
+#endif /* TCL_THREADS */
/*
* Return the channel as the result of the command.
*/
- Tcl_AppendResult(interp, Tcl_GetChannelName(rtPtr->chan), NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ Tcl_GetChannelName(rtPtr->chan), -1));
return TCL_OK;
error:
@@ -714,7 +719,7 @@ TclChanPushObjCmd(
* structure.
*/
- Tcl_EventuallyFree (rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
+ Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
return TCL_ERROR;
#undef CHAN
@@ -881,7 +886,8 @@ ReflectClose(
Tcl_Interp *interp)
{
ReflectedTransform *rtPtr = clientData;
- int result; /* Result code for 'close' */
+ int errorCode, errorCodeSet = 0;
+ int result = TCL_OK; /* Result code for 'close' */
Tcl_Obj *resObj; /* Result data for 'close' */
ReflectedTransformMap *rtmPtr;
/* Map of reflected transforms with handlers
@@ -912,19 +918,13 @@ ReflectClose(
ForwardOpToOwnerThread(rtPtr, ForwardedClose, &p);
result = p.base.code;
- /*
- * FreeReflectedTransform is done in the forwarded operation!, in
- * the other thread. rtPtr here is gone!
- */
-
if (result != TCL_OK) {
FreeReceivedError(&p);
}
- return EOK;
}
-#endif
+#endif /* TCL_THREADS */
- Tcl_EventuallyFree (rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
+ Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
return EOK;
}
@@ -937,18 +937,30 @@ ReflectClose(
*/
if (HAS(rtPtr->methods, METH_DRAIN) && !rtPtr->readIsDrained) {
- int errorCode;
-
if (!TransformDrain(rtPtr, &errorCode)) {
- return errorCode;
+#ifdef TCL_THREADS
+ if (rtPtr->thread != Tcl_GetCurrentThread()) {
+ Tcl_EventuallyFree(rtPtr,
+ (Tcl_FreeProc *) FreeReflectedTransform);
+ return errorCode;
+ }
+#endif /* TCL_THREADS */
+ errorCodeSet = 1;
+ goto cleanup;
}
}
if (HAS(rtPtr->methods, METH_FLUSH)) {
- int errorCode;
-
if (!TransformFlush(rtPtr, &errorCode, FLUSH_WRITE)) {
- return errorCode;
+#ifdef TCL_THREADS
+ if (rtPtr->thread != Tcl_GetCurrentThread()) {
+ Tcl_EventuallyFree(rtPtr,
+ (Tcl_FreeProc *) FreeReflectedTransform);
+ return errorCode;
+ }
+#endif /* TCL_THREADS */
+ errorCodeSet = 1;
+ goto cleanup;
}
}
@@ -963,10 +975,7 @@ ReflectClose(
ForwardOpToOwnerThread(rtPtr, ForwardedClose, &p);
result = p.base.code;
- /*
- * FreeReflectedTransform is done in the forwarded operation!, in the
- * other thread. rtPtr here is gone!
- */
+ Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
if (result != TCL_OK) {
PassReceivedErrorInterp(interp, &p);
@@ -974,7 +983,7 @@ ReflectClose(
}
return EOK;
}
-#endif
+#endif /* TCL_THREADS */
/*
* Do the actual invokation of "finalize" now; we're in the right thread.
@@ -988,6 +997,8 @@ ReflectClose(
Tcl_DecrRefCount(resObj); /* Remove reference we held from the
* invoke. */
+ cleanup:
+
/*
* Remove the transform from the map before releasing the memory, to
* prevent future accesses from finding and dereferencing a dangling
@@ -1001,30 +1012,30 @@ ReflectClose(
* the per-interp DeleteReflectedTransformMap exit-handler.
*/
- if (rtPtr->interp) {
+ if (!rtPtr->dead) {
rtmPtr = GetReflectedTransformMap(rtPtr->interp);
hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle));
if (hPtr) {
Tcl_DeleteHashEntry(hPtr);
}
- }
- /*
- * In a threaded interpreter we manage a per-thread map as well, to allow
- * us to survive if the script level pulls the rug out under a channel by
- * deleting the owning thread.
- */
+ /*
+ * In a threaded interpreter we manage a per-thread map as well,
+ * to allow us to survive if the script level pulls the rug out
+ * under a channel by deleting the owning thread.
+ */
#ifdef TCL_THREADS
- rtmPtr = GetThreadReflectedTransformMap();
- hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle));
- if (hPtr) {
- Tcl_DeleteHashEntry(hPtr);
+ rtmPtr = GetThreadReflectedTransformMap();
+ hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle));
+ if (hPtr) {
+ Tcl_DeleteHashEntry(hPtr);
+ }
+#endif /* TCL_THREADS */
}
-#endif
Tcl_EventuallyFree (rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
- return (result == TCL_OK) ? EOK : EINVAL;
+ return errorCodeSet ? errorCode : ((result == TCL_OK) ? EOK : EINVAL);
}
/*
@@ -1221,7 +1232,7 @@ ReflectInput(
*
* ReflectOutput --
*
- * This function is invoked when data is writen to the channel.
+ * This function is invoked when data is written to the channel.
*
* Results:
* The number of bytes actually written.
@@ -1346,7 +1357,7 @@ ReflectSeekWide(
* transformation.
*/
- if ((rtPtr->methods & FLAG(METH_CLEAR))) {
+ if (rtPtr->methods & FLAG(METH_CLEAR)) {
TransformClear(rtPtr);
}
@@ -1764,6 +1775,7 @@ NewReflectedTransform(
rtPtr->readIsDrained = 0;
rtPtr->nonblocking =
(((Channel *) parentChan)->state->flags & CHANNEL_NONBLOCKING);
+ rtPtr->dead = 0;
/*
* Query parent for current blocking mode.
@@ -1864,18 +1876,18 @@ NextHandle(void)
}
static void
-FreeReflectedTransform(
+FreeReflectedTransformArgs(
ReflectedTransform *rtPtr)
{
- int i, n;
+ int i, n = rtPtr->argc - 2;
- TimerKill(rtPtr);
- ResultClear(&rtPtr->result);
+ if (n < 0) {
+ return;
+ }
Tcl_DecrRefCount(rtPtr->handle);
rtPtr->handle = NULL;
- n = rtPtr->argc - 2;
for (i=0; i<n; i++) {
Tcl_DecrRefCount(rtPtr->argv[i]);
}
@@ -1886,6 +1898,18 @@ FreeReflectedTransform(
*/
Tcl_DecrRefCount(rtPtr->argv[n+1]);
+ rtPtr->argc = 1;
+}
+
+static void
+FreeReflectedTransform(
+ ReflectedTransform *rtPtr)
+{
+ TimerKill(rtPtr);
+ ResultClear(&rtPtr->result);
+
+ FreeReflectedTransformArgs(rtPtr);
+
ckfree(rtPtr->argv);
ckfree(rtPtr);
}
@@ -1931,7 +1955,7 @@ InvokeTclMethod(
int result; /* Result code of method invokation */
Tcl_Obj *resObj = NULL; /* Result of method invokation. */
- if (!rtPtr->interp) {
+ if (rtPtr->dead) {
/*
* The transform is marked as dead. Bail out immediately, with an
* appropriate error.
@@ -2125,7 +2149,7 @@ DeleteReflectedTransformMap(
ForwardingResult *resultPtr;
ForwardingEvent *evPtr;
ForwardParam *paramPtr;
-#endif
+#endif /* TCL_THREADS */
/*
* Delete all entries. The channels may have been closed already, or will
@@ -2144,7 +2168,8 @@ DeleteReflectedTransformMap(
hPtr != NULL;
hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch)) {
rtPtr = Tcl_GetHashValue(hPtr);
- rtPtr->interp = NULL;
+
+ rtPtr->dead = 1;
Tcl_DeleteHashEntry(hPtr);
}
Tcl_DeleteHashTable(&rtmPtr->map);
@@ -2156,6 +2181,32 @@ DeleteReflectedTransformMap(
*/
/*
+ * Get the map of all channels handled by the current thread. This is a
+ * ReflectedTransformMap, but on a per-thread basis, not per-interp. Go
+ * through the channels and remove all which were handled by this
+ * interpreter. They have already been marked as dead.
+ */
+
+ rtmPtr = GetThreadReflectedTransformMap();
+ for (hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch);
+ hPtr != NULL;
+ hPtr = Tcl_NextHashEntry(&hSearch)) {
+ rtPtr = Tcl_GetHashValue(hPtr);
+
+ if (rtPtr->interp != interp) {
+ /*
+ * Ignore entries for other interpreters.
+ */
+
+ continue;
+ }
+
+ rtPtr->dead = 1;
+ FreeReflectedTransformArgs(rtPtr);
+ Tcl_DeleteHashEntry(hPtr);
+ }
+
+ /*
* Go through the list of pending results and cancel all whose events were
* destined for this interpreter. While this is in progress we block any
* other access to the list of pending results.
@@ -2189,33 +2240,8 @@ DeleteReflectedTransformMap(
Tcl_ConditionNotify(&resultPtr->done);
}
-
- /*
- * Get the map of all channels handled by the current thread. This is a
- * ReflectedTransformMap, but on a per-thread basis, not per-interp. Go
- * through the channels and remove all which were handled by this
- * interpreter. They have already been marked as dead.
- */
-
- rtmPtr = GetThreadReflectedTransformMap();
- for (hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch);
- hPtr != NULL;
- hPtr = Tcl_NextHashEntry(&hSearch)) {
- rtPtr = Tcl_GetHashValue(hPtr);
-
- if (rtPtr->interp != interp) {
- /*
- * Ignore entries for other interpreters.
- */
-
- continue;
- }
-
- Tcl_DeleteHashEntry(hPtr);
- }
-
Tcl_MutexUnlock(&rtForwardMutex);
-#endif
+#endif /* TCL_THREADS */
}
#ifdef TCL_THREADS
@@ -2285,6 +2311,24 @@ DeleteThreadReflectedTransformMap(
*/
/*
+ * Get the map of all channels handled by the current thread. This is a
+ * ReflectedTransformMap, but on a per-thread basis, not per-interp. Go
+ * through the channels, remove all, mark them as dead.
+ */
+
+ rtmPtr = GetThreadReflectedTransformMap();
+ for (hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch);
+ hPtr != NULL;
+ hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch)) {
+ ReflectedTransform *rtPtr = Tcl_GetHashValue(hPtr);
+
+ rtPtr->dead = 1;
+ FreeReflectedTransformArgs(rtPtr);
+ Tcl_DeleteHashEntry(hPtr);
+ }
+ ckfree(rtmPtr);
+
+ /*
* Go through the list of pending results and cancel all whose events were
* destined for this thread. While this is in progress we block any
* other access to the list of pending results.
@@ -2321,23 +2365,6 @@ DeleteThreadReflectedTransformMap(
Tcl_ConditionNotify(&resultPtr->done);
}
-
- /*
- * Get the map of all channels handled by the current thread. This is a
- * ReflectedTransformMap, but on a per-thread basis, not per-interp. Go
- * through the channels, remove all, mark them as dead.
- */
-
- rtmPtr = GetThreadReflectedTransformMap();
- for (hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch);
- hPtr != NULL;
- hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch)) {
- ReflectedTransform *rtPtr = Tcl_GetHashValue(hPtr);
-
- rtPtr->interp = NULL;
- Tcl_DeleteHashEntry(hPtr);
- }
-
Tcl_MutexUnlock(&rtForwardMutex);
}
@@ -2358,7 +2385,7 @@ ForwardOpToOwnerThread(
Tcl_MutexLock(&rtForwardMutex);
- if (rtPtr->interp == NULL) {
+ if (rtPtr->dead) {
/*
* The channel is marked as dead. Bail out immediately, with an
* appropriate error. Do not forget to unlock the mutex on this path.
@@ -2384,6 +2411,7 @@ ForwardOpToOwnerThread(
resultPtr->src = Tcl_GetCurrentThread();
resultPtr->dst = dst;
+ resultPtr->dsti = rtPtr->interp;
resultPtr->done = NULL;
resultPtr->result = -1;
resultPtr->evPtr = evPtr;
@@ -2540,7 +2568,7 @@ ForwardProc(
hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle));
Tcl_DeleteHashEntry(hPtr);
- Tcl_EventuallyFree (rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
+ FreeReflectedTransformArgs(rtPtr);
break;
case ForwardedInput: {
@@ -2611,7 +2639,7 @@ ForwardProc(
break;
}
- case ForwardedDrain: {
+ case ForwardedDrain:
if (InvokeTclMethod(rtPtr, "drain", NULL, NULL, &resObj) != TCL_OK) {
ForwardSetObjError(paramPtr, resObj);
paramPtr->transform.size = -1;
@@ -2636,9 +2664,8 @@ ForwardProc(
}
}
break;
- }
- case ForwardedFlush: {
+ case ForwardedFlush:
if (InvokeTclMethod(rtPtr, "flush", NULL, NULL, &resObj) != TCL_OK) {
ForwardSetObjError(paramPtr, resObj);
paramPtr->transform.size = -1;
@@ -2664,12 +2691,10 @@ ForwardProc(
}
}
break;
- }
- case ForwardedClear: {
+ case ForwardedClear:
(void) InvokeTclMethod(rtPtr, "clear", NULL, NULL, NULL);
break;
- }
case ForwardedLimit:
if (InvokeTclMethod(rtPtr, "limit?", NULL, NULL, &resObj) != TCL_OK) {
@@ -2775,7 +2800,7 @@ ForwardSetObjError(
ForwardSetDynamicError(paramPtr, ckalloc(len));
memcpy(paramPtr->base.msgStr, msgStr, (unsigned) len);
}
-#endif
+#endif /* TCL_THREADS */
/*
*----------------------------------------------------------------------
@@ -2834,7 +2859,8 @@ TimerSetup(
return;
}
- rtPtr->timer = Tcl_CreateTimerHandler(FLUSH_DELAY, TimerRun, rtPtr);
+ rtPtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
+ TimerRun, rtPtr);
}
/*
@@ -2916,7 +2942,7 @@ ResultClear(
return;
}
- Tcl_Free((char *) rPtr->buf);
+ ckfree((char *) rPtr->buf);
rPtr->buf = NULL;
rPtr->allocated = 0;
}
@@ -2951,10 +2977,10 @@ ResultAdd(
if (rPtr->allocated == 0) {
rPtr->allocated = toWrite + RB_INCREMENT;
- rPtr->buf = UCHARP(Tcl_Alloc(rPtr->allocated));
+ rPtr->buf = UCHARP(ckalloc(rPtr->allocated));
} else {
rPtr->allocated += toWrite + RB_INCREMENT;
- rPtr->buf = UCHARP(Tcl_Realloc((char *) rPtr->buf,
+ rPtr->buf = UCHARP(ckrealloc((char *) rPtr->buf,
rPtr->allocated));
}
}
@@ -3071,7 +3097,7 @@ TransformRead(
ckfree(p.transform.buf);
return 1;
}
-#endif
+#endif /* TCL_THREADS */
/* ASSERT: rtPtr->method & FLAG(METH_READ) */
/* ASSERT: rtPtr->mode & TCL_READABLE */
@@ -3132,7 +3158,7 @@ TransformWrite(
p.transform.size);
ckfree(p.transform.buf);
} else
-#endif
+#endif /* TCL_THREADS */
{
/* ASSERT: rtPtr->method & FLAG(METH_WRITE) */
/* ASSERT: rtPtr->mode & TCL_WRITABLE */
@@ -3194,7 +3220,7 @@ TransformDrain(
ResultAdd(&rtPtr->result, UCHARP(p.transform.buf), p.transform.size);
ckfree(p.transform.buf);
} else
-#endif
+#endif /* TCL_THREADS */
{
if (InvokeTclMethod(rtPtr, "drain", NULL, NULL, &resObj)!=TCL_OK) {
Tcl_SetChannelError(rtPtr->chan, resObj);
@@ -3249,7 +3275,7 @@ TransformFlush(
}
ckfree(p.transform.buf);
} else
-#endif
+#endif /* TCL_THREADS */
{
if (InvokeTclMethod(rtPtr, "flush", NULL, NULL, &resObj)!=TCL_OK) {
Tcl_SetChannelError(rtPtr->chan, resObj);
@@ -3290,7 +3316,7 @@ TransformClear(
ForwardOpToOwnerThread(rtPtr, ForwardedClear, &p);
return;
}
-#endif
+#endif /* TCL_THREADS */
/* ASSERT: rtPtr->method & FLAG(METH_READ) */
/* ASSERT: rtPtr->mode & TCL_READABLE */
diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c
index 768428f..694501f 100644
--- a/generic/tclIOSock.c
+++ b/generic/tclIOSock.c
@@ -64,8 +64,8 @@ TclSockGetPort(
return TCL_ERROR;
}
if (*portPtr > 0xFFFF) {
- Tcl_AppendResult(interp, "couldn't open socket: port number too high",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "couldn't open socket: port number too high", -1));
return TCL_ERROR;
}
return TCL_OK;
@@ -87,30 +87,33 @@ TclSockGetPort(
*----------------------------------------------------------------------
*/
-#ifdef _WIN32
-# define PTR2SOCK(a) (SOCKET)a
-#else
-# define PTR2SOCK(a) PTR2INT(a)
+#if !defined(_WIN32) && !defined(__CYGWIN__)
+# define SOCKET int
#endif
+
int
TclSockMinimumBuffers(
- ClientData sock, /* Socket file descriptor */
+ void *sock, /* Socket file descriptor */
int size) /* Minimum buffer size */
{
int current;
socklen_t len;
len = sizeof(int);
- getsockopt(PTR2SOCK(sock), SOL_SOCKET, SO_SNDBUF, (char *)&current, &len);
+ getsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_SNDBUF,
+ (char *) &current, &len);
if (current < size) {
len = sizeof(int);
- setsockopt(PTR2SOCK(sock), SOL_SOCKET, SO_SNDBUF, (char *)&size, len);
+ setsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_SNDBUF,
+ (char *) &size, len);
}
len = sizeof(int);
- getsockopt(PTR2SOCK(sock), SOL_SOCKET, SO_RCVBUF, (char *)&current, &len);
+ getsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_RCVBUF,
+ (char *) &current, &len);
if (current < size) {
len = sizeof(int);
- setsockopt(PTR2SOCK(sock), SOL_SOCKET, SO_RCVBUF, (char *)&size, len);
+ setsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_RCVBUF,
+ (char *) &size, len);
}
return TCL_OK;
}
@@ -148,24 +151,34 @@ TclCreateSocketAddress(
struct addrinfo *p;
struct addrinfo *v4head = NULL, *v4ptr = NULL;
struct addrinfo *v6head = NULL, *v6ptr = NULL;
- char *native = NULL, portstring[TCL_INTEGER_SPACE];
+ char *native = NULL, portbuf[TCL_INTEGER_SPACE], *portstring;
const char *family = NULL;
Tcl_DString ds;
int result, i;
- TclFormatInt(portstring, port);
-
if (host != NULL) {
native = Tcl_UtfToExternalDString(NULL, host, -1, &ds);
}
+
+ /*
+ * Workaround for OSX's apparent inability to resolve "localhost", "0"
+ * when the loopback device is the only available network interface.
+ */
+ if (host != NULL && port == 0) {
+ portstring = NULL;
+ } else {
+ TclFormatInt(portbuf, port);
+ portstring = portbuf;
+ }
(void) memset(&hints, 0, sizeof(hints));
-
hints.ai_family = AF_UNSPEC;
+
/*
* Magic variable to enforce a certain address family - to be superseded
* by a TIP that adds explicit switches to [socket]
*/
+
if (interp != NULL) {
family = Tcl_GetVar(interp, "::tcl::unsupported::socketAF", 0);
if (family != NULL) {
@@ -178,22 +191,24 @@ TclCreateSocketAddress(
}
hints.ai_socktype = SOCK_STREAM;
+
#if 0
/*
* We found some problems when using AI_ADDRCONFIG, e.g. on systems that
* have no networking besides the loopback interface and want to resolve
- * localhost. See bugs 3385024, 3382419, 3382431. As the advantage of
+ * localhost. See [Bugs 3385024, 3382419, 3382431]. As the advantage of
* using AI_ADDRCONFIG in situations where it works, is probably low,
* we'll leave it out for now. After all, it is just an optimisation.
- */
-#if defined(AI_ADDRCONFIG) && !defined(_AIX) && !defined(__hpux)
- /*
+ *
* Missing on: OpenBSD, NetBSD.
* Causes failure when used on AIX 5.1 and HP-UX
*/
+
+#if defined(AI_ADDRCONFIG) && !defined(_AIX) && !defined(__hpux)
hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-#endif
+#endif /* AI_ADDRCONFIG && !_AIX && !__hpux */
+#endif /* 0 */
+
if (willBind) {
hints.ai_flags |= AI_PASSIVE;
}
@@ -205,7 +220,12 @@ TclCreateSocketAddress(
}
if (result != 0) {
- goto error;
+ *errorMsgPtr =
+#ifdef EAI_SYSTEM /* Doesn't exist on Windows */
+ (result == EAI_SYSTEM) ? Tcl_PosixError(interp) :
+#endif /* EAI_SYSTEM */
+ gai_strerror(result);
+ return 0;
}
/*
@@ -248,33 +268,6 @@ TclCreateSocketAddress(
}
return 1;
-
- /*
- * Ought to use gai_strerror() here...
- */
-
-error:
- switch (result) {
- case EAI_NONAME:
- case EAI_SERVICE:
-#if defined(EAI_ADDRFAMILY) && EAI_ADDRFAMILY != EAI_NONAME
- case EAI_ADDRFAMILY:
-#endif
-#if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME
- case EAI_NODATA:
-#endif
- *errorMsgPtr = gai_strerror(result);
- errno = EHOSTUNREACH;
- return 0;
-#ifdef EAI_SYSTEM
- case EAI_SYSTEM:
- return 0;
-#endif
- default:
- *errorMsgPtr = gai_strerror(result);
- errno = ENXIO;
- return 0;
- }
}
/*
diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c
index 17e50fa..f624cb7 100644
--- a/generic/tclIOUtil.c
+++ b/generic/tclIOUtil.c
@@ -19,12 +19,49 @@
*/
#include "tclInt.h"
-#ifdef __WIN32__
+#ifdef _WIN32
# include "tclWinInt.h"
#endif
#include "tclFileSystem.h"
/*
+ * struct FilesystemRecord --
+ *
+ * A filesystem record is used to keep track of each filesystem currently
+ * registered with the core, in a linked list.
+ */
+
+typedef struct FilesystemRecord {
+ ClientData clientData; /* Client specific data for the new filesystem
+ * (can be NULL) */
+ const Tcl_Filesystem *fsPtr;/* Pointer to filesystem dispatch table. */
+ struct FilesystemRecord *nextPtr;
+ /* The next filesystem registered to Tcl, or
+ * NULL if no more. */
+ struct FilesystemRecord *prevPtr;
+ /* The previous filesystem registered to Tcl,
+ * or NULL if no more. */
+} FilesystemRecord;
+
+/*
+ * This structure holds per-thread private copy of the current directory
+ * maintained by the global cwdPathPtr. This structure holds per-thread
+ * private copies of some global data. This way we avoid most of the
+ * synchronization calls which boosts performance, at cost of having to update
+ * this information each time the corresponding epoch counter changes.
+ */
+
+typedef struct ThreadSpecificData {
+ int initialized;
+ int cwdPathEpoch;
+ int filesystemEpoch;
+ Tcl_Obj *cwdPathPtr;
+ ClientData cwdClientData;
+ FilesystemRecord *filesystemList;
+ int claims;
+} ThreadSpecificData;
+
+/*
* Prototypes for functions defined later in this file.
*/
@@ -37,9 +74,10 @@ static void FsAddMountsToGlobResult(Tcl_Obj *resultPtr,
Tcl_Obj *pathPtr, const char *pattern,
Tcl_GlobTypeData *types);
static void FsUpdateCwd(Tcl_Obj *cwdObj, ClientData clientData);
-#ifdef TCL_THREADS
static void FsRecacheFilesystemList(void);
-#endif
+static void Claim(void);
+static void Disclaim(void);
+
static void * DivertFindSymbol(Tcl_Interp *interp,
Tcl_LoadHandle loadHandle, const char *symbol);
static void DivertUnloadFile(Tcl_LoadHandle loadHandle);
@@ -141,8 +179,8 @@ const Tcl_Filesystem tclNativeFilesystem = {
TclpObjRenameFile,
TclpObjCopyDirectory,
TclpObjLstat,
- TclpDlopen,
- /* Needs a cast since we're using version_2. */
+ /* Needs casts since we're using version_2. */
+ (Tcl_FSLoadFileProc *) TclpDlopen,
(Tcl_FSGetCwdProc *) TclpGetNativeCwd,
TclpObjChdir
};
@@ -160,7 +198,6 @@ const Tcl_Filesystem tclNativeFilesystem = {
static FilesystemRecord nativeFilesystemRecord = {
NULL,
&tclNativeFilesystem,
- 1,
NULL,
NULL
};
@@ -172,7 +209,7 @@ static FilesystemRecord nativeFilesystemRecord = {
* trigger cache cleanup in all threads.
*/
-static int theFilesystemEpoch = 0;
+static int theFilesystemEpoch = 1;
/*
* Stores the linked list of filesystems. A 1:1 copy of this list is also
@@ -192,7 +229,7 @@ static int cwdPathEpoch = 0;
static ClientData cwdClientData = NULL;
TCL_DECLARE_MUTEX(cwdMutex)
-Tcl_ThreadDataKey tclFsDataKey;
+static Tcl_ThreadDataKey fsDataKey;
/*
* One of these structures is used each time we successfully load a file from
@@ -365,7 +402,7 @@ Tcl_GetCwd(
return NULL;
}
Tcl_DStringInit(cwdPtr);
- Tcl_DStringAppend(cwdPtr, Tcl_GetString(cwd), -1);
+ TclDStringAppendObj(cwdPtr, cwd);
Tcl_DecrRefCount(cwd);
return Tcl_DStringValue(cwdPtr);
}
@@ -416,18 +453,18 @@ FsThrExitProc(
fsRecPtr = tsdPtr->filesystemList;
while (fsRecPtr != NULL) {
tmpFsRecPtr = fsRecPtr->nextPtr;
- if (--fsRecPtr->fileRefCount <= 0) {
- ckfree(fsRecPtr);
- }
+ fsRecPtr->fsPtr = NULL;
+ ckfree(fsRecPtr);
fsRecPtr = tmpFsRecPtr;
}
+ tsdPtr->filesystemList = NULL;
tsdPtr->initialized = 0;
}
int
TclFSCwdIsNative(void)
{
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
if (tsdPtr->cwdClientData != NULL) {
return 1;
@@ -461,7 +498,7 @@ int
TclFSCwdPointerEquals(
Tcl_Obj **pathPtrPtr)
{
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
Tcl_MutexLock(&cwdMutex);
if (tsdPtr->cwdPathPtr == NULL
@@ -520,12 +557,11 @@ TclFSCwdPointerEquals(
}
}
-#ifdef TCL_THREADS
static void
FsRecacheFilesystemList(void)
{
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
- FilesystemRecord *fsRecPtr, *tmpFsRecPtr = NULL;
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
+ FilesystemRecord *fsRecPtr, *tmpFsRecPtr = NULL, *toFree = NULL, *list;
/*
* Trash the current cache.
@@ -534,20 +570,16 @@ FsRecacheFilesystemList(void)
fsRecPtr = tsdPtr->filesystemList;
while (fsRecPtr != NULL) {
tmpFsRecPtr = fsRecPtr->nextPtr;
- if (--fsRecPtr->fileRefCount <= 0) {
- ckfree(fsRecPtr);
- }
+ fsRecPtr->nextPtr = toFree;
+ toFree = fsRecPtr;
fsRecPtr = tmpFsRecPtr;
}
- tsdPtr->filesystemList = NULL;
/*
- * Code below operates on shared data. We are already called under mutex
- * lock so we can safely proceed.
- *
* Locate tail of the global filesystem list.
*/
+ Tcl_MutexLock(&filesystemMutex);
fsRecPtr = filesystemList;
while (fsRecPtr != NULL) {
tmpFsRecPtr = fsRecPtr;
@@ -558,18 +590,26 @@ FsRecacheFilesystemList(void)
* Refill the cache honouring the order.
*/
+ list = NULL;
fsRecPtr = tmpFsRecPtr;
while (fsRecPtr != NULL) {
tmpFsRecPtr = ckalloc(sizeof(FilesystemRecord));
*tmpFsRecPtr = *fsRecPtr;
- tmpFsRecPtr->nextPtr = tsdPtr->filesystemList;
+ tmpFsRecPtr->nextPtr = list;
tmpFsRecPtr->prevPtr = NULL;
- if (tsdPtr->filesystemList) {
- tsdPtr->filesystemList->prevPtr = tmpFsRecPtr;
- }
- tsdPtr->filesystemList = tmpFsRecPtr;
+ list = tmpFsRecPtr;
fsRecPtr = fsRecPtr->prevPtr;
}
+ tsdPtr->filesystemList = list;
+ tsdPtr->filesystemEpoch = theFilesystemEpoch;
+ Tcl_MutexUnlock(&filesystemMutex);
+
+ while (toFree) {
+ FilesystemRecord *next = toFree->nextPtr;
+ toFree->fsPtr = NULL;
+ ckfree(toFree);
+ toFree = next;
+ }
/*
* Make sure the above gets released on thread exit.
@@ -580,28 +620,16 @@ FsRecacheFilesystemList(void)
tsdPtr->initialized = 1;
}
}
-#endif /* TCL_THREADS */
static FilesystemRecord *
FsGetFirstFilesystem(void)
{
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
- FilesystemRecord *fsRecPtr;
-
-#ifndef TCL_THREADS
- tsdPtr->filesystemEpoch = theFilesystemEpoch;
- fsRecPtr = filesystemList;
-#else
- Tcl_MutexLock(&filesystemMutex);
- if (tsdPtr->filesystemList == NULL
- || (tsdPtr->filesystemEpoch != theFilesystemEpoch)) {
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
+ if (tsdPtr->filesystemList == NULL || ((tsdPtr->claims == 0)
+ && (tsdPtr->filesystemEpoch != theFilesystemEpoch))) {
FsRecacheFilesystemList();
- tsdPtr->filesystemEpoch = theFilesystemEpoch;
}
- Tcl_MutexUnlock(&filesystemMutex);
- fsRecPtr = tsdPtr->filesystemList;
-#endif
- return fsRecPtr;
+ return tsdPtr->filesystemList;
}
/*
@@ -613,11 +641,33 @@ int
TclFSEpochOk(
int filesystemEpoch)
{
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
+ return (filesystemEpoch == 0 || filesystemEpoch == theFilesystemEpoch);
+}
+
+static void
+Claim(void)
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
+
+ tsdPtr->claims++;
+}
+
+static void
+Disclaim(void)
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
+
+ tsdPtr->claims--;
+}
+
+int
+TclFSEpoch(void)
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
- (void) FsGetFirstFilesystem();
- return (filesystemEpoch == tsdPtr->filesystemEpoch);
+ return tsdPtr->filesystemEpoch;
}
+
/*
* If non-NULL, clientData is owned by us and must be freed later.
@@ -630,7 +680,7 @@ FsUpdateCwd(
{
int len;
const char *str = NULL;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
if (cwdObj != NULL) {
str = Tcl_GetStringFromObj(cwdObj, &len);
@@ -727,17 +777,14 @@ TclFinalizeFilesystem(void)
while (fsRecPtr != NULL) {
FilesystemRecord *tmpFsRecPtr = fsRecPtr->nextPtr;
- if (fsRecPtr->fileRefCount <= 0) {
- /*
- * The native filesystem is static, so we don't free it.
- */
+ /* The native filesystem is static, so we don't free it. */
- if (fsRecPtr->fsPtr != &tclNativeFilesystem) {
- ckfree(fsRecPtr);
- }
+ if (fsRecPtr != &nativeFilesystemRecord) {
+ ckfree(fsRecPtr);
}
fsRecPtr = tmpFsRecPtr;
}
+ theFilesystemEpoch++;
filesystemList = NULL;
/*
@@ -745,7 +792,7 @@ TclFinalizeFilesystem(void)
* filesystem is likely to fail.
*/
-#ifdef __WIN32__
+#ifdef _WIN32
TclWinEncodingsCleanup();
#endif
}
@@ -770,13 +817,9 @@ void
TclResetFilesystem(void)
{
filesystemList = &nativeFilesystemRecord;
+ theFilesystemEpoch++;
- /*
- * Note, at this point, I believe nativeFilesystemRecord -> fileRefCount
- * should equal 1 and if not, we should try to track down the cause.
- */
-
-#ifdef __WIN32__
+#ifdef _WIN32
/*
* Cleans up the win32 API filesystem proc lookup table. This must happen
* very late in finalization so that deleting of copied dlls can occur.
@@ -833,13 +876,6 @@ Tcl_FSRegister(
newFilesystemPtr->fsPtr = fsPtr;
/*
- * We start with a refCount of 1. If this drops to zero, then anyone is
- * welcome to ckfree us.
- */
-
- newFilesystemPtr->fileRefCount = 1;
-
- /*
* Is this lock and wait strictly speaking necessary? Since any iterators
* out there will have grabbed a copy of the head of the list and be
* iterating away from that, if we add a new element to the head of the
@@ -912,7 +948,7 @@ Tcl_FSUnregister(
*/
fsRecPtr = filesystemList;
- while ((retVal == TCL_ERROR) && (fsRecPtr->fsPtr != &tclNativeFilesystem)) {
+ while ((retVal == TCL_ERROR) && (fsRecPtr != &nativeFilesystemRecord)) {
if (fsRecPtr->fsPtr == fsPtr) {
if (fsRecPtr->prevPtr) {
fsRecPtr->prevPtr->nextPtr = fsRecPtr->nextPtr;
@@ -933,10 +969,7 @@ Tcl_FSUnregister(
theFilesystemEpoch++;
- fsRecPtr->fileRefCount--;
- if (fsRecPtr->fileRefCount <= 0) {
- ckfree(fsRecPtr);
- }
+ ckfree(fsRecPtr);
retVal = TCL_OK;
} else {
@@ -1062,8 +1095,9 @@ Tcl_FSMatchInDirectory(
cwd = Tcl_FSGetCwd(NULL);
if (cwd == NULL) {
if (interp != NULL) {
- Tcl_SetResult(interp, "glob couldn't determine "
- "the current working directory", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "glob couldn't determine the current working directory",
+ -1));
}
return TCL_ERROR;
}
@@ -1344,14 +1378,9 @@ int
TclFSNormalizeToUniquePath(
Tcl_Interp *interp, /* Used for error messages. */
Tcl_Obj *pathPtr, /* The path to normalize in place. */
- int startAt, /* Start at this char-offset. */
- ClientData *clientDataPtr) /* If we generated a complete normalized path
- * for a given filesystem, we can optionally
- * return an fs-specific clientdata here. */
+ int startAt) /* Start at this char-offset. */
{
FilesystemRecord *fsRecPtr, *firstFsRecPtr;
- /* Ignore this variable */
- (void) clientDataPtr;
/*
* Call each of the "normalise path" functions in succession. This is a
@@ -1362,6 +1391,7 @@ TclFSNormalizeToUniquePath(
firstFsRecPtr = FsGetFirstFilesystem();
+ Claim();
for (fsRecPtr=firstFsRecPtr; fsRecPtr!=NULL; fsRecPtr=fsRecPtr->nextPtr) {
if (fsRecPtr->fsPtr != &tclNativeFilesystem) {
continue;
@@ -1399,6 +1429,7 @@ TclFSNormalizeToUniquePath(
* but there's not much benefit.
*/
}
+ Disclaim();
return startAt;
}
@@ -1543,8 +1574,8 @@ TclGetOpenModeEx(
*seekFlagPtr = 0;
*binaryPtr = 0;
if (interp != NULL) {
- Tcl_AppendResult(interp, "illegal access mode \"", modeString,
- "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "illegal access mode \"%s\"", modeString));
}
return -1;
}
@@ -1593,8 +1624,9 @@ TclGetOpenModeEx(
mode |= O_NOCTTY;
#else
if (interp != NULL) {
- Tcl_AppendResult(interp, "access mode \"", flag,
- "\" not supported by this system", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "access mode \"%s\" not supported by this system",
+ flag));
}
ckfree(modeArgv);
return -1;
@@ -1605,8 +1637,9 @@ TclGetOpenModeEx(
mode |= O_NONBLOCK;
#else
if (interp != NULL) {
- Tcl_AppendResult(interp, "access mode \"", flag,
- "\" not supported by this system", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "access mode \"%s\" not supported by this system",
+ flag));
}
ckfree(modeArgv);
return -1;
@@ -1619,9 +1652,10 @@ TclGetOpenModeEx(
} else {
if (interp != NULL) {
- Tcl_AppendResult(interp, "invalid access mode \"", flag,
- "\": must be RDONLY, WRONLY, RDWR, APPEND, BINARY, "
- "CREAT, EXCL, NOCTTY, NONBLOCK, or TRUNC", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid access mode \"%s\": must be RDONLY, WRONLY, "
+ "RDWR, APPEND, BINARY, CREAT, EXCL, NOCTTY, NONBLOCK,"
+ " or TRUNC", flag));
}
ckfree(modeArgv);
return -1;
@@ -1632,8 +1666,9 @@ TclGetOpenModeEx(
if (!gotRW) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "access mode must include either"
- " RDONLY, WRONLY, or RDWR", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "access mode must include either RDONLY, WRONLY, or RDWR",
+ -1));
}
return -1;
}
@@ -1692,15 +1727,16 @@ Tcl_FSEvalFileEx(
if (Tcl_FSStat(pathPtr, &statBuf) == -1) {
Tcl_SetErrno(errno);
- Tcl_AppendResult(interp, "couldn't read file \"",
- Tcl_GetString(pathPtr), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't read file \"%s\": %s",
+ Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
return result;
}
chan = Tcl_FSOpenFileChannel(interp, pathPtr, "r", 0644);
if (chan == NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "couldn't read file \"",
- Tcl_GetString(pathPtr), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't read file \"%s\": %s",
+ Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
return result;
}
@@ -1726,10 +1762,32 @@ Tcl_FSEvalFileEx(
objPtr = Tcl_NewObj();
Tcl_IncrRefCount(objPtr);
- if (Tcl_ReadChars(chan, objPtr, -1, 0) < 0) {
+
+ /*
+ * Try to read first character of stream, so we can check for utf-8 BOM to
+ * be handled especially.
+ */
+
+ if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) {
Tcl_Close(interp, chan);
- Tcl_AppendResult(interp, "couldn't read file \"",
- Tcl_GetString(pathPtr), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't read file \"%s\": %s",
+ Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
+ goto end;
+ }
+ string = Tcl_GetString(objPtr);
+
+ /*
+ * If first character is not a BOM, append the remaining characters,
+ * otherwise replace them. [Bug 3466099]
+ */
+
+ if (Tcl_ReadChars(chan, objPtr, -1,
+ memcmp(string, "\xef\xbb\xbf", 3)) < 0) {
+ Tcl_Close(interp, chan);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't read file \"%s\": %s",
+ Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
goto end;
}
@@ -1748,7 +1806,7 @@ Tcl_FSEvalFileEx(
*/
iPtr->evalFlags |= TCL_EVAL_FILE;
- result = Tcl_EvalEx(interp, string, length, 0);
+ result = TclEvalEx(interp, string, length, 0, 1, NULL, string);
/*
* Now we have to be careful; the script may have changed the
@@ -1795,6 +1853,7 @@ TclNREvalFile(
Tcl_Obj *oldScriptFile, *objPtr;
Interp *iPtr;
Tcl_Channel chan;
+ const char *string;
if (Tcl_FSGetNormalizedPath(interp, pathPtr) == NULL) {
return TCL_ERROR;
@@ -1802,15 +1861,16 @@ TclNREvalFile(
if (Tcl_FSStat(pathPtr, &statBuf) == -1) {
Tcl_SetErrno(errno);
- Tcl_AppendResult(interp, "couldn't read file \"",
- Tcl_GetString(pathPtr), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't read file \"%s\": %s",
+ Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
return TCL_ERROR;
}
chan = Tcl_FSOpenFileChannel(interp, pathPtr, "r", 0644);
if (chan == NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "couldn't read file \"",
- Tcl_GetString(pathPtr), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't read file \"%s\": %s",
+ Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
return TCL_ERROR;
}
@@ -1836,10 +1896,33 @@ TclNREvalFile(
objPtr = Tcl_NewObj();
Tcl_IncrRefCount(objPtr);
- if (Tcl_ReadChars(chan, objPtr, -1, 0) < 0) {
+
+ /*
+ * Try to read first character of stream, so we can check for utf-8 BOM to
+ * be handled especially.
+ */
+
+ if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) {
+ Tcl_Close(interp, chan);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't read file \"%s\": %s",
+ Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
+ Tcl_DecrRefCount(objPtr);
+ return TCL_ERROR;
+ }
+ string = Tcl_GetString(objPtr);
+
+ /*
+ * If first character is not a BOM, append the remaining characters,
+ * otherwise replace them. [Bug 3466099]
+ */
+
+ if (Tcl_ReadChars(chan, objPtr, -1,
+ memcmp(string, "\xef\xbb\xbf", 3)) < 0) {
Tcl_Close(interp, chan);
- Tcl_AppendResult(interp, "couldn't read file \"",
- Tcl_GetString(pathPtr), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't read file \"%s\": %s",
+ Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
Tcl_DecrRefCount(objPtr);
return TCL_ERROR;
}
@@ -2175,9 +2258,9 @@ Tcl_FSOpenFileChannel(
if (seekFlag && Tcl_Seek(retVal, (Tcl_WideInt) 0, SEEK_END)
< (Tcl_WideInt) 0) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "could not seek to end of file "
- "while opening \"", Tcl_GetString(pathPtr), "\": ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not seek to end of file while opening \"%s\": %s",
+ Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
}
Tcl_Close(NULL, retVal);
return NULL;
@@ -2194,8 +2277,9 @@ Tcl_FSOpenFileChannel(
Tcl_SetErrno(ENOENT);
if (interp != NULL) {
- Tcl_AppendResult(interp, "couldn't open \"", Tcl_GetString(pathPtr),
- "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't open \"%s\": %s",
+ Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
}
return NULL;
}
@@ -2551,7 +2635,7 @@ Tcl_Obj *
Tcl_FSGetCwd(
Tcl_Interp *interp)
{
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
if (TclFSCwdPointerEquals(NULL)) {
FilesystemRecord *fsRecPtr;
@@ -2563,8 +2647,9 @@ Tcl_FSGetCwd(
* indicates the particular function has succeeded.
*/
- for (fsRecPtr = FsGetFirstFilesystem();
- (retVal == NULL) && (fsRecPtr != NULL);
+ fsRecPtr = FsGetFirstFilesystem();
+ Claim();
+ for (; (retVal == NULL) && (fsRecPtr != NULL);
fsRecPtr = fsRecPtr->nextPtr) {
ClientData retCd;
TclFSGetCwdProc2 *proc2;
@@ -2588,7 +2673,7 @@ Tcl_FSGetCwd(
retVal = fsRecPtr->fsPtr->internalToNormalizedProc(retCd);
Tcl_IncrRefCount(retVal);
- norm = TclFSNormalizeAbsolutePath(interp,retVal,NULL);
+ norm = TclFSNormalizeAbsolutePath(interp,retVal);
if (norm != NULL) {
/*
* We found a cwd, which is now in our global storage. We
@@ -2609,13 +2694,15 @@ Tcl_FSGetCwd(
}
Tcl_DecrRefCount(retVal);
retVal = NULL;
+ Disclaim();
goto cdDidNotChange;
} else if (interp != NULL) {
- Tcl_AppendResult(interp,
- "error getting working directory name: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error getting working directory name: %s",
+ Tcl_PosixError(interp)));
}
}
+ Disclaim();
/*
* Now the 'cwd' may NOT be normalized, at least on some platforms.
@@ -2627,7 +2714,7 @@ Tcl_FSGetCwd(
*/
if (retVal != NULL) {
- Tcl_Obj *norm = TclFSNormalizeAbsolutePath(interp, retVal, NULL);
+ Tcl_Obj *norm = TclFSNormalizeAbsolutePath(interp, retVal);
if (norm != NULL) {
/*
@@ -2686,9 +2773,9 @@ Tcl_FSGetCwd(
retCd = proc2(tsdPtr->cwdClientData);
if (retCd == NULL && interp != NULL) {
- Tcl_AppendResult(interp,
- "error getting working directory name: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error getting working directory name: %s",
+ Tcl_PosixError(interp)));
}
if (retCd == tsdPtr->cwdClientData) {
@@ -2717,7 +2804,7 @@ Tcl_FSGetCwd(
* Normalize the path.
*/
- norm = TclFSNormalizeAbsolutePath(interp, retVal, NULL);
+ norm = TclFSNormalizeAbsolutePath(interp, retVal);
/*
* Check whether cwd has changed from the value previously stored in
@@ -2899,7 +2986,7 @@ Tcl_FSChdir(
* instead. This should be examined by someone on Unix.
*/
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
ClientData cd;
ClientData oldcd = tsdPtr->cwdClientData;
@@ -3030,7 +3117,7 @@ Tcl_LoadFile(
* code. */
const char *const symbols[],/* Names of functions to look up in the file's
* symbol table. */
- int flags, /* Flags (unused) */
+ int flags, /* Flags */
void *procVPtrs, /* Where to return the addresses corresponding
* to symbols[]. */
Tcl_LoadHandle *handlePtr) /* Filled with token for shared library
@@ -3055,8 +3142,8 @@ Tcl_LoadFile(
}
if (fsPtr->loadFileProc != NULL) {
- int retVal = fsPtr->loadFileProc(interp, pathPtr, handlePtr,
- &unloadProcPtr);
+ int retVal = ((Tcl_FSLoadFileProc2 *)(fsPtr->loadFileProc))
+ (interp, pathPtr, handlePtr, &unloadProcPtr, flags);
if (retVal == TCL_OK) {
if (*handlePtr == NULL) {
@@ -3078,8 +3165,9 @@ Tcl_LoadFile(
*/
if (Tcl_FSAccess(pathPtr, R_OK) != 0) {
- Tcl_AppendResult(interp, "couldn't load library \"",
- Tcl_GetString(pathPtr), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't load library \"%s\": %s",
+ Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
return TCL_ERROR;
}
@@ -3121,7 +3209,7 @@ Tcl_LoadFile(
ret = Tcl_Read(data, buffer, size);
Tcl_Close(interp, data);
ret = TclpLoadMemory(interp, buffer, size, ret, handlePtr,
- &unloadProcPtr);
+ &unloadProcPtr, flags);
if (ret == TCL_OK && *handlePtr != NULL) {
goto resolveSymbols;
}
@@ -3129,7 +3217,7 @@ Tcl_LoadFile(
mustCopyToTempAnyway:
Tcl_ResetResult(interp);
-#endif
+#endif /* TCL_LOAD_FROM_MEMORY */
/*
* Get a temporary filename to use, first to copy the file into, and then
@@ -3137,6 +3225,9 @@ Tcl_LoadFile(
*/
copyToPtr = TclpTempFileNameForLibrary(interp, pathPtr);
+ if (copyToPtr == NULL) {
+ return TCL_ERROR;
+ }
Tcl_IncrRefCount(copyToPtr);
copyFsPtr = Tcl_FSGetFileSystemForPath(copyToPtr);
@@ -3149,8 +3240,8 @@ Tcl_LoadFile(
Tcl_FSDeleteFile(copyToPtr);
Tcl_DecrRefCount(copyToPtr);
- Tcl_AppendResult(interp, "couldn't load from current filesystem",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "couldn't load from current filesystem", -1));
return TCL_ERROR;
}
@@ -3164,7 +3255,7 @@ Tcl_LoadFile(
return TCL_ERROR;
}
-#ifndef __WIN32__
+#ifndef _WIN32
/*
* Do we need to set appropriate permissions on the file? This may be
* required on some systems. On Unix we could loop over the file
@@ -3192,7 +3283,7 @@ Tcl_LoadFile(
Tcl_ResetResult(interp);
- retVal = Tcl_LoadFile(interp, copyToPtr, symbols, 0, procPtrs,
+ retVal = Tcl_LoadFile(interp, copyToPtr, symbols, flags, procPtrs,
&newLoadHandle);
if (retVal != TCL_OK) {
/*
@@ -3424,50 +3515,6 @@ DivertUnloadFile(
}
/*
- * This function used to be in the platform specific directories, but it has
- * now been made to work cross-platform.
- */
-
-int
-TclpLoadFile(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Obj *pathPtr, /* Name of the file containing the desired
- * code (UTF-8). */
- const char *sym1, const char *sym2,
- /* Names of two functions to look up in the
- * file's symbol table. */
- Tcl_PackageInitProc **proc1Ptr, Tcl_PackageInitProc **proc2Ptr,
- /* Where to return the addresses corresponding
- * to sym1 and sym2. */
- ClientData *clientDataPtr, /* Filled with token for dynamically loaded
- * file which will be passed back to
- * (*unloadProcPtr)() to unload the file. */
- Tcl_FSUnloadFileProc **unloadProcPtr)
- /* Filled with address of Tcl_FSUnloadFileProc
- * function which should be used for this
- * file. */
-{
- Tcl_LoadHandle handle = NULL;
- int res;
-
- res = TclpDlopen(interp, pathPtr, &handle, unloadProcPtr);
-
- if (res != TCL_OK) {
- return res;
- }
-
- if (handle == NULL) {
- return TCL_ERROR;
- }
-
- *clientDataPtr = handle;
-
- *proc1Ptr = (Tcl_PackageInitProc*) Tcl_FindSymbol(interp, handle, sym1);
- *proc2Ptr = (Tcl_PackageInitProc*) Tcl_FindSymbol(interp, handle, sym2);
- return TCL_OK;
-}
-
-/*
*----------------------------------------------------------------------
*
* Tcl_FindSymbol --
@@ -3736,6 +3783,7 @@ Tcl_FSListVolumes(void)
*/
fsRecPtr = FsGetFirstFilesystem();
+ Claim();
while (fsRecPtr != NULL) {
if (fsRecPtr->fsPtr->listVolumesProc != NULL) {
Tcl_Obj *thisFsVolumes = fsRecPtr->fsPtr->listVolumesProc();
@@ -3747,6 +3795,7 @@ Tcl_FSListVolumes(void)
}
fsRecPtr = fsRecPtr->nextPtr;
}
+ Disclaim();
return resultPtr;
}
@@ -3786,6 +3835,7 @@ FsListMounts(
*/
fsRecPtr = FsGetFirstFilesystem();
+ Claim();
while (fsRecPtr != NULL) {
if (fsRecPtr->fsPtr != &tclNativeFilesystem &&
fsRecPtr->fsPtr->matchInDirectoryProc != NULL) {
@@ -3797,6 +3847,7 @@ FsListMounts(
}
fsRecPtr = fsRecPtr->nextPtr;
}
+ Disclaim();
return resultPtr;
}
@@ -3908,31 +3959,6 @@ Tcl_FSSplitPath(
}
return result;
}
-
-/* Simple helper function. */
-Tcl_Obj *
-TclFSInternalToNormalized(
- const Tcl_Filesystem *fromFilesystem,
- ClientData clientData,
- FilesystemRecord **fsRecPtrPtr)
-{
- FilesystemRecord *fsRecPtr = FsGetFirstFilesystem();
-
- while (fsRecPtr != NULL) {
- if (fsRecPtr->fsPtr == fromFilesystem) {
- *fsRecPtrPtr = fsRecPtr;
- break;
- }
- fsRecPtr = fsRecPtr->nextPtr;
- }
-
- if ((fsRecPtr == NULL)
- || (fromFilesystem->internalToNormalizedProc == NULL)) {
- return NULL;
- }
- return fromFilesystem->internalToNormalizedProc(clientData);
-}
-
/*
*----------------------------------------------------------------------
*
@@ -4034,6 +4060,7 @@ TclFSNonnativePathType(
*/
fsRecPtr = FsGetFirstFilesystem();
+ Claim();
while (fsRecPtr != NULL) {
/*
* We want to skip the native filesystem in this loop because
@@ -4111,6 +4138,7 @@ TclFSNonnativePathType(
}
fsRecPtr = fsRecPtr->nextPtr;
}
+ Disclaim();
return type;
}
@@ -4498,10 +4526,14 @@ Tcl_FSGetFileSystemForPath(
*/
fsRecPtr = FsGetFirstFilesystem();
+ Claim();
+
if (TclFSEnsureEpochOk(pathPtr, &retVal) != TCL_OK) {
+ Disclaim();
return NULL;
} else if (retVal != NULL) {
/* TODO: Can this happen? */
+ Disclaim();
return retVal;
}
@@ -4523,10 +4555,12 @@ Tcl_FSGetFileSystemForPath(
* call to the pathInFilesystemProc.
*/
- TclFSSetPathDetails(pathPtr, fsRecPtr, clientData);
+ TclFSSetPathDetails(pathPtr, fsRecPtr->fsPtr, clientData);
+ Disclaim();
return fsRecPtr->fsPtr;
}
}
+ Disclaim();
return NULL;
}
diff --git a/generic/tclIndexObj.c b/generic/tclIndexObj.c
index 6f378a4..ce8b9fb 100644
--- a/generic/tclIndexObj.c
+++ b/generic/tclIndexObj.c
@@ -53,7 +53,7 @@ static const Tcl_ObjType indexType = {
/*
* The definition of the internal representation of the "index" object; The
- * internalRep.otherValuePtr field of an object of "index" type will be a
+ * internalRep.twoPtrValue.ptr1 field of an object of "index" type will be a
* pointer to one of these structures.
*
* Keep this structure declaration in sync with tclTestObj.c
@@ -69,12 +69,12 @@ typedef struct {
* The following macros greatly simplify moving through a table...
*/
-#define STRING_AT(table, offset, index) \
- (*((const char *const *)(((char *)(table)) + ((offset) * (index)))))
+#define STRING_AT(table, offset) \
+ (*((const char *const *)(((char *)(table)) + (offset))))
#define NEXT_ENTRY(table, offset) \
- (&(STRING_AT(table, offset, 1)))
+ (&(STRING_AT(table, offset)))
#define EXPAND_OF(indexRep) \
- STRING_AT((indexRep)->tablePtr, (indexRep)->offset, (indexRep)->index)
+ STRING_AT((indexRep)->tablePtr, (indexRep)->offset*(indexRep)->index)
/*
*----------------------------------------------------------------------
@@ -101,6 +101,7 @@ typedef struct {
*----------------------------------------------------------------------
*/
+#undef Tcl_GetIndexFromObj
int
Tcl_GetIndexFromObj(
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
@@ -121,7 +122,7 @@ Tcl_GetIndexFromObj(
*/
if (objPtr->typePtr == &indexType) {
- IndexRep *indexRep = objPtr->internalRep.otherValuePtr;
+ IndexRep *indexRep = objPtr->internalRep.twoPtrValue.ptr1;
/*
* Here's hoping we don't get hit by unfortunate packing constraints
@@ -238,7 +239,7 @@ GetIndexFromObjList(
* a proper match, then TCL_ERROR is returned and an error message is
* left in interp's result (unless interp is NULL). The msg argument is
* used in the error message; for example, if msg has the value "option"
- * then the error message will say something flag 'bad option "foo": must
+ * then the error message will say something like 'bad option "foo": must
* be ...'
*
* Side effects:
@@ -270,12 +271,16 @@ Tcl_GetIndexFromObjStruct(
Tcl_Obj *resultPtr;
IndexRep *indexRep;
+ /* Protect against invalid values, like -1 or 0. */
+ if (offset < (int)sizeof(char *)) {
+ offset = (int)sizeof(char *);
+ }
/*
* See if there is a valid cached result from a previous lookup.
*/
if (objPtr->typePtr == &indexType) {
- indexRep = objPtr->internalRep.otherValuePtr;
+ indexRep = objPtr->internalRep.twoPtrValue.ptr1;
if (indexRep->tablePtr==tablePtr && indexRep->offset==offset) {
*indexPtr = indexRep->index;
return TCL_OK;
@@ -336,11 +341,11 @@ Tcl_GetIndexFromObjStruct(
*/
if (objPtr->typePtr == &indexType) {
- indexRep = objPtr->internalRep.otherValuePtr;
+ indexRep = objPtr->internalRep.twoPtrValue.ptr1;
} else {
TclFreeIntRep(objPtr);
indexRep = ckalloc(sizeof(IndexRep));
- objPtr->internalRep.otherValuePtr = indexRep;
+ objPtr->internalRep.twoPtrValue.ptr1 = indexRep;
objPtr->typePtr = &indexType;
}
indexRep->tablePtr = (void *) tablePtr;
@@ -356,26 +361,31 @@ Tcl_GetIndexFromObjStruct(
* Produce a fancy error message.
*/
- int count;
+ int count = 0;
TclNewObj(resultPtr);
+ entryPtr = tablePtr;
+ while ((*entryPtr != NULL) && !**entryPtr) {
+ entryPtr = NEXT_ENTRY(entryPtr, offset);
+ }
Tcl_AppendStringsToObj(resultPtr,
(numAbbrev>1 && !(flags & TCL_EXACT) ? "ambiguous " : "bad "),
msg, " \"", key, NULL);
- if (STRING_AT(tablePtr, offset, 0) == NULL) {
+ if (*entryPtr == NULL) {
Tcl_AppendStringsToObj(resultPtr, "\": no valid options", NULL);
} else {
Tcl_AppendStringsToObj(resultPtr, "\": must be ",
- STRING_AT(tablePtr, offset, 0), NULL);
- for (entryPtr = NEXT_ENTRY(tablePtr, offset), count = 0;
- *entryPtr != NULL;
- entryPtr = NEXT_ENTRY(entryPtr, offset), count++) {
+ *entryPtr, NULL);
+ entryPtr = NEXT_ENTRY(entryPtr, offset);
+ while (*entryPtr != NULL) {
if (*NEXT_ENTRY(entryPtr, offset) == NULL) {
Tcl_AppendStringsToObj(resultPtr, (count > 0 ? "," : ""),
" or ", *entryPtr, NULL);
- } else {
+ } else if (**entryPtr) {
Tcl_AppendStringsToObj(resultPtr, ", ", *entryPtr, NULL);
+ count++;
}
+ entryPtr = NEXT_ENTRY(entryPtr, offset);
}
}
Tcl_SetObjResult(interp, resultPtr);
@@ -438,7 +448,7 @@ static void
UpdateStringOfIndex(
Tcl_Obj *objPtr)
{
- IndexRep *indexRep = objPtr->internalRep.otherValuePtr;
+ IndexRep *indexRep = objPtr->internalRep.twoPtrValue.ptr1;
register char *buf;
register unsigned len;
register const char *indexStr = EXPAND_OF(indexRep);
@@ -473,11 +483,11 @@ DupIndex(
Tcl_Obj *srcPtr,
Tcl_Obj *dupPtr)
{
- IndexRep *srcIndexRep = srcPtr->internalRep.otherValuePtr;
+ IndexRep *srcIndexRep = srcPtr->internalRep.twoPtrValue.ptr1;
IndexRep *dupIndexRep = ckalloc(sizeof(IndexRep));
memcpy(dupIndexRep, srcIndexRep, sizeof(IndexRep));
- dupPtr->internalRep.otherValuePtr = dupIndexRep;
+ dupPtr->internalRep.twoPtrValue.ptr1 = dupIndexRep;
dupPtr->typePtr = &indexType;
}
@@ -502,7 +512,7 @@ static void
FreeIndex(
Tcl_Obj *objPtr)
{
- ckfree(objPtr->internalRep.otherValuePtr);
+ ckfree(objPtr->internalRep.twoPtrValue.ptr1);
objPtr->typePtr = NULL;
}
@@ -528,9 +538,9 @@ TclInitPrefixCmd(
Tcl_Interp *interp) /* Current interpreter. */
{
static const EnsembleImplMap prefixImplMap[] = {
- {"all", PrefixAllObjCmd, NULL, NULL, NULL, 0},
- {"longest", PrefixLongestObjCmd, NULL, NULL, NULL, 0},
- {"match", PrefixMatchObjCmd, NULL, NULL, NULL, 0},
+ {"all", PrefixAllObjCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"longest", PrefixLongestObjCmd,TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"match", PrefixMatchObjCmd, TclCompileBasicMin2ArgCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
};
Tcl_Command prefixCmd;
@@ -591,8 +601,9 @@ PrefixMatchObjCmd(
flags |= TCL_EXACT;
break;
case PRFMATCH_MESSAGE:
- if (i > (objc - 4)) {
- Tcl_AppendResult(interp, "missing message", NULL);
+ if (i > objc-4) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "missing value for -message", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NOARG", NULL);
return TCL_ERROR;
}
@@ -601,7 +612,8 @@ PrefixMatchObjCmd(
break;
case PRFMATCH_ERROR:
if (i > objc-4) {
- Tcl_AppendResult(interp, "missing error options", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "missing value for -error", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NOARG", NULL);
return TCL_ERROR;
}
@@ -611,8 +623,9 @@ PrefixMatchObjCmd(
return TCL_ERROR;
}
if ((errorLength % 2) != 0) {
- Tcl_AppendResult(interp, "error options must have an even"
- " number of elements", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "error options must have an even number of elements",
+ -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL);
return TCL_ERROR;
}
@@ -940,13 +953,13 @@ Tcl_WrongNumArgs(
if (origObjv[i]->typePtr == &indexType) {
register IndexRep *indexRep =
- origObjv[i]->internalRep.otherValuePtr;
+ origObjv[i]->internalRep.twoPtrValue.ptr1;
elementStr = EXPAND_OF(indexRep);
elemLen = strlen(elementStr);
} else if (origObjv[i]->typePtr == &tclEnsembleCmdType) {
register EnsembleCmdRep *ecrPtr =
- origObjv[i]->internalRep.otherValuePtr;
+ origObjv[i]->internalRep.twoPtrValue.ptr1;
elementStr = ecrPtr->fullSubcmdName;
elemLen = strlen(elementStr);
@@ -995,12 +1008,12 @@ Tcl_WrongNumArgs(
*/
if (objv[i]->typePtr == &indexType) {
- register IndexRep *indexRep = objv[i]->internalRep.otherValuePtr;
+ register IndexRep *indexRep = objv[i]->internalRep.twoPtrValue.ptr1;
Tcl_AppendStringsToObj(objPtr, EXPAND_OF(indexRep), NULL);
} else if (objv[i]->typePtr == &tclEnsembleCmdType) {
register EnsembleCmdRep *ecrPtr =
- objv[i]->internalRep.otherValuePtr;
+ objv[i]->internalRep.twoPtrValue.ptr1;
Tcl_AppendStringsToObj(objPtr, ecrPtr->fullSubcmdName, NULL);
} else {
@@ -1113,13 +1126,15 @@ Tcl_ParseArgsObjv(
if (remObjv != NULL) {
/*
- * Then we should copy the name of the command (0th argument).
+ * Then we should copy the name of the command (0th argument). The
+ * upper bound on the number of elements is known, and (undocumented,
+ * but historically true) there should be a NULL argument after the
+ * last result. [Bug 3413857]
*/
nrem = 1;
- leftovers = ckalloc((nrem + 1) * sizeof(Tcl_Obj *));
- leftovers[nrem-1] = objv[0];
- leftovers[nrem] = NULL;
+ leftovers = ckalloc((1 + *objcPtr) * sizeof(Tcl_Obj *));
+ leftovers[0] = objv[0];
} else {
nrem = 0;
leftovers = NULL;
@@ -1163,8 +1178,8 @@ Tcl_ParseArgsObjv(
goto gotMatch;
}
if (matchPtr != NULL) {
- Tcl_AppendResult(interp, "ambiguous option \"", str, "\"",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "ambiguous option \"%s\"", str));
goto error;
}
matchPtr = infoPtr;
@@ -1176,20 +1191,13 @@ Tcl_ParseArgsObjv(
*/
if (remObjv == NULL) {
- Tcl_AppendResult(interp, "unrecognized argument \"", str,
- "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unrecognized argument \"%s\"", str));
goto error;
}
dstIndex++; /* This argument is now handled */
- nrem++;
-
- /*
- * Allocate nrem (+1 extra for NULL terminator) pointers.
- */
-
- leftovers = ckrealloc(leftovers, (nrem+1) * sizeof(Tcl_Obj *));
- leftovers[nrem-1] = curArg;
+ leftovers[nrem++] = curArg;
continue;
}
@@ -1209,9 +1217,9 @@ Tcl_ParseArgsObjv(
}
if (Tcl_GetIntFromObj(interp, objv[srcIndex],
(int *) infoPtr->dstPtr) == TCL_ERROR) {
- Tcl_AppendResult(interp, "expected integer argument for \"",
- infoPtr->keyStr, "\" but got \"",
- Tcl_GetString(objv[srcIndex]), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "expected integer argument for \"%s\" but got \"%s\"",
+ infoPtr->keyStr, Tcl_GetString(objv[srcIndex])));
goto error;
}
srcIndex++;
@@ -1227,7 +1235,14 @@ Tcl_ParseArgsObjv(
objc--;
break;
case TCL_ARGV_REST:
- *((int *) infoPtr->dstPtr) = dstIndex;
+ /*
+ * Only store the point where we got to if it's not to be written
+ * to NULL, so that TCL_ARGV_AUTO_REST works.
+ */
+
+ if (infoPtr->dstPtr != NULL) {
+ *((int *) infoPtr->dstPtr) = dstIndex;
+ }
goto argsDone;
case TCL_ARGV_FLOAT:
if (objc == 0) {
@@ -1235,9 +1250,9 @@ Tcl_ParseArgsObjv(
}
if (Tcl_GetDoubleFromObj(interp, objv[srcIndex],
(double *) infoPtr->dstPtr) == TCL_ERROR) {
- Tcl_AppendResult(interp, "expected floating-point argument ",
- "for \"", infoPtr->keyStr, "\" but got \"",
- Tcl_GetString(objv[srcIndex]), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "expected floating-point argument for \"%s\" but got \"%s\"",
+ infoPtr->keyStr, Tcl_GetString(objv[srcIndex])));
goto error;
}
srcIndex++;
@@ -1282,7 +1297,9 @@ Tcl_ParseArgsObjv(
/*
* If we broke out of the loop because of an OPT_REST argument, copy the
- * remaining arguments down.
+ * remaining arguments down. Note that there is always at least one
+ * argument left over - the command name - so we always have a result if
+ * our caller is willing to receive it. [Bug 3413857]
*/
argsDone:
@@ -1295,19 +1312,12 @@ Tcl_ParseArgsObjv(
}
if (objc > 0) {
- leftovers = ckrealloc(leftovers, (nrem+objc+1) * sizeof(Tcl_Obj *));
- while (objc) {
- leftovers[nrem] = objv[srcIndex];
- nrem++;
- srcIndex++;
- objc--;
- }
- } else if (leftovers != NULL) {
- ckfree(leftovers);
+ memcpy(leftovers+nrem, objv+srcIndex, objc*sizeof(Tcl_Obj *));
+ nrem += objc;
}
leftovers[nrem] = NULL;
- *objcPtr = nrem;
- *remObjv = leftovers;
+ *objcPtr = nrem++;
+ *remObjv = ckrealloc(leftovers, nrem * sizeof(Tcl_Obj *));
return TCL_OK;
/*
@@ -1316,8 +1326,8 @@ Tcl_ParseArgsObjv(
*/
missingArg:
- Tcl_AppendResult(interp, "\"", str,
- "\" option requires an additional argument", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" option requires an additional argument", str));
error:
if (leftovers != NULL) {
ckfree(leftovers);
@@ -1353,8 +1363,9 @@ PrintUsage(
register const Tcl_ArgvInfo *infoPtr;
int width, numSpaces;
#define NUM_SPACES 20
- static char spaces[] = " ";
+ static const char spaces[] = " ";
char tmp[TCL_DOUBLE_SPACE];
+ Tcl_Obj *msg;
/*
* First, compute the width of the widest option key, so that we can make
@@ -1378,39 +1389,39 @@ PrintUsage(
* Now add the option information, with pretty-printing.
*/
- Tcl_AppendResult(interp, "Command-specific options:", NULL);
+ msg = Tcl_NewStringObj("Command-specific options:", -1);
for (infoPtr = argTable; infoPtr->type != TCL_ARGV_END; infoPtr++) {
if ((infoPtr->type == TCL_ARGV_HELP) && (infoPtr->keyStr == NULL)) {
- Tcl_AppendResult(interp, "\n", infoPtr->helpStr, NULL);
+ Tcl_AppendPrintfToObj(msg, "\n%s", infoPtr->helpStr);
continue;
}
- Tcl_AppendResult(interp, "\n ", infoPtr->keyStr, ":", NULL);
+ Tcl_AppendPrintfToObj(msg, "\n %s:", infoPtr->keyStr);
numSpaces = width + 1 - strlen(infoPtr->keyStr);
while (numSpaces > 0) {
if (numSpaces >= NUM_SPACES) {
- Tcl_AppendResult(interp, spaces, NULL);
+ Tcl_AppendToObj(msg, spaces, NUM_SPACES);
} else {
- Tcl_AppendResult(interp, spaces+NUM_SPACES-numSpaces, NULL);
+ Tcl_AppendToObj(msg, spaces, numSpaces);
}
numSpaces -= NUM_SPACES;
}
- Tcl_AppendResult(interp, infoPtr->helpStr, NULL);
+ Tcl_AppendToObj(msg, infoPtr->helpStr, -1);
switch (infoPtr->type) {
case TCL_ARGV_INT:
- sprintf(tmp, "%d", *((int *) infoPtr->dstPtr));
- Tcl_AppendResult(interp, "\n\t\tDefault value: ", tmp, NULL);
+ Tcl_AppendPrintfToObj(msg, "\n\t\tDefault value: %d",
+ *((int *) infoPtr->dstPtr));
break;
case TCL_ARGV_FLOAT:
+ Tcl_AppendPrintfToObj(msg, "\n\t\tDefault value: %g",
+ *((double *) infoPtr->dstPtr));
sprintf(tmp, "%g", *((double *) infoPtr->dstPtr));
- Tcl_AppendResult(interp, "\n\t\tDefault value: ", tmp, NULL);
break;
case TCL_ARGV_STRING: {
- char *string;
+ char *string = *((char **) infoPtr->dstPtr);
- string = *((char **) infoPtr->dstPtr);
if (string != NULL) {
- Tcl_AppendResult(interp, "\n\t\tDefault value: \"", string,
- "\"", NULL);
+ Tcl_AppendPrintfToObj(msg, "\n\t\tDefault value: \"%s\"",
+ string);
}
break;
}
@@ -1418,6 +1429,7 @@ PrintUsage(
break;
}
}
+ Tcl_SetObjResult(interp, msg);
}
/*
@@ -1429,8 +1441,8 @@ PrintUsage(
*
* Results:
* Returns TCL_ERROR if the value is an invalid completion code.
- * Otherwise, returns TCL_OK, and writes the completion code to
- * the pointer provided.
+ * Otherwise, returns TCL_OK, and writes the completion code to the
+ * pointer provided.
*
* Side effects:
* None.
@@ -1442,30 +1454,30 @@ int
TclGetCompletionCodeFromObj(
Tcl_Interp *interp, /* Current interpreter. */
Tcl_Obj *value,
- int *code) /* Argument objects. */
+ int *codePtr) /* Argument objects. */
{
static const char *const returnCodes[] = {
"ok", "error", "return", "break", "continue", NULL
};
if ((value->typePtr != &indexType)
- && (TCL_OK == TclGetIntFromObj(NULL, value, code))) {
+ && TclGetIntFromObj(NULL, value, codePtr) == TCL_OK) {
return TCL_OK;
}
- if (TCL_OK == Tcl_GetIndexFromObj(NULL, value, returnCodes, NULL,
- TCL_EXACT, code)) {
+ if (Tcl_GetIndexFromObj(NULL, value, returnCodes, NULL, TCL_EXACT,
+ codePtr) == TCL_OK) {
return TCL_OK;
}
+
/*
* Value is not a legal completion code.
*/
if (interp != NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad completion code \"",
- TclGetString(value),
- "\": must be ok, error, return, break, "
- "continue, or an integer", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad completion code \"%s\": must be"
+ " ok, error, return, break, continue, or an integer",
+ TclGetString(value)));
Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_CODE", NULL);
}
return TCL_ERROR;
diff --git a/generic/tclInt.decls b/generic/tclInt.decls
index df60dae..9f7b106 100644
--- a/generic/tclInt.decls
+++ b/generic/tclInt.decls
@@ -18,7 +18,6 @@ library tcl
# Define the unsupported generic interfaces.
interface tclInt
-scspec EXTERN
# Declare each of the functions in the unsupported internal Tcl
# interface. These interfaces are allowed to changed between versions.
@@ -189,7 +188,7 @@ declare 42 {
}
# Removed in Tcl 8.5a2
#declare 43 {
-# int TclGlobalInvoke(Tcl_Interp *interp, int argc, const char **argv,
+# int TclGlobalInvoke(Tcl_Interp *interp, int argc, CONST84 char **argv,
# int flags)
#}
declare 44 {
@@ -224,7 +223,7 @@ declare 51 {
}
# Removed in Tcl 8.5a2
#declare 52 {
-# int TclInvoke(Tcl_Interp *interp, int argc, const char **argv,
+# int TclInvoke(Tcl_Interp *interp, int argc, CONST84 char **argv,
# int flags)
#}
declare 53 {
@@ -320,9 +319,10 @@ declare 76 {
declare 77 {
void TclpGetTime(Tcl_Time *time)
}
-declare 78 {
- int TclpGetTimeZone(unsigned long time)
-}
+# Removed in 8.6:
+#declare 78 {
+# int TclpGetTimeZone(unsigned long time)
+#}
# Replaced by Tcl_FSListVolumes in 8.4:
#declare 79 {
# int TclpListVolumes(Tcl_Interp *interp)
@@ -421,7 +421,7 @@ declare 103 {
int *portPtr)
}
declare 104 {
- int TclSockMinimumBuffers(ClientData sock, int size)
+ int TclSockMinimumBuffersOld(int sock, int size)
}
# Replaced by Tcl_FSStat in 8.4:
#declare 105 {
@@ -439,6 +439,9 @@ declare 108 {
declare 109 {
int TclUpdateReturnInfo(Interp *iPtr)
}
+declare 110 {
+ int TclSockMinimumBuffers(void *sock, int size)
+}
# Removed in 8.1:
# declare 110 {
# char *TclWordEnd(char *start, char *lastChar, int nested, int *semiPtr)
@@ -623,14 +626,14 @@ declare 156 {
declare 157 {
Var *TclVarTraceExists(Tcl_Interp *interp, const char *varName)
}
-# REMOVED - use public Tcl_SetStartupScript()
-#declare 158 {
-# void TclSetStartupScriptFileName(const char *filename)
-#}
-# REMOVED - use public Tcl_GetStartupScript()
-#declare 159 {
-# const char *TclGetStartupScriptFileName(void)
-#}
+# REMOVED (except from stub table) - use public Tcl_SetStartupScript()
+declare 158 {
+ void TclSetStartupScriptFileName(const char *filename)
+}
+# REMOVED (except from stub table) - use public Tcl_GetStartupScript()
+declare 159 {
+ const char *TclGetStartupScriptFileName(void)
+}
#declare 160 {
# int TclpMatchFilesTypes(Tcl_Interp *interp, char *separators,
# Tcl_DString *dirPtr, char *pattern, char *tail,
@@ -675,26 +678,26 @@ declare 166 {
}
# VFS-aware versions of Tcl*StartupScriptFileName (158 and 159 above)
-# REMOVED - use public Tcl_SetStartupScript()
-#declare 167 {
-# void TclSetStartupScriptPath(Tcl_Obj *pathPtr)
-#}
-# REMOVED - use public Tcl_GetStartupScript()
-#declare 168 {
-# Tcl_Obj *TclGetStartupScriptPath(void)
-#}
+# REMOVED (except from stub table) - use public Tcl_SetStartupScript()
+declare 167 {
+ void TclSetStartupScriptPath(Tcl_Obj *pathPtr)
+}
+# REMOVED (except from stub table) - use public Tcl_GetStartupScript()
+declare 168 {
+ Tcl_Obj *TclGetStartupScriptPath(void)
+}
# variant of Tcl_UtfNCmp that takes n as bytes, not chars
declare 169 {
int TclpUtfNcmp2(const char *s1, const char *s2, unsigned long n)
}
declare 170 {
int TclCheckInterpTraces(Tcl_Interp *interp, const char *command,
- int numChars, Command *cmdPtr, int result, int traceFlags,
+ int numChars, Command *cmdPtr, int result, int traceFlags,
int objc, Tcl_Obj *const objv[])
}
declare 171 {
int TclCheckExecutionTraces(Tcl_Interp *interp, const char *command,
- int numChars, Command *cmdPtr, int result, int traceFlags,
+ int numChars, Command *cmdPtr, int result, int traceFlags,
int objc, Tcl_Obj *const objv[])
}
declare 172 {
@@ -728,13 +731,13 @@ declare 177 {
void TclVarErrMsg(Tcl_Interp *interp, const char *part1, const char *part2,
const char *operation, const char *reason)
}
-# TIP 338 made these public - now declared in tcl.h
-#declare 178 {
-# void Tcl_SetStartupScript(Tcl_Obj *pathPtr, const char *encodingName)
-#}
-#declare 179 {
-# Tcl_Obj *Tcl_GetStartupScript(const char **encodingNamePtr)
-#}
+# TIP 338 made these public - now declared in tcl.h too
+declare 178 {
+ void Tcl_SetStartupScript(Tcl_Obj *pathPtr, const char *encodingName)
+}
+declare 179 {
+ Tcl_Obj *Tcl_GetStartupScript(const char **encodingNamePtr)
+}
# REMOVED
# Allocate lists without copying arrays
@@ -746,7 +749,7 @@ declare 177 {
# const char *file, int line)
#}
-# TclpGmtime and TclpLocaltime promoted to the interface from unix
+# TclpGmtime and TclpLocaltime promoted to the generic interface from unix
declare 182 {
struct tm *TclpLocaltime(const time_t *clock)
@@ -938,9 +941,9 @@ declare 235 {
# TIP 337 made this one public
-#declare 236 {
-# void TclBackgroundException(Tcl_Interp *interp, int code)
-#}
+declare 236 {
+ void TclBackgroundException(Tcl_Interp *interp, int code)
+}
# TIP #285: Script cancellation support.
declare 237 {
@@ -996,14 +999,19 @@ declare 248 {
}
declare 249 {
- char* TclDoubleDigits(double dv, int ndigits, int flags,
- int* decpt, int* signum, char** endPtr)
+ char *TclDoubleDigits(double dv, int ndigits, int flags,
+ int *decpt, int *signum, char **endPtr)
}
-
# TIP #285: Script cancellation support.
declare 250 {
void TclSetSlaveCancelFlags(Tcl_Interp *interp, int flags, int force)
}
+
+# Allow extensions for optimization
+declare 251 {
+ int TclRegisterLiteral(void *envPtr,
+ char *bytes, int length, int flags)
+}
##############################################################################
@@ -1016,10 +1024,10 @@ interface tclIntPlat
# Windows specific functions
declare 0 win {
- void TclWinConvertError(unsigned long errCode)
+ void TclWinConvertError(DWORD errCode)
}
declare 1 win {
- void TclWinConvertWSAError(unsigned long errCode)
+ void TclWinConvertWSAError(DWORD errCode)
}
declare 2 win {
struct servent *TclWinGetServByName(const char *nm,
@@ -1027,28 +1035,36 @@ declare 2 win {
}
declare 3 win {
int TclWinGetSockOpt(SOCKET s, int level, int optname,
- char FAR *optval, int FAR *optlen)
+ char *optval, int *optlen)
}
declare 4 win {
HINSTANCE TclWinGetTclInstance(void)
}
+# new for 8.4.20+/8.5.12+ Cygwin only
+declare 5 win {
+ int TclUnixWaitForFile(int fd, int mask, int timeout)
+}
# Removed in 8.1:
# declare 5 win {
# HINSTANCE TclWinLoadLibrary(char *name)
# }
declare 6 win {
- u_short TclWinNToHS(u_short ns)
+ unsigned short TclWinNToHS(unsigned short ns)
}
declare 7 win {
int TclWinSetSockOpt(SOCKET s, int level, int optname,
- const char FAR *optval, int optlen)
+ const char *optval, int optlen)
}
declare 8 win {
- unsigned long TclpGetPid(Tcl_Pid pid)
+ int TclpGetPid(Tcl_Pid pid)
}
declare 9 win {
int TclWinGetPlatformId(void)
}
+# new for 8.4.20+/8.5.12+ Cygwin only
+declare 10 win {
+ Tcl_DirEntry *TclpReaddir(DIR *dir)
+}
# Removed in 8.3.1 (for Win32s only)
#declare 10 win {
# int TclWinSynchSpawn(void *args, int type, void **trans, Tcl_Pid *pidPtr)
@@ -1070,9 +1086,13 @@ declare 14 win {
int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe)
}
declare 15 win {
- int TclpCreateProcess(Tcl_Interp *interp, int argc, const char **argv,
- TclFile inputFile, TclFile outputFile, TclFile errorFile,
- Tcl_Pid *pidPtr)
+ int TclpCreateProcess(Tcl_Interp *interp, int argc,
+ const char **argv, TclFile inputFile, TclFile outputFile,
+ TclFile errorFile, Tcl_Pid *pidPtr)
+}
+# new for 8.4.20+/8.5.12+ Cygwin only
+declare 16 win {
+ int TclpIsAtty(int fd)
}
# Signature changed in 8.1:
# declare 16 win {
@@ -1081,6 +1101,11 @@ declare 15 win {
# declare 17 win {
# char *TclpGetTZName(void)
# }
+# new for 8.5.12+ Cygwin only
+declare 17 win {
+ int TclUnixCopyFile(const char *src, const char *dst,
+ const Tcl_StatBuf *statBufPtr, int dontCopyAtts)
+}
declare 18 win {
TclFile TclpMakeFile(Tcl_Channel channel, int direction)
}
@@ -1088,9 +1113,12 @@ declare 19 win {
TclFile TclpOpenFile(const char *fname, int mode)
}
declare 20 win {
- void TclWinAddProcess(void *hProcess, unsigned long id)
+ void TclWinAddProcess(HANDLE hProcess, DWORD id)
+}
+# new for 8.4.20+/8.5.12+
+declare 21 win {
+ char *TclpInetNtoa(struct in_addr addr)
}
-
# removed permanently for 8.4
#declare 21 win {
# void TclpAsyncMark(Tcl_AsyncHandler async)
@@ -1100,13 +1128,14 @@ declare 20 win {
declare 22 win {
TclFile TclpCreateTempFile(const char *contents)
}
-declare 23 win {
- char *TclpGetTZName(int isdst)
-}
+# Removed in 8.6:
+#declare 23 win {
+# char *TclpGetTZName(int isdst)
+#}
declare 24 win {
char *TclWinNoBackslash(char *path)
}
-# replaced by TclGetPlatform
+# replaced by generic TclGetPlatform
#declare 25 win {
# TclPlatformType *TclWinGetPlatform(void)
#}
@@ -1125,9 +1154,6 @@ declare 27 win {
declare 28 win {
void TclWinResetInterfaces(void)
}
-declare 29 win {
- int TclWinCPUID(unsigned int index, unsigned int *regs)
-}
################################
# Unix specific functions
@@ -1148,9 +1174,9 @@ declare 3 unix {
int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe)
}
declare 4 unix {
- int TclpCreateProcess(Tcl_Interp *interp, int argc, const char **argv,
- TclFile inputFile, TclFile outputFile, TclFile errorFile,
- Tcl_Pid *pidPtr)
+ int TclpCreateProcess(Tcl_Interp *interp, int argc,
+ const char **argv, TclFile inputFile, TclFile outputFile,
+ TclFile errorFile, Tcl_Pid *pidPtr)
}
# Signature changed in 8.1:
# declare 5 unix {
@@ -1178,7 +1204,7 @@ declare 10 unix {
Tcl_DirEntry *TclpReaddir(DIR *dir)
}
# Slots 11 and 12 are forwarders for functions that were promoted to
-# Stubs
+# generic Stubs
declare 11 unix {
struct tm *TclpLocaltime_unix(const time_t *clock)
}
@@ -1220,6 +1246,16 @@ declare 19 macosx {
void TclMacOSXNotifierAddRunLoopMode(const void *runLoopMode)
}
+declare 29 {win unix} {
+ int TclWinCPUID(unsigned int index, unsigned int *regs)
+}
+# Added in 8.6; core of TclpOpenTemporaryFile
+declare 30 {win unix} {
+ int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj,
+ Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj)
+}
+
+
# Local Variables:
# mode: tcl
diff --git a/generic/tclInt.h b/generic/tclInt.h
index d65f712..7b1f5bf 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -23,7 +23,6 @@
* Some numerics configuration options.
*/
-#undef NO_WIDE_TYPE
#undef ACCEPT_NAN
/*
@@ -31,8 +30,7 @@
* here, so that system-dependent personalizations for the include files only
* have to be made in once place. This results in a few extra includes, but
* greater modularity. The order of the three groups of #includes is
- * important. For example, stdio.h is needed by tcl.h, and the _ANSI_ARGS_
- * declaration in tcl.h is needed by stdlib.h in some configurations.
+ * important. For example, stdio.h is needed by tcl.h.
*/
#include "tclPort.h"
@@ -96,14 +94,6 @@ typedef int ptrdiff_t;
#endif
/*
- * When Tcl_WideInt and long are the same type, there's no value in
- * having a tclWideIntType separate from the tclIntType.
- */
-#ifdef TCL_WIDE_INT_IS_LONG
-#define NO_WIDE_TYPE
-#endif
-
-/*
* Macros used to cast between pointers and integers (e.g. when storing an int
* in ClientData), on 64-bit architectures they avoid gcc warning about "cast
* to/from pointer from/to integer of different size".
@@ -128,6 +118,10 @@ typedef int ptrdiff_t;
# endif
#endif
+#if defined(_WIN32) && defined(_MSC_VER)
+# define vsnprintf _vsnprintf
+#endif
+
/*
* The following procedures allow namespaces to be customized to support
* special name resolution rules for commands/variables.
@@ -396,7 +390,7 @@ struct NamespacePathEntry {
/*
* The data cached in an ensemble subcommand's Tcl_Obj rep (reference in
- * otherValuePtr field). This structure is not shared between Tcl_Objs
+ * twoPtrValue.ptr1 field). This structure is not shared between Tcl_Objs
* referring to the same subcommand, even where one is a duplicate of another.
*/
@@ -589,30 +583,6 @@ typedef struct ActiveVarTrace {
} ActiveVarTrace;
/*
- * The following structure describes an enumerative search in progress on an
- * array variable; this are invoked with options to the "array" command.
- */
-
-typedef struct ArraySearch {
- int id; /* Integer id used to distinguish among
- * multiple concurrent searches for the same
- * array. */
- struct Var *varPtr; /* Pointer to array variable that's being
- * searched. */
- Tcl_HashSearch search; /* Info kept by the hash module about progress
- * through the array. */
- Tcl_HashEntry *nextEntry; /* Non-null means this is the next element to
- * be enumerated (it's leftover from the
- * Tcl_FirstHashEntry call or from an "array
- * anymore" command). NULL means must call
- * Tcl_NextHashEntry to get value to
- * return. */
- struct ArraySearch *nextPtr;/* Next in list of all active searches for
- * this variable, or NULL if this is the last
- * one. */
-} ArraySearch;
-
-/*
* The structure below defines a variable, which associates a string name with
* a Tcl_Obj value. These structures are kept in procedure call frames (for
* local variables recognized by the compiler) or in the heap (for global
@@ -801,13 +771,17 @@ typedef struct VarInHash {
#define TclSetVarNamespaceVar(varPtr) \
if (!TclIsVarNamespaceVar(varPtr)) {\
(varPtr)->flags |= VAR_NAMESPACE_VAR;\
- ((VarInHash *)(varPtr))->refCount++;\
+ if (TclIsVarInHash(varPtr)) {\
+ ((VarInHash *)(varPtr))->refCount++;\
+ }\
}
#define TclClearVarNamespaceVar(varPtr) \
if (TclIsVarNamespaceVar(varPtr)) {\
(varPtr)->flags &= ~VAR_NAMESPACE_VAR;\
- ((VarInHash *)(varPtr))->refCount--;\
+ if (TclIsVarInHash(varPtr)) {\
+ ((VarInHash *)(varPtr))->refCount--;\
+ }\
}
/*
@@ -1150,7 +1124,7 @@ typedef struct CallFrame {
* meaning of the value is, which we do not
* specify. */
LocalCache *localCachePtr;
- struct NRE_callback *tailcallPtr;
+ Tcl_Obj *tailcallPtr;
/* NULL if no tailcall is scheduled */
} CallFrame;
@@ -1201,29 +1175,27 @@ typedef struct CmdFrame {
*
* EXECUTION CONTEXTS and usage of CmdFrame
*
- * Field TEBC EvalEx EvalObjEx
- * ======= ==== ====== =========
- * level yes yes yes
- * type BC/PREBC SRC/EVAL EVAL_LIST
- * line0 yes yes yes
- * framePtr yes yes yes
- * ======= ==== ====== =========
+ * Field TEBC EvalEx
+ * ======= ==== ======
+ * level yes yes
+ * type BC/PREBC SRC/EVAL
+ * line0 yes yes
+ * framePtr yes yes
+ * ======= ==== ======
*
- * ======= ==== ====== ========= union data
- * line1 - yes -
- * line3 - yes -
- * path - yes -
- * ------- ---- ------ ---------
- * codePtr yes - -
- * pc yes - -
- * ======= ==== ====== =========
+ * ======= ==== ========= union data
+ * line1 - yes
+ * line3 - yes
+ * path - yes
+ * ------- ---- ------
+ * codePtr yes -
+ * pc yes -
+ * ======= ==== ======
*
- * ======= ==== ====== ========= | union cmd
- * listPtr - - yes |
- * ------- ---- ------ --------- |
- * cmd yes yes - |
- * cmdlen yes yes - |
- * ------- ---- ------ --------- |
+ * ======= ==== ========= union cmd
+ * str.cmd yes yes
+ * str.len yes yes
+ * ------- ---- ------
*/
union {
@@ -1236,15 +1208,9 @@ typedef struct CmdFrame {
const char *pc; /* ... and instruction pointer. */
} tebc;
} data;
- union {
- struct {
- const char *cmd; /* The executed command, if possible... */
- int len; /* ... and its length. */
- } str;
- Tcl_Obj *listPtr; /* Tcl_EvalObjEx, cmd list. */
- } cmd;
- int numLevels; /* Value of interp's numLevels when the frame
- * was pushed. */
+ Tcl_Obj *cmdObj;
+ const char *cmd; /* The executed command, if possible... */
+ int len; /* ... and its length. */
const struct CFWordBC *litarg;
/* Link to set of literal arguments which have
* ben pushed on the lineLABCPtr stack by
@@ -1308,8 +1274,6 @@ typedef struct ContLineLoc {
* location data referenced via the 'baseLocPtr'.
*
* TCL_LOCATION_EVAL : Frame is for a script evaluated by EvalEx.
- * TCL_LOCATION_EVAL_LIST : Frame is for a script evaluated by the list
- * optimization path of EvalObjEx.
* TCL_LOCATION_BC : Frame is for bytecode.
* TCL_LOCATION_PREBC : Frame is for precompiled bytecode.
* TCL_LOCATION_SOURCE : Frame is for a script evaluated by EvalEx, from a
@@ -1321,8 +1285,6 @@ typedef struct ContLineLoc {
*/
#define TCL_LOCATION_EVAL (0) /* Location in a dynamic eval script. */
-#define TCL_LOCATION_EVAL_LIST (1) /* Location in a dynamic eval script,
- * list-path. */
#define TCL_LOCATION_BC (2) /* Location in byte code. */
#define TCL_LOCATION_PREBC (3) /* Location in precompiled byte code, no
* location. */
@@ -1710,6 +1672,9 @@ typedef struct Command {
* CMD_HAS_EXEC_TRACES - 1 means that this command has at least one
* execution trace (as opposed to simple
* delete/rename traces) in its tracePtr list.
+ * CMD_COMPILES_EXPANDED - 1 means that this command has a compiler that
+ * can handle expansion (provided it is not the
+ * first word).
* TCL_TRACE_RENAME - A rename trace is in progress. Further
* recursive renames will not be traced.
* TCL_TRACE_DELETE - A delete trace is in progress. Further
@@ -1720,6 +1685,8 @@ typedef struct Command {
#define CMD_IS_DELETED 0x1
#define CMD_TRACE_ACTIVE 0x2
#define CMD_HAS_EXEC_TRACES 0x4
+#define CMD_COMPILES_EXPANDED 0x8
+#define CMD_REDEF_IN_PROGRESS 0x10
/*
*----------------------------------------------------------------
@@ -1843,7 +1810,14 @@ typedef struct Interp {
ClientData interpInfo; /* Information used by tclInterp.c to keep
* track of master/slave interps on a
* per-interp basis. */
- Tcl_HashTable unused2; /* No longer used (was mathFuncTable) */
+ union {
+ void (*optimizer)(void *envPtr);
+ Tcl_HashTable unused2; /* No longer used (was mathFuncTable). The
+ * unused space in interp was repurposed for
+ * pluggable bytecode optimizers. The core
+ * contains one optimizer, which can be
+ * selectively overriden by extensions. */
+ } extra;
/*
* Information related to procedures and variables. See tclProc.c and
@@ -2198,17 +2172,6 @@ typedef struct Interp {
(iPtr)->flags &= (~(CANCELED | TCL_CANCEL_UNWIND))
/*
- * General list of interpreters. Doubly linked for easier removal of items
- * deep in the list.
- */
-
-typedef struct InterpList {
- Interp *interpPtr;
- struct InterpList *prevPtr;
- struct InterpList *nextPtr;
-} InterpList;
-
-/*
* Macros for splicing into and out of doubly linked lists. They assume
* existence of struct items 'prevPtr' and 'nextPtr'.
*
@@ -2243,10 +2206,10 @@ typedef struct InterpList {
* other than these should be turned into errors.
*/
-#define TCL_ALLOW_EXCEPTIONS 4
-#define TCL_EVAL_FILE 2
-#define TCL_EVAL_CTX 8
-#define TCL_EVAL_REDIRECT 16
+#define TCL_ALLOW_EXCEPTIONS 0x04
+#define TCL_EVAL_FILE 0x02
+#define TCL_EVAL_SOURCE_IN_FRAME 0x10
+#define TCL_EVAL_NORESOLVE 0x20
/*
* Flag bits for Interp structures:
@@ -2314,35 +2277,6 @@ typedef struct InterpList {
#define MAX_NESTING_DEPTH 1000
/*
- * TIP#143 limit handler internal representation.
- */
-
-struct LimitHandler {
- int flags; /* The state of this particular handler. */
- Tcl_LimitHandlerProc *handlerProc;
- /* The handler callback. */
- ClientData clientData; /* Opaque argument to the handler callback. */
- Tcl_LimitHandlerDeleteProc *deleteProc;
- /* How to delete the clientData. */
- LimitHandler *prevPtr; /* Previous item in linked list of
- * handlers. */
- LimitHandler *nextPtr; /* Next item in linked list of handlers. */
-};
-
-/*
- * Values for the LimitHandler flags field.
- * LIMIT_HANDLER_ACTIVE - Whether the handler is currently being
- * processed; handlers are never to be entered reentrantly.
- * LIMIT_HANDLER_DELETED - Whether the handler has been deleted. This
- * should not normally be observed because when a handler is
- * deleted it is also spliced out of the list of handlers, but
- * even so we will be careful.
- */
-
-#define LIMIT_HANDLER_ACTIVE 0x01
-#define LIMIT_HANDLER_DELETED 0x02
-
-/*
* The macro below is used to modify a "char" value (e.g. by casting it to an
* unsigned character) so that it can be used safely with macros such as
* isspace.
@@ -2483,6 +2417,14 @@ typedef struct List {
(((listPtr)->typePtr == &tclListType) ? ListObjIsCanonical((listPtr)) : 0)
/*
+ * Modes for collecting (or not) in the implementations of TclNRForeachCmd,
+ * TclNRLmapCmd and their compilations.
+ */
+
+#define TCL_EACH_KEEP_NONE 0 /* Discard iteration result like [foreach] */
+#define TCL_EACH_COLLECT 1 /* Collect iteration result like [lmap] */
+
+/*
* Macros providing a faster path to integers: Tcl_GetLongFromObj everywhere,
* Tcl_GetIntFromObj and TclGetIntForIndex on platforms where longs are ints.
*
@@ -2552,6 +2494,8 @@ typedef struct List {
#define TCL_FILESYSTEM_VERSION_2 ((Tcl_FSVersion) 0x2)
typedef ClientData (TclFSGetCwdProc2)(ClientData clientData);
+typedef int (Tcl_FSLoadFileProc2) (Tcl_Interp *interp, Tcl_Obj *pathPtr,
+ Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr, int flags);
/*
* The following types are used for getting and storing platform-specific file
@@ -2696,6 +2640,8 @@ MODULE_SCOPE char *tclMemDumpFileName;
MODULE_SCOPE TclPlatformType tclPlatform;
MODULE_SCOPE Tcl_NotifierProcs tclNotifierHooks;
+MODULE_SCOPE Tcl_Encoding tclIdentityEncoding;
+
/*
* TIP #233 (Virtualized Time)
* Data for the time hooks, if any.
@@ -2722,7 +2668,7 @@ MODULE_SCOPE const Tcl_ObjType tclProcBodyType;
MODULE_SCOPE const Tcl_ObjType tclStringType;
MODULE_SCOPE const Tcl_ObjType tclArraySearchType;
MODULE_SCOPE const Tcl_ObjType tclEnsembleCmdType;
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
MODULE_SCOPE const Tcl_ObjType tclWideIntType;
#endif
MODULE_SCOPE const Tcl_ObjType tclRegexpType;
@@ -2768,27 +2714,36 @@ MODULE_SCOPE char tclEmptyString;
*/
MODULE_SCOPE Tcl_ObjCmdProc TclNRApplyObjCmd;
-MODULE_SCOPE Tcl_ObjCmdProc TclNRUplevelObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNREvalObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRCatchObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRExprObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRForObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRForeachCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRIfObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRLmapCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRSourceObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRSubstObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRSwitchObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRTryObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRUplevelObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRWhileObjCmd;
MODULE_SCOPE Tcl_NRPostProc TclNRForIterCallback;
+MODULE_SCOPE Tcl_NRPostProc TclNRCoroutineActivateCallback;
MODULE_SCOPE Tcl_ObjCmdProc TclNRTailcallObjCmd;
+MODULE_SCOPE Tcl_NRPostProc TclNRTailcallEval;
MODULE_SCOPE Tcl_ObjCmdProc TclNRCoroutineObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldmObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldToObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRInvoke;
-MODULE_SCOPE void TclSpliceTailcall(Tcl_Interp *interp,
- struct NRE_callback *tailcallPtr);
+MODULE_SCOPE void TclSetTailcall(Tcl_Interp *interp, Tcl_Obj *tailcallPtr);
+MODULE_SCOPE void TclPushTailcallPoint(Tcl_Interp *interp);
+
+/* These two can be considered for the public api */
+MODULE_SCOPE void TclMarkTailcall(Tcl_Interp *interp);
+MODULE_SCOPE void TclSkipTailcall(Tcl_Interp *interp);
/*
* This structure holds the data for the various iteration callbacks used to
@@ -2863,7 +2818,6 @@ MODULE_SCOPE void TclAppendBytesToByteArray(Tcl_Obj *objPtr,
const unsigned char *bytes, int len);
MODULE_SCOPE int TclNREvalCmd(Tcl_Interp *interp, Tcl_Obj *objPtr,
int flags);
-MODULE_SCOPE void TclPushTailcallPoint(Tcl_Interp *interp);
MODULE_SCOPE void TclAdvanceContinuations(int *line, int **next,
int loc);
MODULE_SCOPE void TclAdvanceLines(int *line, const char *start,
@@ -2874,7 +2828,7 @@ MODULE_SCOPE void TclArgumentRelease(Tcl_Interp *interp,
Tcl_Obj *objv[], int objc);
MODULE_SCOPE void TclArgumentBCEnter(Tcl_Interp *interp,
Tcl_Obj *objv[], int objc,
- void *codePtr, CmdFrame *cfPtr, int pc);
+ void *codePtr, CmdFrame *cfPtr, int cmd, int pc);
MODULE_SCOPE void TclArgumentBCRelease(Tcl_Interp *interp,
CmdFrame *cfPtr);
MODULE_SCOPE void TclArgumentGet(Tcl_Interp *interp, Tcl_Obj *obj,
@@ -2919,6 +2873,11 @@ MODULE_SCOPE void TclCreateLateExitHandler(Tcl_ExitProc *proc,
ClientData clientData);
MODULE_SCOPE void TclDeleteLateExitHandler(Tcl_ExitProc *proc,
ClientData clientData);
+MODULE_SCOPE char * TclDStringAppendObj(Tcl_DString *dsPtr,
+ Tcl_Obj *objPtr);
+MODULE_SCOPE char * TclDStringAppendDString(Tcl_DString *dsPtr,
+ Tcl_DString *toAppendPtr);
+MODULE_SCOPE Tcl_Obj * TclDStringToObj(Tcl_DString *dsPtr);
MODULE_SCOPE void TclFinalizeAllocSubsystem(void);
MODULE_SCOPE void TclFinalizeAsync(void);
MODULE_SCOPE void TclFinalizeDoubleConversion(void);
@@ -2937,6 +2896,7 @@ MODULE_SCOPE void TclFinalizeObjects(void);
MODULE_SCOPE void TclFinalizePreserve(void);
MODULE_SCOPE void TclFinalizeSynchronization(void);
MODULE_SCOPE void TclFinalizeThreadAlloc(void);
+MODULE_SCOPE void TclFinalizeThreadAllocThread(void);
MODULE_SCOPE void TclFinalizeThreadData(void);
MODULE_SCOPE void TclFinalizeThreadObjects(void);
MODULE_SCOPE double TclFloor(const mp_int *a);
@@ -2960,7 +2920,8 @@ MODULE_SCOPE int TclGetOpenModeEx(Tcl_Interp *interp,
const char *modeString, int *seekFlagPtr,
int *binaryPtr);
MODULE_SCOPE Tcl_Obj * TclGetProcessGlobalValue(ProcessGlobalValue *pgvPtr);
-MODULE_SCOPE const char *TclGetSrcInfoForCmd(Interp *iPtr, int *lenPtr);
+MODULE_SCOPE Tcl_Obj * TclGetSourceFromFrame(CmdFrame *cfPtr, int objc,
+ Tcl_Obj *const objv[]);
MODULE_SCOPE int TclGlob(Tcl_Interp *interp, char *pattern,
Tcl_Obj *unquotedPrefix, int globFlags,
Tcl_GlobTypeData *types);
@@ -2994,6 +2955,7 @@ MODULE_SCOPE void TclInitSubsystems(void);
MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp);
MODULE_SCOPE int TclIsLocalScalar(const char *src, int len);
MODULE_SCOPE int TclIsSpaceProc(char byte);
+MODULE_SCOPE Tcl_Obj * TclJoinPath(int elements, Tcl_Obj * const objv[]);
MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result);
MODULE_SCOPE void TclLimitRemoveAllHandlers(Tcl_Interp *interp);
MODULE_SCOPE Tcl_Obj * TclLindexList(Tcl_Interp *interp,
@@ -3062,12 +3024,6 @@ MODULE_SCOPE void TclpInitLibraryPath(char **valuePtr,
MODULE_SCOPE void TclpInitLock(void);
MODULE_SCOPE void TclpInitPlatform(void);
MODULE_SCOPE void TclpInitUnlock(void);
-MODULE_SCOPE int TclpLoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr,
- const char *sym1, const char *sym2,
- Tcl_PackageInitProc **proc1Ptr,
- Tcl_PackageInitProc **proc2Ptr,
- ClientData *clientDataPtr,
- Tcl_FSUnloadFileProc **unloadProcPtr);
MODULE_SCOPE Tcl_Obj * TclpObjListVolumes(void);
MODULE_SCOPE void TclpMasterLock(void);
MODULE_SCOPE void TclpMasterUnlock(void);
@@ -3114,6 +3070,7 @@ MODULE_SCOPE void TclSetBgErrorHandler(Tcl_Interp *interp,
Tcl_Obj *cmdPrefix);
MODULE_SCOPE void TclSetBignumIntRep(Tcl_Obj *objPtr,
mp_int *bignumValue);
+MODULE_SCOPE int TclSetBooleanFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
MODULE_SCOPE void TclSetCmdNameObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
Command *cmdPtr);
MODULE_SCOPE void TclSetDuplicateObj(Tcl_Obj *dupPtr, Tcl_Obj *objPtr);
@@ -3142,17 +3099,18 @@ MODULE_SCOPE int TclTrimLeft(const char *bytes, int numBytes,
const char *trim, int numTrim);
MODULE_SCOPE int TclTrimRight(const char *bytes, int numBytes,
const char *trim, int numTrim);
+MODULE_SCOPE int TclUtfCasecmp(const char *cs, const char *ct);
MODULE_SCOPE Tcl_Obj * TclpNativeToNormalized(ClientData clientData);
MODULE_SCOPE Tcl_Obj * TclpFilesystemPathType(Tcl_Obj *pathPtr);
MODULE_SCOPE int TclpDlopen(Tcl_Interp *interp, Tcl_Obj *pathPtr,
Tcl_LoadHandle *loadHandle,
- Tcl_FSUnloadFileProc **unloadProcPtr);
+ Tcl_FSUnloadFileProc **unloadProcPtr, int flags);
MODULE_SCOPE int TclpUtime(Tcl_Obj *pathPtr, struct utimbuf *tval);
#ifdef TCL_LOAD_FROM_MEMORY
MODULE_SCOPE void * TclpLoadMemoryGetBuffer(Tcl_Interp *interp, int size);
MODULE_SCOPE int TclpLoadMemory(Tcl_Interp *interp, void *buffer,
int size, int codeSize, Tcl_LoadHandle *loadHandle,
- Tcl_FSUnloadFileProc **unloadProcPtr);
+ Tcl_FSUnloadFileProc **unloadProcPtr, int flags);
#endif
MODULE_SCOPE void TclInitThreadStorage(void);
MODULE_SCOPE void TclFinalizeThreadDataThread(void);
@@ -3230,6 +3188,12 @@ MODULE_SCOPE int TclDefaultBgErrorHandlerObjCmd(
ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
MODULE_SCOPE Tcl_Command TclInitDictCmd(Tcl_Interp *interp);
+MODULE_SCOPE int TclDictWithFinish(Tcl_Interp *interp, Var *varPtr,
+ Var *arrayPtr, Tcl_Obj *part1Ptr,
+ Tcl_Obj *part2Ptr, int index, int pathc,
+ Tcl_Obj *const pathv[], Tcl_Obj *keysPtr);
+MODULE_SCOPE Tcl_Obj * TclDictWithInit(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+ int pathc, Tcl_Obj *const pathv[]);
MODULE_SCOPE int Tcl_DisassembleObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
@@ -3329,6 +3293,9 @@ MODULE_SCOPE int Tcl_LlengthObjCmd(ClientData clientData,
MODULE_SCOPE int Tcl_ListObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_LmapObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
MODULE_SCOPE int Tcl_LoadObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
@@ -3464,18 +3431,36 @@ MODULE_SCOPE int Tcl_WhileObjCmd(ClientData clientData,
MODULE_SCOPE int TclCompileAppendCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileArrayExistsCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileArraySetCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileArrayUnsetCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileBreakCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileCatchCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileConcatCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileContinueCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileDictAppendCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileDictCreateCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileDictExistsCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileDictForCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
@@ -3488,12 +3473,24 @@ MODULE_SCOPE int TclCompileDictIncrCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileDictLappendCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileDictMapCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileDictMergeCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileDictSetCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileDictUnsetCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileDictUpdateCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileDictWithCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileEnsemble(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
@@ -3509,15 +3506,36 @@ MODULE_SCOPE int TclCompileForCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileForeachCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileFormatCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileGlobalCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileIfCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileInfoCommandsCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileInfoCoroutineCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileInfoExistsCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileInfoLevelCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileInfoObjectClassCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileInfoObjectIsACmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileInfoObjectNamespaceCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileIncrCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
@@ -3530,24 +3548,66 @@ MODULE_SCOPE int TclCompileLassignCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileLindexCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileLinsertCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileListCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileLlengthCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileLmapCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileLrangeCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileLreplaceCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileLsetCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileNamespaceCodeCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileNamespaceCurrentCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileNamespaceOriginCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileNamespaceQualifiersCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileNamespaceTailCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileNamespaceUpvarCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileNamespaceWhichCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileNoOp(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileObjectNextCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileObjectNextToCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileObjectSelfCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileRegexpCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileRegsubCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileReturnCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
@@ -3560,21 +3620,60 @@ MODULE_SCOPE int TclCompileStringCmpCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileStringEqualCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStringFirstCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileStringIndexCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStringIsCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStringLastCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileStringLenCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStringMapCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileStringMatchCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStringRangeCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStringReplaceCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStringToLowerCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStringToTitleCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStringToUpperCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStringTrimCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStringTrimLCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStringTrimRCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileSubstCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileSwitchCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileTailcallCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileThrowCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
@@ -3593,6 +3692,48 @@ MODULE_SCOPE int TclCompileVariableCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileWhileCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileYieldCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileYieldToCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileBasic0ArgCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileBasic1ArgCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileBasic2ArgCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileBasic3ArgCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileBasic0Or1ArgCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileBasic1Or2ArgCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileBasic2Or3ArgCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileBasic0To2ArgCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileBasic1To3ArgCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileBasicMin0ArgCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileBasicMin1ArgCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileBasicMin2ArgCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclInvertOpCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
@@ -3770,6 +3911,8 @@ MODULE_SCOPE int TclPtrUnsetVar(Tcl_Interp *interp, Var *varPtr,
Tcl_Obj *part2Ptr, const int flags,
int index);
MODULE_SCOPE void TclInvalidateNsPath(Namespace *nsPtr);
+MODULE_SCOPE void TclFindArrayPtrElements(Var *arrayPtr,
+ Tcl_HashTable *tablePtr);
/*
* The new extended interface to the variable traces.
@@ -3885,12 +4028,13 @@ typedef const char *TclDTraceStr;
*/
# define TclAllocObjStorageEx(interp, objPtr) \
- (objPtr) = (Tcl_Obj *) Tcl_Alloc(sizeof(Tcl_Obj))
+ (objPtr) = (Tcl_Obj *) ckalloc(sizeof(Tcl_Obj))
# define TclFreeObjStorageEx(interp, objPtr) \
ckfree((char *) (objPtr))
#undef USE_THREAD_ALLOC
+#undef USE_TCLALLOC
#elif defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
/*
@@ -3926,7 +4070,7 @@ MODULE_SCOPE void TclpFreeAllocCache(void *);
(objPtr) = TclThreadAllocObj(); \
} else { \
(objPtr) = cachePtr->firstObjPtr; \
- cachePtr->firstObjPtr = (objPtr)->internalRep.otherValuePtr; \
+ cachePtr->firstObjPtr = (objPtr)->internalRep.twoPtrValue.ptr1; \
--cachePtr->numObjects; \
} \
} while (0)
@@ -3939,7 +4083,7 @@ MODULE_SCOPE void TclpFreeAllocCache(void *);
(cachePtr->numObjects >= ALLOC_NOBJHIGH))) { \
TclThreadFreeObj(objPtr); \
} else { \
- (objPtr)->internalRep.otherValuePtr = cachePtr->firstObjPtr; \
+ (objPtr)->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr; \
cachePtr->firstObjPtr = objPtr; \
++cachePtr->numObjects; \
} \
@@ -3967,14 +4111,14 @@ MODULE_SCOPE Tcl_Mutex tclObjMutex;
} \
(objPtr) = tclFreeObjList; \
tclFreeObjList = (Tcl_Obj *) \
- tclFreeObjList->internalRep.otherValuePtr; \
+ tclFreeObjList->internalRep.twoPtrValue.ptr1; \
Tcl_MutexUnlock(&tclObjMutex); \
} while (0)
# define TclFreeObjStorageEx(interp, objPtr) \
do { \
Tcl_MutexLock(&tclObjMutex); \
- (objPtr)->internalRep.otherValuePtr = (void *) tclFreeObjList; \
+ (objPtr)->internalRep.twoPtrValue.ptr1 = (void *) tclFreeObjList; \
tclFreeObjList = (objPtr); \
Tcl_MutexUnlock(&tclObjMutex); \
} while (0)
@@ -4309,7 +4453,7 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
*----------------------------------------------------------------
*/
-#define TclSetIntObj(objPtr, i) \
+#define TclSetLongObj(objPtr, i) \
do { \
TclInvalidateStringRep(objPtr); \
TclFreeIntRep(objPtr); \
@@ -4317,8 +4461,8 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
(objPtr)->typePtr = &tclIntType; \
} while (0)
-#define TclSetLongObj(objPtr, l) \
- TclSetIntObj((objPtr), (l))
+#define TclSetIntObj(objPtr, l) \
+ TclSetLongObj(objPtr, l)
/*
* NOTE: There is to be no such thing as a "pure" boolean. Boolean values set
@@ -4328,9 +4472,9 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
*/
#define TclSetBooleanObj(objPtr, b) \
- TclSetIntObj((objPtr), ((b)? 1 : 0));
+ TclSetLongObj(objPtr, (b)!=0);
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
#define TclSetWideIntObj(objPtr, w) \
do { \
TclInvalidateStringRep(objPtr); \
@@ -4366,7 +4510,7 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
*/
#ifndef TCL_MEM_DEBUG
-#define TclNewIntObj(objPtr, i) \
+#define TclNewLongObj(objPtr, i) \
do { \
TclIncrObjsAllocated(); \
TclAllocObjStorage(objPtr); \
@@ -4377,15 +4521,15 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
TCL_DTRACE_OBJ_CREATE(objPtr); \
} while (0)
-#define TclNewLongObj(objPtr, l) \
- TclNewIntObj((objPtr), (l))
+#define TclNewIntObj(objPtr, l) \
+ TclNewLongObj(objPtr, l)
/*
* NOTE: There is to be no such thing as a "pure" boolean.
* See comment above TclSetBooleanObj macro above.
*/
#define TclNewBooleanObj(objPtr, b) \
- TclNewIntObj((objPtr), ((b)? 1 : 0))
+ TclNewLongObj((objPtr), (b)!=0)
#define TclNewDoubleObj(objPtr, d) \
do { \
@@ -4434,6 +4578,21 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
/*
*----------------------------------------------------------------
+ * Convenience macros for DStrings.
+ * The ANSI C "prototypes" for these macros are:
+ *
+ * MODULE_SCOPE char * TclDStringAppendLiteral(Tcl_DString *dsPtr,
+ * const char *sLiteral);
+ * MODULE_SCOPE void TclDStringClear(Tcl_DString *dsPtr);
+ */
+
+#define TclDStringAppendLiteral(dsPtr, sLiteral) \
+ Tcl_DStringAppend((dsPtr), (sLiteral), (int) (sizeof(sLiteral "") - 1))
+#define TclDStringClear(dsPtr) \
+ Tcl_DStringSetLength((dsPtr), 0)
+
+/*
+ *----------------------------------------------------------------
* Macros used by the Tcl core to test for some special double values.
* The ANSI C "prototypes" for these macros are:
*
@@ -4633,35 +4792,6 @@ typedef struct NRE_callback {
TOP_CB(interp) = callbackPtr; \
} while (0)
-#define TclNRDeferCallback(interp,postProcPtr,data0,data1,data2,data3) \
- do { \
- NRE_callback *callbackPtr; \
- TCLNR_ALLOC((interp), (callbackPtr)); \
- callbackPtr->procPtr = (postProcPtr); \
- callbackPtr->data[0] = (ClientData)(data0); \
- callbackPtr->data[1] = (ClientData)(data1); \
- callbackPtr->data[2] = (ClientData)(data2); \
- callbackPtr->data[3] = (ClientData)(data3); \
- callbackPtr->nextPtr = ((Interp *)interp)->deferredCallbacks; \
- ((Interp *)interp)->deferredCallbacks = callbackPtr; \
- } while (0)
-
-#define TclNRSpliceCallbacks(interp, topPtr) \
- do { \
- NRE_callback *bottomPtr = topPtr; \
- while (bottomPtr->nextPtr) { \
- bottomPtr = bottomPtr->nextPtr; \
- } \
- bottomPtr->nextPtr = TOP_CB(interp); \
- TOP_CB(interp) = topPtr; \
- } while (0)
-
-#define TclNRSpliceDeferred(interp) \
- if (((Interp *)interp)->deferredCallbacks) { \
- TclNRSpliceCallbacks(interp, ((Interp *)interp)->deferredCallbacks); \
- ((Interp *)interp)->deferredCallbacks = NULL; \
- }
-
#if NRE_USE_SMALL_ALLOC
#define TCLNR_ALLOC(interp, ptr) \
TclSmallAllocEx(interp, sizeof(NRE_callback), (ptr))
diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h
index b294e4f..f95f999 100644
--- a/generic/tclIntDecls.h
+++ b/generic/tclIntDecls.h
@@ -29,19 +29,20 @@
#endif
/* [Bug #803489] Tcl_FindNamespace problem in the Stubs table */
-#undef Tcl_AppendExportList
#undef Tcl_CreateNamespace
#undef Tcl_DeleteNamespace
+#undef Tcl_AppendExportList
#undef Tcl_Export
-#undef Tcl_FindCommand
-#undef Tcl_FindNamespace
-#undef Tcl_FindNamespaceVar
+#undef Tcl_Import
#undef Tcl_ForgetImport
-#undef Tcl_GetCommandFromObj
-#undef Tcl_GetCommandFullName
#undef Tcl_GetCurrentNamespace
#undef Tcl_GetGlobalNamespace
-#undef Tcl_Import
+#undef Tcl_FindNamespace
+#undef Tcl_FindCommand
+#undef Tcl_GetCommandFromObj
+#undef Tcl_GetCommandFullName
+#undef Tcl_SetStartupScript
+#undef Tcl_GetStartupScript
/*
* WARNING: This file is automatically generated by the tools/genStubs.tcl
@@ -51,6 +52,10 @@
/* !BEGIN!: Do not edit below this line. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Exported function declarations:
*/
@@ -214,8 +219,7 @@ EXTERN unsigned long TclpGetClicks(void);
EXTERN unsigned long TclpGetSeconds(void);
/* 77 */
EXTERN void TclpGetTime(Tcl_Time *time);
-/* 78 */
-EXTERN int TclpGetTimeZone(unsigned long time);
+/* Slot 78 is reserved */
/* Slot 79 is reserved */
/* Slot 80 is reserved */
/* 81 */
@@ -263,7 +267,7 @@ EXTERN void TclSetupEnv(Tcl_Interp *interp);
EXTERN int TclSockGetPort(Tcl_Interp *interp, const char *str,
const char *proto, int *portPtr);
/* 104 */
-EXTERN int TclSockMinimumBuffers(ClientData sock, int size);
+EXTERN int TclSockMinimumBuffersOld(int sock, int size);
/* Slot 105 is reserved */
/* Slot 106 is reserved */
/* Slot 107 is reserved */
@@ -271,7 +275,8 @@ EXTERN int TclSockMinimumBuffers(ClientData sock, int size);
EXTERN void TclTeardownNamespace(Namespace *nsPtr);
/* 109 */
EXTERN int TclUpdateReturnInfo(Interp *iPtr);
-/* Slot 110 is reserved */
+/* 110 */
+EXTERN int TclSockMinimumBuffers(void *sock, int size);
/* 111 */
EXTERN void Tcl_AddInterpResolvers(Tcl_Interp *interp,
const char *name,
@@ -395,8 +400,10 @@ EXTERN void TclRegError(Tcl_Interp *interp, const char *msg,
/* 157 */
EXTERN Var * TclVarTraceExists(Tcl_Interp *interp,
const char *varName);
-/* Slot 158 is reserved */
-/* Slot 159 is reserved */
+/* 158 */
+EXTERN void TclSetStartupScriptFileName(const char *filename);
+/* 159 */
+EXTERN const char * TclGetStartupScriptFileName(void);
/* Slot 160 is reserved */
/* 161 */
EXTERN int TclChannelTransform(Tcl_Interp *interp,
@@ -414,8 +421,10 @@ EXTERN void TclpSetInitialEncodings(void);
EXTERN int TclListObjSetElement(Tcl_Interp *interp,
Tcl_Obj *listPtr, int index,
Tcl_Obj *valuePtr);
-/* Slot 167 is reserved */
-/* Slot 168 is reserved */
+/* 167 */
+EXTERN void TclSetStartupScriptPath(Tcl_Obj *pathPtr);
+/* 168 */
+EXTERN Tcl_Obj * TclGetStartupScriptPath(void);
/* 169 */
EXTERN int TclpUtfNcmp2(const char *s1, const char *s2,
unsigned long n);
@@ -447,8 +456,11 @@ EXTERN void TclCleanupVar(Var *varPtr, Var *arrayPtr);
EXTERN void TclVarErrMsg(Tcl_Interp *interp, const char *part1,
const char *part2, const char *operation,
const char *reason);
-/* Slot 178 is reserved */
-/* Slot 179 is reserved */
+/* 178 */
+EXTERN void Tcl_SetStartupScript(Tcl_Obj *pathPtr,
+ const char *encodingName);
+/* 179 */
+EXTERN Tcl_Obj * Tcl_GetStartupScript(const char **encodingNamePtr);
/* Slot 180 is reserved */
/* Slot 181 is reserved */
/* 182 */
@@ -557,7 +569,8 @@ EXTERN Var * TclVarHashCreateVar(TclVarHashTable *tablePtr,
/* 235 */
EXTERN void TclInitVarHashTable(TclVarHashTable *tablePtr,
Namespace *nsPtr);
-/* Slot 236 is reserved */
+/* 236 */
+EXTERN void TclBackgroundException(Tcl_Interp *interp, int code);
/* 237 */
EXTERN int TclResetCancellation(Tcl_Interp *interp, int force);
/* 238 */
@@ -596,15 +609,18 @@ EXTERN int TclCopyChannel(Tcl_Interp *interp,
Tcl_Channel inChan, Tcl_Channel outChan,
Tcl_WideInt toRead, Tcl_Obj *cmdPtr);
/* 249 */
-EXTERN char* TclDoubleDigits(double dv, int ndigits, int flags,
- int*decpt, int*signum, char**endPtr);
+EXTERN char * TclDoubleDigits(double dv, int ndigits, int flags,
+ int *decpt, int *signum, char **endPtr);
/* 250 */
EXTERN void TclSetSlaveCancelFlags(Tcl_Interp *interp, int flags,
int force);
+/* 251 */
+EXTERN int TclRegisterLiteral(void *envPtr, char *bytes,
+ int length, int flags);
typedef struct TclIntStubs {
int magic;
- const struct TclIntStubHooks *hooks;
+ void *hooks;
void (*reserved0)(void);
void (*reserved1)(void);
@@ -684,7 +700,7 @@ typedef struct TclIntStubs {
unsigned long (*tclpGetClicks) (void); /* 75 */
unsigned long (*tclpGetSeconds) (void); /* 76 */
void (*tclpGetTime) (Tcl_Time *time); /* 77 */
- int (*tclpGetTimeZone) (unsigned long time); /* 78 */
+ void (*reserved78)(void);
void (*reserved79)(void);
void (*reserved80)(void);
char * (*tclpRealloc) (char *ptr, unsigned int size); /* 81 */
@@ -710,13 +726,13 @@ typedef struct TclIntStubs {
CONST86 char * (*tclSetPreInitScript) (const char *string); /* 101 */
void (*tclSetupEnv) (Tcl_Interp *interp); /* 102 */
int (*tclSockGetPort) (Tcl_Interp *interp, const char *str, const char *proto, int *portPtr); /* 103 */
- int (*tclSockMinimumBuffers) (ClientData sock, int size); /* 104 */
+ int (*tclSockMinimumBuffersOld) (int sock, int size); /* 104 */
void (*reserved105)(void);
void (*reserved106)(void);
void (*reserved107)(void);
void (*tclTeardownNamespace) (Namespace *nsPtr); /* 108 */
int (*tclUpdateReturnInfo) (Interp *iPtr); /* 109 */
- void (*reserved110)(void);
+ int (*tclSockMinimumBuffers) (void *sock, int size); /* 110 */
void (*tcl_AddInterpResolvers) (Tcl_Interp *interp, const char *name, Tcl_ResolveCmdProc *cmdProc, Tcl_ResolveVarProc *varProc, Tcl_ResolveCompiledVarProc *compiledVarProc); /* 111 */
int (*tcl_AppendExportList) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, Tcl_Obj *objPtr); /* 112 */
Tcl_Namespace * (*tcl_CreateNamespace) (Tcl_Interp *interp, const char *name, ClientData clientData, Tcl_NamespaceDeleteProc *deleteProc); /* 113 */
@@ -764,8 +780,8 @@ typedef struct TclIntStubs {
void (*reserved155)(void);
void (*tclRegError) (Tcl_Interp *interp, const char *msg, int status); /* 156 */
Var * (*tclVarTraceExists) (Tcl_Interp *interp, const char *varName); /* 157 */
- void (*reserved158)(void);
- void (*reserved159)(void);
+ void (*tclSetStartupScriptFileName) (const char *filename); /* 158 */
+ const char * (*tclGetStartupScriptFileName) (void); /* 159 */
void (*reserved160)(void);
int (*tclChannelTransform) (Tcl_Interp *interp, Tcl_Channel chan, Tcl_Obj *cmdObjPtr); /* 161 */
void (*tclChannelEventScriptInvoker) (ClientData clientData, int flags); /* 162 */
@@ -773,8 +789,8 @@ typedef struct TclIntStubs {
void (*tclExpandCodeArray) (void *envPtr); /* 164 */
void (*tclpSetInitialEncodings) (void); /* 165 */
int (*tclListObjSetElement) (Tcl_Interp *interp, Tcl_Obj *listPtr, int index, Tcl_Obj *valuePtr); /* 166 */
- void (*reserved167)(void);
- void (*reserved168)(void);
+ void (*tclSetStartupScriptPath) (Tcl_Obj *pathPtr); /* 167 */
+ Tcl_Obj * (*tclGetStartupScriptPath) (void); /* 168 */
int (*tclpUtfNcmp2) (const char *s1, const char *s2, unsigned long n); /* 169 */
int (*tclCheckInterpTraces) (Tcl_Interp *interp, const char *command, int numChars, Command *cmdPtr, int result, int traceFlags, int objc, Tcl_Obj *const objv[]); /* 170 */
int (*tclCheckExecutionTraces) (Tcl_Interp *interp, const char *command, int numChars, Command *cmdPtr, int result, int traceFlags, int objc, Tcl_Obj *const objv[]); /* 171 */
@@ -784,8 +800,8 @@ typedef struct TclIntStubs {
int (*tclCallVarTraces) (Interp *iPtr, Var *arrayPtr, Var *varPtr, const char *part1, const char *part2, int flags, int leaveErrMsg); /* 175 */
void (*tclCleanupVar) (Var *varPtr, Var *arrayPtr); /* 176 */
void (*tclVarErrMsg) (Tcl_Interp *interp, const char *part1, const char *part2, const char *operation, const char *reason); /* 177 */
- void (*reserved178)(void);
- void (*reserved179)(void);
+ void (*tcl_SetStartupScript) (Tcl_Obj *pathPtr, const char *encodingName); /* 178 */
+ Tcl_Obj * (*tcl_GetStartupScript) (const char **encodingNamePtr); /* 179 */
void (*reserved180)(void);
void (*reserved181)(void);
struct tm * (*tclpLocaltime) (const time_t *clock); /* 182 */
@@ -842,7 +858,7 @@ typedef struct TclIntStubs {
void (*tclGetSrcInfoForPc) (CmdFrame *contextPtr); /* 233 */
Var * (*tclVarHashCreateVar) (TclVarHashTable *tablePtr, const char *key, int *newPtr); /* 234 */
void (*tclInitVarHashTable) (TclVarHashTable *tablePtr, Namespace *nsPtr); /* 235 */
- void (*reserved236)(void);
+ void (*tclBackgroundException) (Tcl_Interp *interp, int code); /* 236 */
int (*tclResetCancellation) (Tcl_Interp *interp, int force); /* 237 */
int (*tclNRInterpProc) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 238 */
int (*tclNRInterpProcCore) (Tcl_Interp *interp, Tcl_Obj *procNameObj, int skip, ProcErrorProc *errorProc); /* 239 */
@@ -855,14 +871,13 @@ typedef struct TclIntStubs {
int (*tclInitRewriteEnsemble) (Tcl_Interp *interp, int numRemoved, int numInserted, Tcl_Obj *const *objv); /* 246 */
void (*tclResetRewriteEnsemble) (Tcl_Interp *interp, int isRootEnsemble); /* 247 */
int (*tclCopyChannel) (Tcl_Interp *interp, Tcl_Channel inChan, Tcl_Channel outChan, Tcl_WideInt toRead, Tcl_Obj *cmdPtr); /* 248 */
- char* (*tclDoubleDigits) (double dv, int ndigits, int flags, int*decpt, int*signum, char**endPtr); /* 249 */
+ char * (*tclDoubleDigits) (double dv, int ndigits, int flags, int *decpt, int *signum, char **endPtr); /* 249 */
void (*tclSetSlaveCancelFlags) (Tcl_Interp *interp, int flags, int force); /* 250 */
+ int (*tclRegisterLiteral) (void *envPtr, char *bytes, int length, int flags); /* 251 */
} TclIntStubs;
-#ifdef __cplusplus
-extern "C" {
-#endif
extern const TclIntStubs *tclIntStubsPtr;
+
#ifdef __cplusplus
}
#endif
@@ -995,8 +1010,7 @@ extern const TclIntStubs *tclIntStubsPtr;
(tclIntStubsPtr->tclpGetSeconds) /* 76 */
#define TclpGetTime \
(tclIntStubsPtr->tclpGetTime) /* 77 */
-#define TclpGetTimeZone \
- (tclIntStubsPtr->tclpGetTimeZone) /* 78 */
+/* Slot 78 is reserved */
/* Slot 79 is reserved */
/* Slot 80 is reserved */
#define TclpRealloc \
@@ -1034,8 +1048,8 @@ extern const TclIntStubs *tclIntStubsPtr;
(tclIntStubsPtr->tclSetupEnv) /* 102 */
#define TclSockGetPort \
(tclIntStubsPtr->tclSockGetPort) /* 103 */
-#define TclSockMinimumBuffers \
- (tclIntStubsPtr->tclSockMinimumBuffers) /* 104 */
+#define TclSockMinimumBuffersOld \
+ (tclIntStubsPtr->tclSockMinimumBuffersOld) /* 104 */
/* Slot 105 is reserved */
/* Slot 106 is reserved */
/* Slot 107 is reserved */
@@ -1043,7 +1057,8 @@ extern const TclIntStubs *tclIntStubsPtr;
(tclIntStubsPtr->tclTeardownNamespace) /* 108 */
#define TclUpdateReturnInfo \
(tclIntStubsPtr->tclUpdateReturnInfo) /* 109 */
-/* Slot 110 is reserved */
+#define TclSockMinimumBuffers \
+ (tclIntStubsPtr->tclSockMinimumBuffers) /* 110 */
#define Tcl_AddInterpResolvers \
(tclIntStubsPtr->tcl_AddInterpResolvers) /* 111 */
#define Tcl_AppendExportList \
@@ -1130,8 +1145,10 @@ extern const TclIntStubs *tclIntStubsPtr;
(tclIntStubsPtr->tclRegError) /* 156 */
#define TclVarTraceExists \
(tclIntStubsPtr->tclVarTraceExists) /* 157 */
-/* Slot 158 is reserved */
-/* Slot 159 is reserved */
+#define TclSetStartupScriptFileName \
+ (tclIntStubsPtr->tclSetStartupScriptFileName) /* 158 */
+#define TclGetStartupScriptFileName \
+ (tclIntStubsPtr->tclGetStartupScriptFileName) /* 159 */
/* Slot 160 is reserved */
#define TclChannelTransform \
(tclIntStubsPtr->tclChannelTransform) /* 161 */
@@ -1145,8 +1162,10 @@ extern const TclIntStubs *tclIntStubsPtr;
(tclIntStubsPtr->tclpSetInitialEncodings) /* 165 */
#define TclListObjSetElement \
(tclIntStubsPtr->tclListObjSetElement) /* 166 */
-/* Slot 167 is reserved */
-/* Slot 168 is reserved */
+#define TclSetStartupScriptPath \
+ (tclIntStubsPtr->tclSetStartupScriptPath) /* 167 */
+#define TclGetStartupScriptPath \
+ (tclIntStubsPtr->tclGetStartupScriptPath) /* 168 */
#define TclpUtfNcmp2 \
(tclIntStubsPtr->tclpUtfNcmp2) /* 169 */
#define TclCheckInterpTraces \
@@ -1164,8 +1183,10 @@ extern const TclIntStubs *tclIntStubsPtr;
(tclIntStubsPtr->tclCleanupVar) /* 176 */
#define TclVarErrMsg \
(tclIntStubsPtr->tclVarErrMsg) /* 177 */
-/* Slot 178 is reserved */
-/* Slot 179 is reserved */
+#define Tcl_SetStartupScript \
+ (tclIntStubsPtr->tcl_SetStartupScript) /* 178 */
+#define Tcl_GetStartupScript \
+ (tclIntStubsPtr->tcl_GetStartupScript) /* 179 */
/* Slot 180 is reserved */
/* Slot 181 is reserved */
#define TclpLocaltime \
@@ -1252,7 +1273,8 @@ extern const TclIntStubs *tclIntStubsPtr;
(tclIntStubsPtr->tclVarHashCreateVar) /* 234 */
#define TclInitVarHashTable \
(tclIntStubsPtr->tclInitVarHashTable) /* 235 */
-/* Slot 236 is reserved */
+#define TclBackgroundException \
+ (tclIntStubsPtr->tclBackgroundException) /* 236 */
#define TclResetCancellation \
(tclIntStubsPtr->tclResetCancellation) /* 237 */
#define TclNRInterpProc \
@@ -1281,6 +1303,8 @@ extern const TclIntStubs *tclIntStubsPtr;
(tclIntStubsPtr->tclDoubleDigits) /* 249 */
#define TclSetSlaveCancelFlags \
(tclIntStubsPtr->tclSetSlaveCancelFlags) /* 250 */
+#define TclRegisterLiteral \
+ (tclIntStubsPtr->tclRegisterLiteral) /* 251 */
#endif /* defined(USE_TCL_STUBS) */
@@ -1289,4 +1313,58 @@ extern const TclIntStubs *tclIntStubsPtr;
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
+#undef TclGetStartupScriptFileName
+#undef TclSetStartupScriptFileName
+#undef TclGetStartupScriptPath
+#undef TclSetStartupScriptPath
+#undef TclBackgroundException
+
+#if defined(USE_TCL_STUBS) && defined(TCL_NO_DEPRECATED)
+# undef Tcl_SetStartupScript
+# define Tcl_SetStartupScript \
+ (tclStubsPtr->tcl_SetStartupScript) /* 622 */
+# undef Tcl_GetStartupScript
+# define Tcl_GetStartupScript \
+ (tclStubsPtr->tcl_GetStartupScript) /* 623 */
+# undef Tcl_CreateNamespace
+# define Tcl_CreateNamespace \
+ (tclStubsPtr->tcl_CreateNamespace) /* 506 */
+# undef Tcl_DeleteNamespace
+# define Tcl_DeleteNamespace \
+ (tclStubsPtr->tcl_DeleteNamespace) /* 507 */
+# undef Tcl_AppendExportList
+# define Tcl_AppendExportList \
+ (tclStubsPtr->tcl_AppendExportList) /* 508 */
+# undef Tcl_Export
+# define Tcl_Export \
+ (tclStubsPtr->tcl_Export) /* 509 */
+# undef Tcl_Import
+# define Tcl_Import \
+ (tclStubsPtr->tcl_Import) /* 510 */
+# undef Tcl_ForgetImport
+# define Tcl_ForgetImport \
+ (tclStubsPtr->tcl_ForgetImport) /* 511 */
+# undef Tcl_GetCurrentNamespace
+# define Tcl_GetCurrentNamespace \
+ (tclStubsPtr->tcl_GetCurrentNamespace) /* 512 */
+# undef Tcl_GetGlobalNamespace
+# define Tcl_GetGlobalNamespace \
+ (tclStubsPtr->tcl_GetGlobalNamespace) /* 513 */
+# undef Tcl_FindNamespace
+# define Tcl_FindNamespace \
+ (tclStubsPtr->tcl_FindNamespace) /* 514 */
+# undef Tcl_FindCommand
+# define Tcl_FindCommand \
+ (tclStubsPtr->tcl_FindCommand) /* 515 */
+# undef Tcl_GetCommandFromObj
+# define Tcl_GetCommandFromObj \
+ (tclStubsPtr->tcl_GetCommandFromObj) /* 516 */
+# undef Tcl_GetCommandFullName
+# define Tcl_GetCommandFullName \
+ (tclStubsPtr->tcl_GetCommandFullName) /* 517 */
+#endif
+
+#undef TclCopyChannelOld
+#undef TclSockMinimumBuffersOld
+
#endif /* _TCLINTDECLS */
diff --git a/generic/tclIntPlatDecls.h b/generic/tclIntPlatDecls.h
index 0f1c0d1..ac06787 100644
--- a/generic/tclIntPlatDecls.h
+++ b/generic/tclIntPlatDecls.h
@@ -13,6 +13,11 @@
#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
@@ -32,11 +37,15 @@
/* !BEGIN!: Do not edit below this line. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Exported function declarations:
*/
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
/* 0 */
EXTERN void TclGetAndDetachPids(Tcl_Interp *interp,
Tcl_Channel chan);
@@ -74,31 +83,53 @@ EXTERN char * TclpInetNtoa(struct in_addr addr);
EXTERN int TclUnixCopyFile(const char *src, const char *dst,
const Tcl_StatBuf *statBufPtr,
int dontCopyAtts);
+/* Slot 15 is reserved */
+/* Slot 16 is reserved */
+/* Slot 17 is reserved */
+/* Slot 18 is reserved */
+/* Slot 19 is reserved */
+/* Slot 20 is reserved */
+/* Slot 21 is reserved */
+/* Slot 22 is reserved */
+/* Slot 23 is reserved */
+/* Slot 24 is reserved */
+/* Slot 25 is reserved */
+/* Slot 26 is reserved */
+/* Slot 27 is reserved */
+/* Slot 28 is reserved */
+/* 29 */
+EXTERN int TclWinCPUID(unsigned int index, unsigned int *regs);
+/* 30 */
+EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
+ Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
+ Tcl_Obj *resultingNameObj);
#endif /* UNIX */
-#ifdef __WIN32__ /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
/* 0 */
-EXTERN void TclWinConvertError(unsigned long errCode);
+EXTERN void TclWinConvertError(DWORD errCode);
/* 1 */
-EXTERN void TclWinConvertWSAError(unsigned long errCode);
+EXTERN void TclWinConvertWSAError(DWORD errCode);
/* 2 */
EXTERN struct servent * TclWinGetServByName(const char *nm,
const char *proto);
/* 3 */
EXTERN int TclWinGetSockOpt(SOCKET s, int level, int optname,
- char FAR *optval, int FAR *optlen);
+ char *optval, int *optlen);
/* 4 */
EXTERN HINSTANCE TclWinGetTclInstance(void);
-/* Slot 5 is reserved */
+/* 5 */
+EXTERN int TclUnixWaitForFile(int fd, int mask, int timeout);
/* 6 */
-EXTERN u_short TclWinNToHS(u_short ns);
+EXTERN unsigned short TclWinNToHS(unsigned short ns);
/* 7 */
EXTERN int TclWinSetSockOpt(SOCKET s, int level, int optname,
- const char FAR *optval, int optlen);
+ const char *optval, int optlen);
/* 8 */
-EXTERN unsigned long TclpGetPid(Tcl_Pid pid);
+EXTERN int TclpGetPid(Tcl_Pid pid);
/* 9 */
EXTERN int TclWinGetPlatformId(void);
-/* Slot 10 is reserved */
+/* 10 */
+EXTERN Tcl_DirEntry * TclpReaddir(DIR *dir);
/* 11 */
EXTERN void TclGetAndDetachPids(Tcl_Interp *interp,
Tcl_Channel chan);
@@ -115,19 +146,23 @@ EXTERN int TclpCreateProcess(Tcl_Interp *interp, int argc,
const char **argv, TclFile inputFile,
TclFile outputFile, TclFile errorFile,
Tcl_Pid *pidPtr);
-/* Slot 16 is reserved */
-/* Slot 17 is reserved */
+/* 16 */
+EXTERN int TclpIsAtty(int fd);
+/* 17 */
+EXTERN int TclUnixCopyFile(const char *src, const char *dst,
+ const Tcl_StatBuf *statBufPtr,
+ int dontCopyAtts);
/* 18 */
EXTERN TclFile TclpMakeFile(Tcl_Channel channel, int direction);
/* 19 */
EXTERN TclFile TclpOpenFile(const char *fname, int mode);
/* 20 */
-EXTERN void TclWinAddProcess(void *hProcess, unsigned long id);
-/* Slot 21 is reserved */
+EXTERN void TclWinAddProcess(HANDLE hProcess, DWORD id);
+/* 21 */
+EXTERN char * TclpInetNtoa(struct in_addr addr);
/* 22 */
EXTERN TclFile TclpCreateTempFile(const char *contents);
-/* 23 */
-EXTERN char * TclpGetTZName(int isdst);
+/* Slot 23 is reserved */
/* 24 */
EXTERN char * TclWinNoBackslash(char *path);
/* Slot 25 is reserved */
@@ -139,6 +174,10 @@ EXTERN void TclWinFlushDirtyChannels(void);
EXTERN void TclWinResetInterfaces(void);
/* 29 */
EXTERN int TclWinCPUID(unsigned int index, unsigned int *regs);
+/* 30 */
+EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
+ Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
+ Tcl_Obj *resultingNameObj);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
/* 0 */
@@ -198,13 +237,28 @@ EXTERN int TclMacOSXMatchType(Tcl_Interp *interp,
/* 19 */
EXTERN void TclMacOSXNotifierAddRunLoopMode(
const void *runLoopMode);
+/* Slot 20 is reserved */
+/* Slot 21 is reserved */
+/* Slot 22 is reserved */
+/* Slot 23 is reserved */
+/* Slot 24 is reserved */
+/* Slot 25 is reserved */
+/* Slot 26 is reserved */
+/* Slot 27 is reserved */
+/* Slot 28 is reserved */
+/* 29 */
+EXTERN int TclWinCPUID(unsigned int index, unsigned int *regs);
+/* 30 */
+EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
+ Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
+ Tcl_Obj *resultingNameObj);
#endif /* MACOSX */
typedef struct TclIntPlatStubs {
int magic;
- const struct TclIntPlatStubHooks *hooks;
+ void *hooks;
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 0 */
int (*tclpCloseFile) (TclFile file); /* 1 */
Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 2 */
@@ -220,38 +274,55 @@ typedef struct TclIntPlatStubs {
struct tm * (*tclpGmtime_unix) (const time_t *clock); /* 12 */
char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */
int (*tclUnixCopyFile) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr, int dontCopyAtts); /* 14 */
+ void (*reserved15)(void);
+ void (*reserved16)(void);
+ void (*reserved17)(void);
+ void (*reserved18)(void);
+ void (*reserved19)(void);
+ void (*reserved20)(void);
+ void (*reserved21)(void);
+ void (*reserved22)(void);
+ void (*reserved23)(void);
+ void (*reserved24)(void);
+ void (*reserved25)(void);
+ void (*reserved26)(void);
+ void (*reserved27)(void);
+ void (*reserved28)(void);
+ int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */
+ int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */
#endif /* UNIX */
-#ifdef __WIN32__ /* WIN */
- void (*tclWinConvertError) (unsigned long errCode); /* 0 */
- void (*tclWinConvertWSAError) (unsigned long errCode); /* 1 */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
+ void (*tclWinConvertError) (DWORD errCode); /* 0 */
+ void (*tclWinConvertWSAError) (DWORD errCode); /* 1 */
struct servent * (*tclWinGetServByName) (const char *nm, const char *proto); /* 2 */
- int (*tclWinGetSockOpt) (SOCKET s, int level, int optname, char FAR *optval, int FAR *optlen); /* 3 */
+ int (*tclWinGetSockOpt) (SOCKET s, int level, int optname, char *optval, int *optlen); /* 3 */
HINSTANCE (*tclWinGetTclInstance) (void); /* 4 */
- void (*reserved5)(void);
- u_short (*tclWinNToHS) (u_short ns); /* 6 */
- int (*tclWinSetSockOpt) (SOCKET s, int level, int optname, const char FAR *optval, int optlen); /* 7 */
- unsigned long (*tclpGetPid) (Tcl_Pid pid); /* 8 */
+ int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 5 */
+ unsigned short (*tclWinNToHS) (unsigned short ns); /* 6 */
+ int (*tclWinSetSockOpt) (SOCKET s, int level, int optname, const char *optval, int optlen); /* 7 */
+ int (*tclpGetPid) (Tcl_Pid pid); /* 8 */
int (*tclWinGetPlatformId) (void); /* 9 */
- void (*reserved10)(void);
+ Tcl_DirEntry * (*tclpReaddir) (DIR *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 */
int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 14 */
int (*tclpCreateProcess) (Tcl_Interp *interp, int argc, const char **argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid *pidPtr); /* 15 */
- void (*reserved16)(void);
- void (*reserved17)(void);
+ int (*tclpIsAtty) (int fd); /* 16 */
+ int (*tclUnixCopyFile) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr, int dontCopyAtts); /* 17 */
TclFile (*tclpMakeFile) (Tcl_Channel channel, int direction); /* 18 */
TclFile (*tclpOpenFile) (const char *fname, int mode); /* 19 */
- void (*tclWinAddProcess) (void *hProcess, unsigned long id); /* 20 */
- void (*reserved21)(void);
+ void (*tclWinAddProcess) (HANDLE hProcess, DWORD id); /* 20 */
+ char * (*tclpInetNtoa) (struct in_addr addr); /* 21 */
TclFile (*tclpCreateTempFile) (const char *contents); /* 22 */
- char * (*tclpGetTZName) (int isdst); /* 23 */
+ void (*reserved23)(void);
char * (*tclWinNoBackslash) (char *path); /* 24 */
void (*reserved25)(void);
void (*tclWinSetInterfaces) (int wide); /* 26 */
void (*tclWinFlushDirtyChannels) (void); /* 27 */
void (*tclWinResetInterfaces) (void); /* 28 */
int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */
+ int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 0 */
@@ -274,13 +345,22 @@ typedef struct TclIntPlatStubs {
int (*tclMacOSXCopyFileAttributes) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr); /* 17 */
int (*tclMacOSXMatchType) (Tcl_Interp *interp, const char *pathName, const char *fileName, Tcl_StatBuf *statBufPtr, Tcl_GlobTypeData *types); /* 18 */
void (*tclMacOSXNotifierAddRunLoopMode) (const void *runLoopMode); /* 19 */
+ void (*reserved20)(void);
+ void (*reserved21)(void);
+ void (*reserved22)(void);
+ void (*reserved23)(void);
+ void (*reserved24)(void);
+ void (*reserved25)(void);
+ void (*reserved26)(void);
+ void (*reserved27)(void);
+ void (*reserved28)(void);
+ int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */
+ int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */
#endif /* MACOSX */
} TclIntPlatStubs;
-#ifdef __cplusplus
-extern "C" {
-#endif
extern const TclIntPlatStubs *tclIntPlatStubsPtr;
+
#ifdef __cplusplus
}
#endif
@@ -291,7 +371,7 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
* Inline function declarations:
*/
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
#define TclGetAndDetachPids \
(tclIntPlatStubsPtr->tclGetAndDetachPids) /* 0 */
#define TclpCloseFile \
@@ -321,8 +401,26 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
(tclIntPlatStubsPtr->tclpInetNtoa) /* 13 */
#define TclUnixCopyFile \
(tclIntPlatStubsPtr->tclUnixCopyFile) /* 14 */
+/* Slot 15 is reserved */
+/* Slot 16 is reserved */
+/* Slot 17 is reserved */
+/* Slot 18 is reserved */
+/* Slot 19 is reserved */
+/* Slot 20 is reserved */
+/* Slot 21 is reserved */
+/* Slot 22 is reserved */
+/* Slot 23 is reserved */
+/* Slot 24 is reserved */
+/* Slot 25 is reserved */
+/* Slot 26 is reserved */
+/* Slot 27 is reserved */
+/* Slot 28 is reserved */
+#define TclWinCPUID \
+ (tclIntPlatStubsPtr->tclWinCPUID) /* 29 */
+#define TclUnixOpenTemporaryFile \
+ (tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */
#endif /* UNIX */
-#ifdef __WIN32__ /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
#define TclWinConvertError \
(tclIntPlatStubsPtr->tclWinConvertError) /* 0 */
#define TclWinConvertWSAError \
@@ -333,7 +431,8 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
(tclIntPlatStubsPtr->tclWinGetSockOpt) /* 3 */
#define TclWinGetTclInstance \
(tclIntPlatStubsPtr->tclWinGetTclInstance) /* 4 */
-/* Slot 5 is reserved */
+#define TclUnixWaitForFile \
+ (tclIntPlatStubsPtr->tclUnixWaitForFile) /* 5 */
#define TclWinNToHS \
(tclIntPlatStubsPtr->tclWinNToHS) /* 6 */
#define TclWinSetSockOpt \
@@ -342,7 +441,8 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
(tclIntPlatStubsPtr->tclpGetPid) /* 8 */
#define TclWinGetPlatformId \
(tclIntPlatStubsPtr->tclWinGetPlatformId) /* 9 */
-/* Slot 10 is reserved */
+#define TclpReaddir \
+ (tclIntPlatStubsPtr->tclpReaddir) /* 10 */
#define TclGetAndDetachPids \
(tclIntPlatStubsPtr->tclGetAndDetachPids) /* 11 */
#define TclpCloseFile \
@@ -353,19 +453,21 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
(tclIntPlatStubsPtr->tclpCreatePipe) /* 14 */
#define TclpCreateProcess \
(tclIntPlatStubsPtr->tclpCreateProcess) /* 15 */
-/* Slot 16 is reserved */
-/* Slot 17 is reserved */
+#define TclpIsAtty \
+ (tclIntPlatStubsPtr->tclpIsAtty) /* 16 */
+#define TclUnixCopyFile \
+ (tclIntPlatStubsPtr->tclUnixCopyFile) /* 17 */
#define TclpMakeFile \
(tclIntPlatStubsPtr->tclpMakeFile) /* 18 */
#define TclpOpenFile \
(tclIntPlatStubsPtr->tclpOpenFile) /* 19 */
#define TclWinAddProcess \
(tclIntPlatStubsPtr->tclWinAddProcess) /* 20 */
-/* Slot 21 is reserved */
+#define TclpInetNtoa \
+ (tclIntPlatStubsPtr->tclpInetNtoa) /* 21 */
#define TclpCreateTempFile \
(tclIntPlatStubsPtr->tclpCreateTempFile) /* 22 */
-#define TclpGetTZName \
- (tclIntPlatStubsPtr->tclpGetTZName) /* 23 */
+/* Slot 23 is reserved */
#define TclWinNoBackslash \
(tclIntPlatStubsPtr->tclWinNoBackslash) /* 24 */
/* Slot 25 is reserved */
@@ -377,6 +479,8 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
(tclIntPlatStubsPtr->tclWinResetInterfaces) /* 28 */
#define TclWinCPUID \
(tclIntPlatStubsPtr->tclWinCPUID) /* 29 */
+#define TclUnixOpenTemporaryFile \
+ (tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
#define TclGetAndDetachPids \
@@ -418,6 +522,19 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
(tclIntPlatStubsPtr->tclMacOSXMatchType) /* 18 */
#define TclMacOSXNotifierAddRunLoopMode \
(tclIntPlatStubsPtr->tclMacOSXNotifierAddRunLoopMode) /* 19 */
+/* Slot 20 is reserved */
+/* Slot 21 is reserved */
+/* Slot 22 is reserved */
+/* Slot 23 is reserved */
+/* Slot 24 is reserved */
+/* Slot 25 is reserved */
+/* Slot 26 is reserved */
+/* Slot 27 is reserved */
+/* Slot 28 is reserved */
+#define TclWinCPUID \
+ (tclIntPlatStubsPtr->tclWinCPUID) /* 29 */
+#define TclUnixOpenTemporaryFile \
+ (tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */
#endif /* MACOSX */
#endif /* defined(USE_TCL_STUBS) */
@@ -428,5 +545,23 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
#define TCL_STORAGE_CLASS DLLIMPORT
#undef TclpLocaltime_unix
#undef TclpGmtime_unix
+#undef TclWinConvertWSAError
+#define TclWinConvertWSAError TclWinConvertError
+#undef TclpInetNtoa
+#define TclpInetNtoa inet_ntoa
+
+#if defined(_WIN32)
+# undef TclWinNToHS
+# undef TclWinGetServByName
+# undef TclWinGetSockOpt
+# undef TclWinSetSockOpt
+# define TclWinNToHS ntohs
+# define TclWinGetServByName getservbyname
+# define TclWinGetSockOpt getsockopt
+# define TclWinSetSockOpt setsockopt
+#else
+# undef TclpGetPid
+# define TclpGetPid(pid) ((unsigned long) (pid))
+#endif
#endif /* _TCLINTPLATDECLS */
diff --git a/generic/tclInterp.c b/generic/tclInterp.c
index a156a57..0da5d47 100644
--- a/generic/tclInterp.c
+++ b/generic/tclInterp.c
@@ -179,6 +179,37 @@ typedef struct ScriptLimitCallbackKey {
} ScriptLimitCallbackKey;
/*
+ * TIP#143 limit handler internal representation.
+ */
+
+struct LimitHandler {
+ int flags; /* The state of this particular handler. */
+ Tcl_LimitHandlerProc *handlerProc;
+ /* The handler callback. */
+ ClientData clientData; /* Opaque argument to the handler callback. */
+ Tcl_LimitHandlerDeleteProc *deleteProc;
+ /* How to delete the clientData. */
+ LimitHandler *prevPtr; /* Previous item in linked list of
+ * handlers. */
+ LimitHandler *nextPtr; /* Next item in linked list of handlers. */
+};
+
+/*
+ * Values for the LimitHandler flags field.
+ * LIMIT_HANDLER_ACTIVE - Whether the handler is currently being
+ * processed; handlers are never to be entered reentrantly.
+ * LIMIT_HANDLER_DELETED - Whether the handler has been deleted. This
+ * should not normally be observed because when a handler is
+ * deleted it is also spliced out of the list of handlers, but
+ * even so we will be careful.
+ */
+
+#define LIMIT_HANDLER_ACTIVE 0x01
+#define LIMIT_HANDLER_DELETED 0x02
+
+
+
+/*
* Prototypes for local static functions:
*/
@@ -248,6 +279,12 @@ static void DeleteScriptLimitCallback(ClientData clientData);
static void RunLimitHandlers(LimitHandler *handlerPtr,
Tcl_Interp *interp);
static void TimeLimitCallback(ClientData clientData);
+
+/* NRE enabling */
+static Tcl_NRPostProc NRPostInvokeHidden;
+static Tcl_ObjCmdProc NRInterpCmd;
+static Tcl_ObjCmdProc NRSlaveCmd;
+
/*
*----------------------------------------------------------------------
@@ -450,7 +487,8 @@ TclInterpInit(
slavePtr->interpCmd = NULL;
Tcl_InitHashTable(&slavePtr->aliasTable, TCL_STRING_KEYS);
- Tcl_CreateObjCommand(interp, "interp", Tcl_InterpObjCmd, NULL, NULL);
+ Tcl_NRCreateCommand(interp, "interp", Tcl_InterpObjCmd, NRInterpCmd,
+ NULL, NULL);
Tcl_CallWhenDeleted(interp, InterpInfoDeleteProc, NULL);
return TCL_OK;
@@ -559,6 +597,16 @@ Tcl_InterpObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
+ return Tcl_NRCallObjProc(interp, NRInterpCmd, clientData, objc, objv);
+}
+
+static int
+NRInterpCmd(
+ ClientData clientData, /* Unused. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
Tcl_Interp *slaveInterp;
int index;
static const char *const options[] = {
@@ -1043,18 +1091,18 @@ Tcl_InterpObjCmd(
iiPtr = (InterpInfo *) ((Interp *) slaveInterp)->interpInfo;
hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName);
if (hPtr == NULL) {
- Tcl_AppendResult(interp, "alias \"", aliasName, "\" in path \"",
- Tcl_GetString(objv[2]), "\" not found", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "alias \"%s\" in path \"%s\" not found",
+ aliasName, Tcl_GetString(objv[2])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ALIAS", aliasName,
NULL);
return TCL_ERROR;
}
aliasPtr = Tcl_GetHashValue(hPtr);
if (Tcl_GetInterpPath(interp, aliasPtr->targetInterp) != TCL_OK) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "target interpreter for alias \"",
- aliasName, "\" in path \"", Tcl_GetString(objv[2]),
- "\" is not my descendant", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "target interpreter for alias \"%s\" in path \"%s\" is "
+ "not my descendant", aliasName, Tcl_GetString(objv[2])));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
"TARGETSHROUDED", NULL);
return TCL_ERROR;
@@ -1234,7 +1282,8 @@ Tcl_GetAlias(
hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName);
if (hPtr == NULL) {
- Tcl_AppendResult(interp, "alias \"", aliasName, "\" not found", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "alias \"%s\" not found", aliasName));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ALIAS", aliasName, NULL);
return TCL_ERROR;
}
@@ -1295,7 +1344,8 @@ Tcl_GetAliasObj(
hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName);
if (hPtr == NULL) {
- Tcl_AppendResult(interp, "alias \"", aliasName, "\" not found", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "alias \"%s\" not found", aliasName));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ALIAS", aliasName, NULL);
return TCL_ERROR;
}
@@ -1383,9 +1433,9 @@ TclPreventAliasLoop(
* [Bug #641195]
*/
- Tcl_AppendResult(interp, "cannot define or rename alias \"",
- Tcl_GetCommandName(cmdInterp, cmd),
- "\": interpreter deleted", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "cannot define or rename alias \"%s\": interpreter deleted",
+ Tcl_GetCommandName(cmdInterp, cmd)));
return TCL_ERROR;
}
cmdNamePtr = nextAliasPtr->objPtr;
@@ -1398,9 +1448,9 @@ TclPreventAliasLoop(
}
aliasCmdPtr = (Command *) aliasCmd;
if (aliasCmdPtr == cmdPtr) {
- Tcl_AppendResult(interp, "cannot define or rename alias \"",
- Tcl_GetCommandName(cmdInterp, cmd),
- "\": would create a loop", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "cannot define or rename alias \"%s\": would create a loop",
+ Tcl_GetCommandName(cmdInterp, cmd)));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
"ALIASLOOP", NULL);
return TCL_ERROR;
@@ -1621,8 +1671,8 @@ AliasDelete(
slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave;
hPtr = Tcl_FindHashEntry(&slavePtr->aliasTable, TclGetString(namePtr));
if (hPtr == NULL) {
- Tcl_AppendResult(interp, "alias \"", TclGetString(namePtr),
- "\" not found", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "alias \"%s\" not found", TclGetString(namePtr)));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ALIAS",
TclGetString(namePtr), NULL);
return TCL_ERROR;
@@ -1796,9 +1846,9 @@ AliasNRCmd(
*/
if (isRootEnsemble) {
- TclNRDeferCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
+ TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
}
- iPtr->evalFlags |= TCL_EVAL_REDIRECT;
+ TclSkipTailcall(interp);
return Tcl_NREvalObj(interp, listPtr, flags);
}
@@ -2154,17 +2204,19 @@ Tcl_GetInterpPath(
InterpInfo *iiPtr;
if (targetInterp == askingInterp) {
+ Tcl_SetObjResult(askingInterp, Tcl_NewObj());
return TCL_OK;
}
if (targetInterp == NULL) {
return TCL_ERROR;
}
iiPtr = (InterpInfo *) ((Interp *) targetInterp)->interpInfo;
- if (Tcl_GetInterpPath(askingInterp, iiPtr->slave.masterInterp) != TCL_OK) {
+ if (Tcl_GetInterpPath(askingInterp, iiPtr->slave.masterInterp) != TCL_OK){
return TCL_ERROR;
}
- Tcl_AppendElement(askingInterp, Tcl_GetHashKey(&iiPtr->master.slaveTable,
- iiPtr->slave.slaveEntryPtr));
+ Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(askingInterp),
+ Tcl_NewStringObj(Tcl_GetHashKey(&iiPtr->master.slaveTable,
+ iiPtr->slave.slaveEntryPtr), -1));
return TCL_OK;
}
@@ -2218,8 +2270,8 @@ GetInterp(
}
}
if (searchInterp == NULL) {
- Tcl_AppendResult(interp, "could not find interpreter \"",
- TclGetString(pathPtr), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not find interpreter \"%s\"", TclGetString(pathPtr)));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INTERP",
TclGetString(pathPtr), NULL);
}
@@ -2256,8 +2308,8 @@ SlaveBgerror(
if (TCL_ERROR == TclListObjLength(NULL, objv[0], &length)
|| (length < 1)) {
- Tcl_AppendResult(interp, "cmdPrefix must be list of length >= 1",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "cmdPrefix must be list of length >= 1", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
"BGERRORFORMAT", NULL);
return TCL_ERROR;
@@ -2326,8 +2378,9 @@ SlaveCreate(
hPtr = Tcl_CreateHashEntry(&masterInfoPtr->master.slaveTable, path,
&isNew);
if (isNew == 0) {
- Tcl_AppendResult(interp, "interpreter named \"", path,
- "\" already exists, cannot create", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "interpreter named \"%s\" already exists, cannot create",
+ path));
return NULL;
}
@@ -2336,8 +2389,8 @@ SlaveCreate(
slavePtr->masterInterp = masterInterp;
slavePtr->slaveEntryPtr = hPtr;
slavePtr->slaveInterp = slaveInterp;
- slavePtr->interpCmd = Tcl_CreateObjCommand(masterInterp, path,
- SlaveObjCmd, slaveInterp, SlaveObjCmdDeleteProc);
+ slavePtr->interpCmd = Tcl_NRCreateCommand(masterInterp, path,
+ SlaveObjCmd, NRSlaveCmd, slaveInterp, SlaveObjCmdDeleteProc);
Tcl_InitHashTable(&slavePtr->aliasTable, TCL_STRING_KEYS);
Tcl_SetHashValue(hPtr, slavePtr);
Tcl_SetVar(slaveInterp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
@@ -2426,6 +2479,16 @@ SlaveObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
+ return Tcl_NRCallObjProc(interp, NRSlaveCmd, clientData, objc, objv);
+}
+
+static int
+NRSlaveCmd(
+ ClientData clientData, /* Slave interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
Tcl_Interp *slaveInterp = clientData;
int index;
static const char *const options[] = {
@@ -2860,8 +2923,8 @@ SlaveRecursionLimit(
if (objc) {
if (Tcl_IsSafe(interp)) {
- Tcl_AppendResult(interp, "permission denied: "
- "safe interpreters cannot change recursion limit", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("permission denied: "
+ "safe interpreters cannot change recursion limit", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "UNSAFE",
NULL);
return TCL_ERROR;
@@ -3016,7 +3079,11 @@ SlaveInvokeHidden(
Tcl_AllowExceptions(slaveInterp);
if (namespaceName == NULL) {
- result = TclObjInvoke(slaveInterp, objc, objv, TCL_INVOKE_HIDDEN);
+ NRE_callback *rootPtr = TOP_CB(slaveInterp);
+
+ Tcl_NRAddCallback(interp, NRPostInvokeHidden, slaveInterp,
+ rootPtr, NULL, NULL);
+ return TclNRInvoke(NULL, slaveInterp, objc, objv);
} else {
Namespace *nsPtr, *dummy1, *dummy2;
const char *tail;
@@ -3035,6 +3102,23 @@ SlaveInvokeHidden(
Tcl_Release(slaveInterp);
return result;
}
+
+static int
+NRPostInvokeHidden(
+ ClientData data[],
+ Tcl_Interp *interp,
+ int result)
+{
+ Tcl_Interp *slaveInterp = (Tcl_Interp *)data[0];
+ NRE_callback *rootPtr = (NRE_callback *)data[1];
+
+ if (interp != slaveInterp) {
+ result = TclNRRunCallbacks(slaveInterp, result, rootPtr);
+ Tcl_TransferResult(slaveInterp, result, interp);
+ }
+ Tcl_Release(slaveInterp);
+ return result;
+}
/*
*----------------------------------------------------------------------
@@ -3320,8 +3404,8 @@ Tcl_LimitCheck(
if (iPtr->limit.cmdCount >= iPtr->cmdCount) {
iPtr->limit.exceeded &= ~TCL_LIMIT_COMMANDS;
} else if (iPtr->limit.exceeded & TCL_LIMIT_COMMANDS) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "command count limit exceeded", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "command count limit exceeded", -1));
Tcl_SetErrorCode(interp, "TCL", "LIMIT", "COMMANDS", NULL);
Tcl_Release(interp);
return TCL_ERROR;
@@ -3346,8 +3430,8 @@ Tcl_LimitCheck(
iPtr->limit.time.usec >= now.usec)) {
iPtr->limit.exceeded &= ~TCL_LIMIT_TIME;
} else if (iPtr->limit.exceeded & TCL_LIMIT_TIME) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "time limit exceeded", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "time limit exceeded", -1));
Tcl_SetErrorCode(interp, "TCL", "LIMIT", "TIME", NULL);
Tcl_Release(interp);
return TCL_ERROR;
@@ -4345,6 +4429,20 @@ SlaveCommandLimitCmd(
ScriptLimitCallback *limitCBPtr;
Tcl_HashEntry *hPtr;
+ /*
+ * First, ensure that we are not reading or writing the calling
+ * interpreter's limits; it may only manipulate its children. Note that
+ * the low level API enforces this with Tcl_Panic, which we want to
+ * avoid. [Bug 3398794]
+ */
+
+ if (interp == slaveInterp) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "limits on current interpreter inaccessible", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "SELF", NULL);
+ return TCL_ERROR;
+ }
+
if (objc == consumedObjc) {
Tcl_Obj *dictPtr;
@@ -4437,8 +4535,8 @@ SlaveCommandLimitCmd(
return TCL_ERROR;
}
if (gran < 1) {
- Tcl_AppendResult(interp, "granularity must be at "
- "least 1", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "granularity must be at least 1", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
"BADVALUE", NULL);
return TCL_ERROR;
@@ -4454,8 +4552,8 @@ SlaveCommandLimitCmd(
return TCL_ERROR;
}
if (limit < 0) {
- Tcl_AppendResult(interp, "command limit value must be at "
- "least 0", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "command limit value must be at least 0", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
"BADVALUE", NULL);
return TCL_ERROR;
@@ -4519,6 +4617,20 @@ SlaveTimeLimitCmd(
ScriptLimitCallback *limitCBPtr;
Tcl_HashEntry *hPtr;
+ /*
+ * First, ensure that we are not reading or writing the calling
+ * interpreter's limits; it may only manipulate its children. Note that
+ * the low level API enforces this with Tcl_Panic, which we want to
+ * avoid. [Bug 3398794]
+ */
+
+ if (interp == slaveInterp) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "limits on current interpreter inaccessible", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "SELF", NULL);
+ return TCL_ERROR;
+ }
+
if (objc == consumedObjc) {
Tcl_Obj *dictPtr;
@@ -4632,8 +4744,8 @@ SlaveTimeLimitCmd(
return TCL_ERROR;
}
if (gran < 1) {
- Tcl_AppendResult(interp, "granularity must be at "
- "least 1", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "granularity must be at least 1", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
"BADVALUE", NULL);
return TCL_ERROR;
@@ -4649,13 +4761,13 @@ SlaveTimeLimitCmd(
return TCL_ERROR;
}
if (tmp < 0) {
- Tcl_AppendResult(interp, "milliseconds must be at least 0",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "milliseconds must be at least 0", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
"BADVALUE", NULL);
return TCL_ERROR;
}
- limitMoment.usec = ((long)tmp)*1000;
+ limitMoment.usec = ((long) tmp)*1000;
break;
case OPT_SEC:
secObj = objv[i+1];
@@ -4667,8 +4779,8 @@ SlaveTimeLimitCmd(
return TCL_ERROR;
}
if (tmp < 0) {
- Tcl_AppendResult(interp, "seconds must be at least 0",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "seconds must be at least 0", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
"BADVALUE", NULL);
return TCL_ERROR;
@@ -4685,15 +4797,17 @@ SlaveTimeLimitCmd(
*/
if (secObj != NULL && secLen == 0 && milliLen > 0) {
- Tcl_AppendResult(interp, "may only set -milliseconds "
- "if -seconds is not also being reset", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "may only set -milliseconds if -seconds is not "
+ "also being reset", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
"BADUSAGE", NULL);
return TCL_ERROR;
}
if (milliLen == 0 && (secObj == NULL || secLen > 0)) {
- Tcl_AppendResult(interp, "may only reset -milliseconds "
- "if -seconds is also being reset", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "may only reset -milliseconds if -seconds is "
+ "also being reset", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
"BADUSAGE", NULL);
return TCL_ERROR;
diff --git a/generic/tclLink.c b/generic/tclLink.c
index a3b42bd..2735256 100644
--- a/generic/tclLink.c
+++ b/generic/tclLink.c
@@ -112,8 +112,8 @@ Tcl_LinkVar(
Link *linkPtr;
int code;
- linkPtr = (Link *) Tcl_VarTraceInfo(interp, varName, TCL_GLOBAL_ONLY,
- LinkTraceProc, (ClientData) NULL);
+ linkPtr = (Link *) Tcl_VarTraceInfo2(interp, varName, NULL,
+ TCL_GLOBAL_ONLY, LinkTraceProc, (ClientData) NULL);
if (linkPtr != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"variable '%s' is already linked", varName));
@@ -138,8 +138,9 @@ Tcl_LinkVar(
ckfree(linkPtr);
return TCL_ERROR;
}
- code = Tcl_TraceVar(interp, varName, TCL_GLOBAL_ONLY|TCL_TRACE_READS
- |TCL_TRACE_WRITES|TCL_TRACE_UNSETS, LinkTraceProc, linkPtr);
+ code = Tcl_TraceVar2(interp, varName, NULL,
+ TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ LinkTraceProc, linkPtr);
if (code != TCL_OK) {
Tcl_DecrRefCount(linkPtr->varName);
ckfree(linkPtr);
@@ -170,13 +171,13 @@ Tcl_UnlinkVar(
Tcl_Interp *interp, /* Interpreter containing variable to unlink */
const char *varName) /* Global variable in interp to unlink. */
{
- Link *linkPtr = (Link *) Tcl_VarTraceInfo(interp, varName,
+ Link *linkPtr = (Link *) Tcl_VarTraceInfo2(interp, varName, NULL,
TCL_GLOBAL_ONLY, LinkTraceProc, NULL);
if (linkPtr == NULL) {
return;
}
- Tcl_UntraceVar(interp, varName,
+ Tcl_UntraceVar2(interp, varName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
LinkTraceProc, linkPtr);
Tcl_DecrRefCount(linkPtr->varName);
@@ -207,7 +208,7 @@ Tcl_UpdateLinkedVar(
Tcl_Interp *interp, /* Interpreter containing variable. */
const char *varName) /* Name of global variable that is linked. */
{
- Link *linkPtr = (Link *) Tcl_VarTraceInfo(interp, varName,
+ Link *linkPtr = (Link *) Tcl_VarTraceInfo2(interp, varName, NULL,
TCL_GLOBAL_ONLY, LinkTraceProc, NULL);
int savedFlag;
@@ -221,8 +222,8 @@ Tcl_UpdateLinkedVar(
/*
* Callback may have unlinked the variable. [Bug 1740631]
*/
- linkPtr = (Link *) Tcl_VarTraceInfo(interp, varName, TCL_GLOBAL_ONLY,
- LinkTraceProc, NULL);
+ linkPtr = (Link *) Tcl_VarTraceInfo2(interp, varName, NULL,
+ TCL_GLOBAL_ONLY, LinkTraceProc, NULL);
if (linkPtr != NULL) {
linkPtr->flags = (linkPtr->flags & ~LINK_BEING_UPDATED) | savedFlag;
}
@@ -278,7 +279,7 @@ LinkTraceProc(
} else if (flags & TCL_TRACE_DESTROYED) {
Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
TCL_GLOBAL_ONLY);
- Tcl_TraceVar(interp, Tcl_GetString(linkPtr->varName),
+ Tcl_TraceVar2(interp, Tcl_GetString(linkPtr->varName), NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES
|TCL_TRACE_UNSETS, LinkTraceProc, linkPtr);
}
diff --git a/generic/tclListObj.c b/generic/tclListObj.c
index 3668b45..bd2dbc4 100644
--- a/generic/tclListObj.c
+++ b/generic/tclListObj.c
@@ -237,7 +237,7 @@ Tcl_NewListObj(
* Now create the object.
*/
- Tcl_InvalidateStringRep(listPtr);
+ TclInvalidateStringRep(listPtr);
ListSetIntRep(listPtr, listRepPtr);
return listPtr;
}
@@ -302,7 +302,7 @@ Tcl_DbNewListObj(
* Now create the object.
*/
- Tcl_InvalidateStringRep(listPtr);
+ TclInvalidateStringRep(listPtr);
ListSetIntRep(listPtr, listRepPtr);
return listPtr;
@@ -362,7 +362,7 @@ Tcl_SetListObj(
*/
TclFreeIntRep(objPtr);
- Tcl_InvalidateStringRep(objPtr);
+ TclInvalidateStringRep(objPtr);
/*
* Set the object's type to "list" and initialize the internal rep.
@@ -697,7 +697,7 @@ Tcl_ListObjAppendElement(
* representation has changed.
*/
- Tcl_InvalidateStringRep(listPtr);
+ TclInvalidateStringRep(listPtr);
return TCL_OK;
}
@@ -909,6 +909,10 @@ Tcl_ListObjReplace(
isShared = (listRepPtr->refCount > 1);
numRequired = numElems - count + objc;
+ for (i = 0; i < objc; i++) {
+ Tcl_IncrRefCount(objv[i]);
+ }
+
if ((numRequired <= listRepPtr->maxElemCount) && !isShared) {
int shift;
@@ -963,6 +967,14 @@ Tcl_ListObjReplace(
if (listRepPtr == NULL) {
listRepPtr = AttemptNewList(interp, numRequired, NULL);
if (listRepPtr == NULL) {
+ for (i = 0; i < objc; i++) {
+ /* See bug 3598580 */
+#if TCL_MAJOR_VERSION > 8
+ Tcl_DecrRefCount(objv[i]);
+#else
+ objv[i]->refCount--;
+#endif
+ }
return TCL_ERROR;
}
}
@@ -1027,14 +1039,11 @@ Tcl_ListObjReplace(
}
/*
- * Insert the new elements into elemPtrs before "first". We don't do a
- * memcpy here because we must increment the reference counts for the
- * added elements, so we must explicitly loop anyway.
+ * Insert the new elements into elemPtrs before "first".
*/
for (i=0,j=first ; i<objc ; i++,j++) {
elemPtrs[j] = objv[i];
- Tcl_IncrRefCount(objv[i]);
}
/*
@@ -1048,7 +1057,7 @@ Tcl_ListObjReplace(
* reflects the list's internal representation.
*/
- Tcl_InvalidateStringRep(listPtr);
+ TclInvalidateStringRep(listPtr);
return TCL_OK;
}
@@ -1514,7 +1523,7 @@ TclLsetFlat(
* containing lists.
*/
- Tcl_InvalidateStringRep(objPtr);
+ TclInvalidateStringRep(objPtr);
}
/*
@@ -1550,7 +1559,7 @@ TclLsetFlat(
} else {
TclListObjSetElement(NULL, subListPtr, index, valuePtr);
}
- Tcl_InvalidateStringRep(subListPtr);
+ TclInvalidateStringRep(subListPtr);
Tcl_IncrRefCount(retValuePtr);
return retValuePtr;
}
@@ -1727,8 +1736,6 @@ FreeListInternalRep(
ckfree(listRepPtr);
}
- listPtr->internalRep.twoPtrValue.ptr1 = NULL;
- listPtr->internalRep.twoPtrValue.ptr2 = NULL;
listPtr->typePtr = NULL;
}
diff --git a/generic/tclLiteral.c b/generic/tclLiteral.c
index 3a9f8e1..2b0cc7e 100644
--- a/generic/tclLiteral.c
+++ b/generic/tclLiteral.c
@@ -32,6 +32,10 @@ static int AddLocalLiteralEntry(CompileEnv *envPtr,
Tcl_Obj *objPtr, int localHash);
static void ExpandLocalLiteralArray(CompileEnv *envPtr);
static unsigned HashString(const char *string, int length);
+#ifdef TCL_COMPILE_DEBUG
+static LiteralEntry * LookupLiteralEntry(Tcl_Interp *interp,
+ Tcl_Obj *objPtr);
+#endif
static void RebuildLiteralTable(LiteralTable *tablePtr);
/*
@@ -239,7 +243,7 @@ TclCreateLiteral(
}
#ifdef TCL_COMPILE_DEBUG
- if (TclLookupLiteralEntry((Tcl_Interp *) iPtr, objPtr) != NULL) {
+ if (LookupLiteralEntry((Tcl_Interp *) iPtr, objPtr) != NULL) {
Tcl_Panic("%s: literal \"%.*s\" found globally but shouldn't be",
"TclRegisterLiteral", (length>60? 60 : length), bytes);
}
@@ -301,6 +305,33 @@ TclCreateLiteral(
/*
*----------------------------------------------------------------------
*
+ * TclFetchLiteral --
+ *
+ * Fetch from a CompileEnv the literal value identified by an index
+ * value, as returned by a prior call to TclRegisterLiteral().
+ *
+ * Results:
+ * The literal value, or NULL if the index is out of range.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclFetchLiteral(
+ CompileEnv *envPtr, /* Points to the CompileEnv from which to
+ * fetch the registered literal value. */
+ unsigned int index) /* Index of the desired literal, as returned
+ * by prior call to TclRegisterLiteral() */
+{
+ if (index >= (unsigned int) envPtr->literalArrayNext) {
+ return NULL;
+ }
+ return envPtr->literalArrayPtr[index].objPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclRegisterLiteral --
*
* Find, or if necessary create, an object in a CompileEnv literal array
@@ -327,7 +358,7 @@ TclCreateLiteral(
int
TclRegisterLiteral(
- CompileEnv *envPtr, /* Points to the CompileEnv in whose object
+ void *ePtr, /* Points to the CompileEnv in whose object
* array an object is found or created. */
register char *bytes, /* Points to string for which to find or
* create an object in CompileEnv's object
@@ -341,6 +372,7 @@ TclRegisterLiteral(
* the literal should not be shared accross
* namespaces. */
{
+ CompileEnv *envPtr = ePtr;
Interp *iPtr = envPtr->iPtr;
LiteralTable *localTablePtr = &envPtr->localLitTable;
LiteralEntry *globalPtr, *localPtr;
@@ -414,10 +446,11 @@ TclRegisterLiteral(
return objIndex;
}
+#ifdef TCL_COMPILE_DEBUG
/*
*----------------------------------------------------------------------
*
- * TclLookupLiteralEntry --
+ * LookupLiteralEntry --
*
* Finds the LiteralEntry that corresponds to a literal Tcl object
* holding a literal.
@@ -431,8 +464,8 @@ TclRegisterLiteral(
*----------------------------------------------------------------------
*/
-LiteralEntry *
-TclLookupLiteralEntry(
+static LiteralEntry *
+LookupLiteralEntry(
Tcl_Interp *interp, /* Interpreter for which objPtr was created to
* hold a literal. */
register Tcl_Obj *objPtr) /* Points to a Tcl object holding a literal
@@ -456,6 +489,7 @@ TclLookupLiteralEntry(
return NULL;
}
+#endif
/*
*----------------------------------------------------------------------
*
@@ -750,11 +784,16 @@ TclReleaseLiteral(
* TclRegisterLiteral. */
{
Interp *iPtr = (Interp *) interp;
- LiteralTable *globalTablePtr = &iPtr->literalTable;
+ LiteralTable *globalTablePtr;
register LiteralEntry *entryPtr, *prevPtr;
const char *bytes;
int length, index;
+ if (iPtr == NULL) {
+ goto done;
+ }
+
+ globalTablePtr = &iPtr->literalTable;
bytes = TclGetStringFromObj(objPtr, &length);
index = (HashString(bytes, length) & globalTablePtr->mask);
@@ -798,6 +837,7 @@ TclReleaseLiteral(
* Remove the reference corresponding to the local literal table entry.
*/
+ done:
Tcl_DecrRefCount(objPtr);
}
@@ -936,6 +976,51 @@ RebuildLiteralTable(
}
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInvalidateCmdLiteral --
+ *
+ * Invalidate a command literal entry, if present in the literal hash
+ * tables, by resetting its internal representation. This invalidation
+ * leaves it in the literal tables and in existing literal arrays. As a
+ * result, existing references continue to work but we force a fresh
+ * command look-up upon the next use (see, in particular,
+ * TclSetCmdNameObj()).
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Resets the internal representation of the CmdName Tcl_Obj
+ * using TclFreeIntRep().
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclInvalidateCmdLiteral(
+ Tcl_Interp *interp, /* Interpreter for which to invalidate a
+ * command literal. */
+ const char *name, /* Points to the start of the cmd literal
+ * name. */
+ Namespace *nsPtr) /* The namespace for which to lookup and
+ * invalidate a cmd literal. */
+{
+ Interp *iPtr = (Interp *) interp;
+ Tcl_Obj *literalObjPtr = TclCreateLiteral(iPtr, (char *) name,
+ strlen(name), -1, NULL, nsPtr, 0, NULL);
+
+ if (literalObjPtr != NULL) {
+ if (literalObjPtr->typePtr == &tclCmdNameType) {
+ TclFreeIntRep(literalObjPtr);
+ }
+ /* Balance the refcount effects of TclCreateLiteral() above */
+ Tcl_IncrRefCount(literalObjPtr);
+ TclReleaseLiteral(interp, literalObjPtr);
+ }
+}
+
#ifdef TCL_COMPILE_STATS
/*
*----------------------------------------------------------------------
@@ -1050,7 +1135,7 @@ TclVerifyLocalLiteralTable(
"TclVerifyLocalLiteralTable",
(length>60? 60 : length), bytes, localPtr->refCount);
}
- if (TclLookupLiteralEntry((Tcl_Interp *) envPtr->iPtr,
+ if (LookupLiteralEntry((Tcl_Interp *) envPtr->iPtr,
localPtr->objPtr) == NULL) {
bytes = Tcl_GetStringFromObj(localPtr->objPtr, &length);
Tcl_Panic("%s: local literal \"%.*s\" is not global",
diff --git a/generic/tclLoad.c b/generic/tclLoad.c
index 820707e..7c70e03 100644
--- a/generic/tclLoad.c
+++ b/generic/tclLoad.c
@@ -132,9 +132,34 @@ Tcl_LoadObjCmd(
Tcl_LoadHandle loadHandle;
Tcl_UniChar ch;
unsigned len;
+ int index, flags = 0;
+ Tcl_Obj *const *savedobjv = objv;
+ static const char *const options[] = {
+ "-global", "-lazy", "--", NULL
+ };
+ enum options {
+ LOAD_GLOBAL, LOAD_LAZY, LOAD_LAST
+ };
+ while (objc > 2) {
+ if (TclGetString(objv[1])[0] != '-') {
+ break;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ ++objv; --objc;
+ if (LOAD_GLOBAL == (enum options) index) {
+ flags |= TCL_LOAD_GLOBAL;
+ } else if (LOAD_LAZY == (enum options) index) {
+ flags |= TCL_LOAD_LAZY;
+ } else {
+ break;
+ }
+ }
if ((objc < 2) || (objc > 4)) {
- Tcl_WrongNumArgs(interp, 1, objv, "fileName ?packageName? ?interp?");
+ Tcl_WrongNumArgs(interp, 1, savedobjv, "?-global? ?-lazy? ?--? fileName ?packageName? ?interp?");
return TCL_ERROR;
}
if (Tcl_FSConvertToPathType(interp, objv[1]) != TCL_OK) {
@@ -157,9 +182,8 @@ Tcl_LoadObjCmd(
}
}
if ((fullFileName[0] == 0) && (packageName == NULL)) {
- Tcl_SetResult(interp,
- "must specify either file name or package name",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "must specify either file name or package name", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "NOLIBRARY",
NULL);
code = TCL_ERROR;
@@ -198,9 +222,9 @@ Tcl_LoadObjCmd(
if (packageName == NULL) {
namesMatch = 0;
} else {
- Tcl_DStringSetLength(&pkgName, 0);
+ TclDStringClear(&pkgName);
Tcl_DStringAppend(&pkgName, packageName, -1);
- Tcl_DStringSetLength(&tmp, 0);
+ TclDStringClear(&tmp);
Tcl_DStringAppend(&tmp, pkgPtr->packageName, -1);
Tcl_UtfToLower(Tcl_DStringValue(&pkgName));
Tcl_UtfToLower(Tcl_DStringValue(&tmp));
@@ -211,7 +235,7 @@ Tcl_LoadObjCmd(
namesMatch = 0;
}
}
- Tcl_DStringSetLength(&pkgName, 0);
+ TclDStringClear(&pkgName);
filesMatch = (strcmp(pkgPtr->fileName, fullFileName) == 0);
if (filesMatch && (namesMatch || (packageName == NULL))) {
@@ -225,9 +249,9 @@ Tcl_LoadObjCmd(
* Can't have two different packages loaded from the same file.
*/
- Tcl_AppendResult(interp, "file \"", fullFileName,
- "\" is already loaded for package \"",
- pkgPtr->packageName, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "file \"%s\" is already loaded for package \"%s\"",
+ fullFileName, pkgPtr->packageName));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD",
"SPLITPERSONALITY", NULL);
code = TCL_ERROR;
@@ -263,8 +287,8 @@ Tcl_LoadObjCmd(
*/
if (fullFileName[0] == 0) {
- Tcl_AppendResult(interp, "package \"", packageName,
- "\" isn't loaded statically", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "package \"%s\" isn't loaded statically", packageName));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "NOTSTATIC",
NULL);
code = TCL_ERROR;
@@ -305,6 +329,12 @@ Tcl_LoadObjCmd(
&& (pkgGuess[2] == 'b')) {
pkgGuess += 3;
}
+#ifdef __CYGWIN__
+ if ((pkgGuess[0] == 'c') && (pkgGuess[1] == 'y')
+ && (pkgGuess[2] == 'g')) {
+ pkgGuess += 3;
+ }
+#endif /* __CYGWIN__ */
for (p = pkgGuess; *p != 0; p += offset) {
offset = Tcl_UtfToUniChar(p, &ch);
if ((ch > 0x100)
@@ -315,15 +345,15 @@ Tcl_LoadObjCmd(
}
if (p == pkgGuess) {
Tcl_DecrRefCount(splitPtr);
- Tcl_AppendResult(interp,
- "couldn't figure out package name for ",
- fullFileName, NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't figure out package name for %s",
+ fullFileName));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD",
"WHATPACKAGE", NULL);
code = TCL_ERROR;
goto done;
}
- Tcl_DStringAppend(&pkgName, pkgGuess, (p - pkgGuess));
+ Tcl_DStringAppend(&pkgName, pkgGuess, p - pkgGuess);
Tcl_DecrRefCount(splitPtr);
}
}
@@ -342,14 +372,14 @@ Tcl_LoadObjCmd(
* package name.
*/
- Tcl_DStringAppend(&initName, Tcl_DStringValue(&pkgName), -1);
- Tcl_DStringAppend(&initName, "_Init", 5);
- Tcl_DStringAppend(&safeInitName, Tcl_DStringValue(&pkgName), -1);
- Tcl_DStringAppend(&safeInitName, "_SafeInit", 9);
- Tcl_DStringAppend(&unloadName, Tcl_DStringValue(&pkgName), -1);
- Tcl_DStringAppend(&unloadName, "_Unload", 7);
- Tcl_DStringAppend(&safeUnloadName, Tcl_DStringValue(&pkgName), -1);
- Tcl_DStringAppend(&safeUnloadName, "_SafeUnload", 11);
+ TclDStringAppendDString(&initName, &pkgName);
+ TclDStringAppendLiteral(&initName, "_Init");
+ TclDStringAppendDString(&safeInitName, &pkgName);
+ TclDStringAppendLiteral(&safeInitName, "_SafeInit");
+ TclDStringAppendDString(&unloadName, &pkgName);
+ TclDStringAppendLiteral(&unloadName, "_Unload");
+ TclDStringAppendDString(&safeUnloadName, &pkgName);
+ TclDStringAppendLiteral(&safeUnloadName, "_SafeUnload");
/*
* Call platform-specific code to load the package and find the two
@@ -360,7 +390,7 @@ Tcl_LoadObjCmd(
symbols[1] = NULL;
Tcl_MutexLock(&packageMutex);
- code = Tcl_LoadFile(interp, objv[1], symbols, 0, &initProc,
+ code = Tcl_LoadFile(interp, objv[1], symbols, flags, &initProc,
&loadHandle);
Tcl_MutexUnlock(&packageMutex);
if (code != TCL_OK) {
@@ -386,7 +416,7 @@ Tcl_LoadObjCmd(
pkgPtr->unloadProc = (Tcl_PackageUnloadProc *)
Tcl_FindSymbol(interp, loadHandle,
Tcl_DStringValue(&unloadName));
- pkgPtr->safeUnloadProc = (Tcl_PackageUnloadProc *)
+ pkgPtr->safeUnloadProc = (Tcl_PackageUnloadProc *)
Tcl_FindSymbol(interp, loadHandle,
Tcl_DStringValue(&safeUnloadName));
pkgPtr->interpRefCount = 0;
@@ -412,9 +442,9 @@ Tcl_LoadObjCmd(
if (Tcl_IsSafe(target)) {
if (pkgPtr->safeInitProc == NULL) {
- Tcl_AppendResult(interp,
- "can't use package in a safe interpreter: no ",
- pkgPtr->packageName, "_SafeInit procedure", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't use package in a safe interpreter: no"
+ " %s_SafeInit procedure", pkgPtr->packageName));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "UNSAFE",
NULL);
code = TCL_ERROR;
@@ -423,9 +453,9 @@ Tcl_LoadObjCmd(
code = pkgPtr->safeInitProc(target);
} else {
if (pkgPtr->initProc == NULL) {
- Tcl_AppendResult(interp,
- "can't attach package to interpreter: no ",
- pkgPtr->packageName, "_Init procedure", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't attach package to interpreter: no %s_Init procedure",
+ pkgPtr->packageName));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "ENTRYPOINT",
NULL);
code = TCL_ERROR;
@@ -575,9 +605,8 @@ Tcl_UnloadObjCmd(
}
}
if ((fullFileName[0] == 0) && (packageName == NULL)) {
- Tcl_SetResult(interp,
- "must specify either file name or package name",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "must specify either file name or package name", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NOLIBRARY",
NULL);
code = TCL_ERROR;
@@ -617,9 +646,9 @@ Tcl_UnloadObjCmd(
if (packageName == NULL) {
namesMatch = 0;
} else {
- Tcl_DStringSetLength(&pkgName, 0);
+ TclDStringClear(&pkgName);
Tcl_DStringAppend(&pkgName, packageName, -1);
- Tcl_DStringSetLength(&tmp, 0);
+ TclDStringClear(&tmp);
Tcl_DStringAppend(&tmp, pkgPtr->packageName, -1);
Tcl_UtfToLower(Tcl_DStringValue(&pkgName));
Tcl_UtfToLower(Tcl_DStringValue(&tmp));
@@ -630,7 +659,7 @@ Tcl_UnloadObjCmd(
namesMatch = 0;
}
}
- Tcl_DStringSetLength(&pkgName, 0);
+ TclDStringClear(&pkgName);
filesMatch = (strcmp(pkgPtr->fileName, fullFileName) == 0);
if (filesMatch && (namesMatch || (packageName == NULL))) {
@@ -649,8 +678,9 @@ Tcl_UnloadObjCmd(
* It's an error to try unload a static package.
*/
- Tcl_AppendResult(interp, "package \"", packageName,
- "\" is loaded statically and cannot be unloaded", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "package \"%s\" is loaded statically and cannot be unloaded",
+ packageName));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "STATIC",
NULL);
code = TCL_ERROR;
@@ -661,8 +691,8 @@ Tcl_UnloadObjCmd(
* The DLL pointed by the provided filename has never been loaded.
*/
- Tcl_AppendResult(interp, "file \"", fullFileName,
- "\" has never been loaded", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "file \"%s\" has never been loaded", fullFileName));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NEVERLOADED",
NULL);
code = TCL_ERROR;
@@ -690,8 +720,9 @@ Tcl_UnloadObjCmd(
* The package has not been loaded in this interpreter.
*/
- Tcl_AppendResult(interp, "file \"", fullFileName,
- "\" has never been loaded in this interpreter", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "file \"%s\" has never been loaded in this interpreter",
+ fullFileName));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NEVERLOADED",
NULL);
code = TCL_ERROR;
@@ -706,8 +737,9 @@ Tcl_UnloadObjCmd(
if (Tcl_IsSafe(target)) {
if (pkgPtr->safeUnloadProc == NULL) {
- Tcl_AppendResult(interp, "file \"", fullFileName,
- "\" cannot be unloaded under a safe interpreter", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "file \"%s\" cannot be unloaded under a safe interpreter",
+ fullFileName));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "CANNOT",
NULL);
code = TCL_ERROR;
@@ -716,8 +748,9 @@ Tcl_UnloadObjCmd(
unloadProc = pkgPtr->safeUnloadProc;
} else {
if (pkgPtr->unloadProc == NULL) {
- Tcl_AppendResult(interp, "file \"", fullFileName,
- "\" cannot be unloaded under a trusted interpreter", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "file \"%s\" cannot be unloaded under a trusted interpreter",
+ fullFileName));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "CANNOT",
NULL);
code = TCL_ERROR;
@@ -797,7 +830,7 @@ Tcl_UnloadObjCmd(
* Unload the shared library from the application memory...
*/
-#if defined(TCL_UNLOAD_DLLS) || defined(__WIN32__)
+#if defined(TCL_UNLOAD_DLLS) || defined(_WIN32)
/*
* Some Unix dlls are poorly behaved - registering things like atexit
* calls that can't be unregistered. If you unload such dlls, you get
@@ -856,8 +889,9 @@ Tcl_UnloadObjCmd(
}
}
#else
- Tcl_AppendResult(interp, "file \"", fullFileName,
- "\" cannot be unloaded: unloading disabled", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "file \"%s\" cannot be unloaded: unloading disabled",
+ fullFileName));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "DISABLED",
NULL);
code = TCL_ERROR;
@@ -867,40 +901,10 @@ Tcl_UnloadObjCmd(
done:
Tcl_DStringFree(&pkgName);
Tcl_DStringFree(&tmp);
- if (!complain && code!=TCL_OK) {
+ if (!complain && (code != TCL_OK)) {
code = TCL_OK;
Tcl_ResetResult(interp);
}
- if (code == TCL_OK) {
-#if 0
- /*
- * Result of [unload] was not documented in TIP#100, so force to be
- * the empty string by commenting this out. DKF.
- */
-
- Tcl_Obj *resultObjPtr, *objPtr[2];
-
- /*
- * Our result is the two reference counts.
- */
-
- TclNewIntObj(objPtr[0], trustedRefCount);
- TclNewIntObj(objPtr[1], safeRefCount);
- if (objPtr[0] == NULL || objPtr[1] == NULL) {
- if (objPtr[0]) {
- Tcl_DecrRefCount(objPtr[0]);
- }
- if (objPtr[1]) {
- Tcl_DecrRefCount(objPtr[1]);
- }
- } else {
- TclNewListObj(resultObjPtr, 2, objPtr);
- if (resultObjPtr != NULL) {
- Tcl_SetObjResult(interp, resultObjPtr);
- }
- }
-#endif
- }
return code;
}
@@ -1147,7 +1151,7 @@ TclFinalizeLoad(void)
pkgPtr = firstPackagePtr;
firstPackagePtr = pkgPtr->nextPtr;
-#if defined(TCL_UNLOAD_DLLS) || defined(__WIN32__)
+#if defined(TCL_UNLOAD_DLLS) || defined(_WIN32)
/*
* Some Unix dlls are poorly behaved - registering things like atexit
* calls that can't be unregistered. If you unload such dlls, you get
diff --git a/generic/tclLoadNone.c b/generic/tclLoadNone.c
index ac094e6..c22c4c4 100644
--- a/generic/tclLoadNone.c
+++ b/generic/tclLoadNone.c
@@ -39,14 +39,15 @@ TclpDlopen(
Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
- Tcl_FSUnloadFileProc **unloadProcPtr)
+ Tcl_FSUnloadFileProc **unloadProcPtr,
/* Filled with address of Tcl_FSUnloadFileProc
* function which should be used for this
* file. */
+ int flags)
{
- Tcl_SetResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"dynamic loading is not currently available on this system",
- TCL_STATIC);
+ -1));
return TCL_ERROR;
}
@@ -81,6 +82,39 @@ TclGuessPackageName(
}
/*
+ * These functions are fallbacks if we somehow determine that the platform can
+ * do loading from memory but the user wishes to disable it. They just report
+ * (gracefully) that they fail.
+ */
+
+#ifdef TCL_LOAD_FROM_MEMORY
+
+MODULE_SCOPE void *
+TclpLoadMemoryGetBuffer(
+ Tcl_Interp *interp, /* Dummy: unused by this implementation */
+ int size) /* Dummy: unused by this implementation */
+{
+ return NULL;
+}
+
+MODULE_SCOPE int
+TclpLoadMemory(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ void *buffer, /* Dummy: unused by this implementation */
+ int size, /* Dummy: unused by this implementation */
+ int codeSize, /* Dummy: unused by this implementation */
+ Tcl_LoadHandle *loadHandle, /* Dummy: unused by this implementation */
+ Tcl_FSUnloadFileProc **unloadProcPtr)
+ /* Dummy: unused by this implementation */
+{
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("dynamic loading from memory "
+ "is not available on this system", -1));
+ return TCL_ERROR;
+}
+
+#endif /* TCL_LOAD_FROM_MEMORY */
+
+/*
* Local Variables:
* mode: c
* c-basic-offset: 4
diff --git a/generic/tclMain.c b/generic/tclMain.c
index 652074e..360f5e9 100644
--- a/generic/tclMain.c
+++ b/generic/tclMain.c
@@ -16,11 +16,12 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-/**
- * On Windows, this file needs to be compiled twice, once with
- * TCL_ASCII_MAIN defined. This way both Tcl_Main and Tcl_MainExW
- * can be implemented, sharing the same source code.
+/*
+ * On Windows, this file needs to be compiled twice, once with TCL_ASCII_MAIN
+ * defined. This way both Tcl_Main and Tcl_MainExW can be implemented, sharing
+ * the same source code.
*/
+
#if defined(TCL_ASCII_MAIN)
# ifdef UNICODE
# undef UNICODE
@@ -40,33 +41,36 @@
#define DEFAULT_PRIMARY_PROMPT "% "
/*
- * This file can be compiled on Windows in UNICODE mode, as well as
- * on all other platforms using the native encoding. This is done
- * by using the normal Windows functions like _tcscmp, but on
- * platforms which don't have <tchar.h> we have to translate that
- * to strcmp here.
+ * This file can be compiled on Windows in UNICODE mode, as well as on all
+ * other platforms using the native encoding. This is done by using the normal
+ * Windows functions like _tcscmp, but on platforms which don't have <tchar.h>
+ * we have to translate that to strcmp here.
*/
-#ifndef __WIN32__
+
+#ifndef _WIN32
# define TCHAR char
# define TEXT(arg) arg
# define _tcscmp strcmp
#endif
/*
- * Further on, in UNICODE mode, we need to use Tcl_NewUnicodeObj,
- * while otherwise NewNativeObj is needed (which provides proper
- * conversion from native encoding to UTF-8).
+ * Further on, in UNICODE mode we just use Tcl_NewUnicodeObj, otherwise
+ * NewNativeObj is needed (which provides proper conversion from native
+ * encoding to UTF-8).
*/
+
#ifdef UNICODE
# define NewNativeObj Tcl_NewUnicodeObj
#else /* !UNICODE */
- static Tcl_Obj *NewNativeObj(char *string, int length) {
- Tcl_Obj *obj;
- Tcl_DString ds;
- Tcl_ExternalToUtfDString(NULL, string, length, &ds);
- obj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
- Tcl_DStringFree(&ds);
- return obj;
+static inline Tcl_Obj *
+NewNativeObj(
+ char *string,
+ int length)
+{
+ Tcl_DString ds;
+
+ Tcl_ExternalToUtfDString(NULL, string, length, &ds);
+ return TclDStringToObj(&ds);
}
#endif /* !UNICODE */
@@ -125,10 +129,11 @@ typedef struct InteractiveState {
MODULE_SCOPE Tcl_MainLoopProc *TclGetMainLoop(void);
static void Prompt(Tcl_Interp *interp, InteractiveState *isPtr);
static void StdinProc(ClientData clientData, int mask);
-static void FreeMainInterp(ClientData clientData);
+static void FreeMainInterp(ClientData clientData);
#ifndef TCL_ASCII_MAIN
static Tcl_ThreadDataKey dataKey;
+
/*
*----------------------------------------------------------------------
*
@@ -308,6 +313,9 @@ Tcl_MainEx(
Tcl_Channel chan;
InteractiveState is;
+ TclpSetInitialEncodings();
+ TclpFindExecutable((const char *)argv[0]);
+
Tcl_InitMemory(interp);
is.interp = interp;
@@ -329,13 +337,14 @@ Tcl_MainEx(
*/
if ((argc > 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1]))
- && (TEXT('-') != argv[3][0])) {
- Tcl_Obj *value = NewNativeObj(argv[2], -1);
- Tcl_SetStartupScript(NewNativeObj(argv[3], -1), Tcl_GetString(value));
+ && ('-' != argv[3][0])) {
+ Tcl_Obj *value = NewNativeObj(argv[2], -1);
+ Tcl_SetStartupScript(NewNativeObj(argv[3], -1),
+ Tcl_GetString(value));
Tcl_DecrRefCount(value);
argc -= 3;
argv += 3;
- } else if ((argc > 1) && (TEXT('-') != argv[1][0])) {
+ } else if ((argc > 1) && ('-' != argv[1][0])) {
Tcl_SetStartupScript(NewNativeObj(argv[1], -1), NULL);
argc--;
argv++;
@@ -392,8 +401,9 @@ Tcl_MainEx(
/*
* Arrange for final deletion of the main interp
*/
- // ARGH Munchhausen effect
- Tcl_CreateExitHandler(FreeMainInterp, (ClientData)interp);
+
+ /* ARGH Munchhausen effect */
+ Tcl_CreateExitHandler(FreeMainInterp, interp);
}
/*
@@ -455,6 +465,7 @@ Tcl_MainEx(
mainLoopProc = TclGetMainLoop();
if (mainLoopProc == NULL) {
int length;
+
if (is.tty) {
Prompt(interp, &is);
if (Tcl_InterpDeleted(interp)) {
@@ -520,7 +531,8 @@ Tcl_MainEx(
Tcl_GetStringFromObj(is.commandPtr, &length);
Tcl_SetObjLength(is.commandPtr, --length);
- code = Tcl_RecordAndEvalObj(interp, is.commandPtr, TCL_EVAL_GLOBAL);
+ code = Tcl_RecordAndEvalObj(interp, is.commandPtr,
+ TCL_EVAL_GLOBAL);
is.input = Tcl_GetStdChannel(TCL_STDIN);
Tcl_DecrRefCount(is.commandPtr);
is.commandPtr = Tcl_NewObj();
@@ -554,7 +566,8 @@ Tcl_MainEx(
Prompt(interp, &is);
}
- Tcl_CreateChannelHandler(is.input, TCL_READABLE, StdinProc, &is);
+ Tcl_CreateChannelHandler(is.input, TCL_READABLE,
+ StdinProc, &is);
}
mainLoopProc();
@@ -565,24 +578,23 @@ Tcl_MainEx(
}
is.input = Tcl_GetStdChannel(TCL_STDIN);
}
-#ifdef TCL_MEM_DEBUG
/*
* This code here only for the (unsupported and deprecated) [checkmem]
* command.
*/
+#ifdef TCL_MEM_DEBUG
if (tclMemDumpFileName != NULL) {
Tcl_SetMainLoop(NULL);
Tcl_DeleteInterp(interp);
}
-#endif
+#endif /* TCL_MEM_DEBUG */
}
done:
mainLoopProc = TclGetMainLoop();
- if ((exitCode == 0) && (mainLoopProc != NULL)
- && !Tcl_LimitExceeded(interp)) {
+ if ((exitCode == 0) && mainLoopProc && !Tcl_LimitExceeded(interp)) {
/*
* If everything has gone OK so far, call the main loop proc, if it
* exists. Packages (like Tk) can set it to start processing events at
@@ -602,38 +614,38 @@ Tcl_MainEx(
* exit. The Tcl_EvalObjEx call should never return.
*/
- if (!Tcl_InterpDeleted(interp)) {
- if (!Tcl_LimitExceeded(interp)) {
- Tcl_Obj *cmd = Tcl_ObjPrintf("exit %d", exitCode);
+ if (!Tcl_InterpDeleted(interp) && !Tcl_LimitExceeded(interp)) {
+ Tcl_Obj *cmd = Tcl_ObjPrintf("exit %d", exitCode);
- Tcl_IncrRefCount(cmd);
- Tcl_EvalObjEx(interp, cmd, TCL_EVAL_GLOBAL);
- Tcl_DecrRefCount(cmd);
- }
+ Tcl_IncrRefCount(cmd);
+ Tcl_EvalObjEx(interp, cmd, TCL_EVAL_GLOBAL);
+ Tcl_DecrRefCount(cmd);
}
- /*
- * If Tcl_EvalObjEx returns, trying to eval [exit], something unusual
- * is happening. Maybe interp has been deleted; maybe [exit] was
- * redefined, maybe we've blown up because of an exceeded limit. We
- * still want to cleanup and exit.
- */
+
+ /*
+ * If Tcl_EvalObjEx returns, trying to eval [exit], something unusual is
+ * happening. Maybe interp has been deleted; maybe [exit] was redefined,
+ * maybe we've blown up because of an exceeded limit. We still want to
+ * cleanup and exit.
+ */
+
Tcl_Exit(exitCode);
}
-#ifndef UNICODE
-void
+#if (TCL_MAJOR_VERSION == 8) && !defined(UNICODE)
+#undef Tcl_Main
+extern DLLEXPORT void
Tcl_Main(
int argc, /* Number of arguments. */
- TCHAR **argv, /* Array of argument strings. */
+ char **argv, /* Array of argument strings. */
Tcl_AppInitProc *appInitProc)
/* Application-specific initialization
* function to call after most initialization
* but before starting to execute commands. */
{
- Tcl_FindExecutable(argv[0]);
- Tcl_MainEx(argc, argv, appInitProc, Tcl_CreateInterp());
+ Tcl_MainEx(argc, argv, appInitProc, Tcl_CreateInterp());
}
-#endif
+#endif /* TCL_MAJOR_VERSION == 8 && !UNICODE */
#ifndef TCL_ASCII_MAIN
@@ -707,6 +719,7 @@ TclGetMainLoop(void)
*
*----------------------------------------------------------------------
*/
+
MODULE_SCOPE int
TclFullFinalizationRequested(void)
{
@@ -723,7 +736,7 @@ TclFullFinalizationRequested(void)
Tcl_DStringFree(&ds);
}
return finalize;
-#endif
+#endif /* PURIFY */
}
#endif /* !TCL_ASCII_MAIN */
@@ -862,9 +875,8 @@ StdinProc(
static void
Prompt(
Tcl_Interp *interp, /* Interpreter to use for prompting. */
- InteractiveState *isPtr) /* InteractiveState. Filled
- * with PROMPT_NONE after a prompt is
- * printed. */
+ InteractiveState *isPtr) /* InteractiveState. Filled with PROMPT_NONE
+ * after a prompt is printed. */
{
Tcl_Obj *promptCmdPtr;
int code;
@@ -875,7 +887,7 @@ Prompt(
}
promptCmdPtr = Tcl_GetVar2Ex(interp,
- ((isPtr->prompt == PROMPT_CONTINUE) ? "tcl_prompt2" : "tcl_prompt1"),
+ (isPtr->prompt==PROMPT_CONTINUE ? "tcl_prompt2" : "tcl_prompt1"),
NULL, TCL_GLOBAL_ONLY);
if (Tcl_InterpDeleted(interp)) {
@@ -916,8 +928,8 @@ Prompt(
*
* FreeMainInterp --
*
- * Exit handler used to cleanup the main interpreter and ancillary startup
- * script storage at exit.
+ * Exit handler used to cleanup the main interpreter and ancillary
+ * startup script storage at exit.
*
*----------------------------------------------------------------------
*/
@@ -926,13 +938,13 @@ static void
FreeMainInterp(
ClientData clientData)
{
- Tcl_Interp *interp = (Tcl_Interp *) clientData;
+ Tcl_Interp *interp = clientData;
- //if (TclInExit()) return;
+ /*if (TclInExit()) return;*/
- if (!Tcl_InterpDeleted(interp)) {
- Tcl_DeleteInterp(interp);
- }
+ if (!Tcl_InterpDeleted(interp)) {
+ Tcl_DeleteInterp(interp);
+ }
Tcl_SetStartupScript(NULL, NULL);
Tcl_Release(interp);
}
diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c
index 9a2152a..8f2f10e 100644
--- a/generic/tclNamesp.c
+++ b/generic/tclNamesp.c
@@ -24,7 +24,7 @@
*/
#include "tclInt.h"
-#include "tclCompile.h" /* for NRCommand; and TclLogCommandInfo visibility */
+#include "tclCompile.h" /* for TclLogCommandInfo visibility */
/*
* Thread-local storage used to avoid having a global lock on data that is not
@@ -104,7 +104,7 @@ static int NamespaceDeleteCmd(ClientData dummy,Tcl_Interp *interp,
static int NamespaceEvalCmd(ClientData dummy, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
static int NRNamespaceEvalCmd(ClientData dummy,
- Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
+ Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
static int NamespaceExistsCmd(ClientData dummy,Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
static int NamespaceExportCmd(ClientData dummy,Tcl_Interp *interp,
@@ -160,25 +160,25 @@ static const Tcl_ObjType nsNameType = {
*/
static const EnsembleImplMap defaultNamespaceMap[] = {
- {"children", NamespaceChildrenCmd, NULL, NULL, NULL, 0},
- {"code", NamespaceCodeCmd, NULL, NULL, NULL, 0},
- {"current", NamespaceCurrentCmd, NULL, NULL, NULL, 0},
- {"delete", NamespaceDeleteCmd, NULL, NULL, NULL, 0},
- {"ensemble", TclNamespaceEnsembleCmd, NULL, NULL, NULL, 0},
- {"eval", NamespaceEvalCmd, NULL, NRNamespaceEvalCmd, NULL, 0},
- {"exists", NamespaceExistsCmd, NULL, NULL, NULL, 0},
- {"export", NamespaceExportCmd, NULL, NULL, NULL, 0},
- {"forget", NamespaceForgetCmd, NULL, NULL, NULL, 0},
- {"import", NamespaceImportCmd, NULL, NULL, NULL, 0},
- {"inscope", NamespaceInscopeCmd, NULL, NULL, NRNamespaceInscopeCmd, 0},
- {"origin", NamespaceOriginCmd, NULL, NULL, NULL, 0},
- {"parent", NamespaceParentCmd, NULL, NULL, NULL, 0},
- {"path", NamespacePathCmd, NULL, NULL, NULL, 0},
- {"qualifiers", NamespaceQualifiersCmd, NULL, NULL, NULL, 0},
- {"tail", NamespaceTailCmd, NULL, NULL, NULL, 0},
- {"unknown", NamespaceUnknownCmd, NULL, NULL, NULL, 0},
- {"upvar", NamespaceUpvarCmd, TclCompileNamespaceUpvarCmd, NULL, NULL, 0},
- {"which", NamespaceWhichCmd, NULL, NULL, NULL, 0},
+ {"children", NamespaceChildrenCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 0},
+ {"code", NamespaceCodeCmd, TclCompileNamespaceCodeCmd, NULL, NULL, 0},
+ {"current", NamespaceCurrentCmd, TclCompileNamespaceCurrentCmd, NULL, NULL, 0},
+ {"delete", NamespaceDeleteCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
+ {"ensemble", TclNamespaceEnsembleCmd, NULL, NULL, NULL, 0},
+ {"eval", NamespaceEvalCmd, NULL, NRNamespaceEvalCmd, NULL, 0},
+ {"exists", NamespaceExistsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"export", NamespaceExportCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
+ {"forget", NamespaceForgetCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
+ {"import", NamespaceImportCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
+ {"inscope", NamespaceInscopeCmd, NULL, NRNamespaceInscopeCmd, NULL, 0},
+ {"origin", NamespaceOriginCmd, TclCompileNamespaceOriginCmd, NULL, NULL, 0},
+ {"parent", NamespaceParentCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+ {"path", NamespacePathCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+ {"qualifiers", NamespaceQualifiersCmd, TclCompileNamespaceQualifiersCmd, NULL, NULL, 0},
+ {"tail", NamespaceTailCmd, TclCompileNamespaceTailCmd, NULL, NULL, 0},
+ {"unknown", NamespaceUnknownCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+ {"upvar", NamespaceUpvarCmd, TclCompileNamespaceUpvarCmd, NULL, NULL, 0},
+ {"which", NamespaceWhichCmd, TclCompileNamespaceWhichCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
};
@@ -423,7 +423,7 @@ Tcl_PopCallFrame(
framePtr->nsPtr = NULL;
if (framePtr->tailcallPtr) {
- TclSpliceTailcall(interp, framePtr->tailcallPtr);
+ TclSetTailcall(interp, framePtr->tailcallPtr);
}
}
@@ -505,9 +505,9 @@ EstablishErrorCodeTraces(
const char *name2,
int flags)
{
- Tcl_TraceVar(interp, "errorCode", TCL_GLOBAL_ONLY | TCL_TRACE_READS,
+ Tcl_TraceVar2(interp, "errorCode", NULL, TCL_GLOBAL_ONLY|TCL_TRACE_READS,
ErrorCodeRead, NULL);
- Tcl_TraceVar(interp, "errorCode", TCL_GLOBAL_ONLY | TCL_TRACE_UNSETS,
+ Tcl_TraceVar2(interp, "errorCode", NULL, TCL_GLOBAL_ONLY|TCL_TRACE_UNSETS,
EstablishErrorCodeTraces, NULL);
return NULL;
}
@@ -579,9 +579,9 @@ EstablishErrorInfoTraces(
const char *name2,
int flags)
{
- Tcl_TraceVar(interp, "errorInfo", TCL_GLOBAL_ONLY | TCL_TRACE_READS,
+ Tcl_TraceVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY|TCL_TRACE_READS,
ErrorInfoRead, NULL);
- Tcl_TraceVar(interp, "errorInfo", TCL_GLOBAL_ONLY | TCL_TRACE_UNSETS,
+ Tcl_TraceVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY|TCL_TRACE_UNSETS,
EstablishErrorInfoTraces, NULL);
return NULL;
}
@@ -673,6 +673,10 @@ Tcl_CreateNamespace(
Tcl_DString *namePtr, *buffPtr;
int newEntry, nameLen;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ const char *nameStr;
+ Tcl_DString tmpBuffer;
+
+ Tcl_DStringInit(&tmpBuffer);
/*
* If there is no active namespace, the interpreter is being initialized.
@@ -686,51 +690,78 @@ Tcl_CreateNamespace(
parentPtr = NULL;
simpleName = "";
- } else if (*name == '\0') {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "can't create namespace \"\": "
- "only global namespace can have empty name", NULL);
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NAMESPACE",
- "CREATEGLOBAL", NULL);
+ goto doCreate;
+ }
+
+ /*
+ * Ensure that there are no trailing colons as that causes chaos when a
+ * deleteProc is specified. [Bug d614d63989]
+ */
+
+ if (deleteProc != NULL) {
+ nameStr = name + strlen(name) - 2;
+ if (nameStr >= name && nameStr[1] == ':' && nameStr[0] == ':') {
+ Tcl_DStringAppend(&tmpBuffer, name, -1);
+ while ((nameLen = Tcl_DStringLength(&tmpBuffer)) > 0
+ && Tcl_DStringValue(&tmpBuffer)[nameLen-1] == ':') {
+ Tcl_DStringSetLength(&tmpBuffer, nameLen-1);
+ }
+ name = Tcl_DStringValue(&tmpBuffer);
+ }
+ }
+
+ /*
+ * If we've ended up with an empty string now, we're attempting to create
+ * the global namespace despite the global namespace existing. That's
+ * naughty!
+ */
+
+ if (*name == '\0') {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("can't create namespace"
+ " \"\": only global namespace can have empty name", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NAMESPACE",
+ "CREATEGLOBAL", NULL);
+ Tcl_DStringFree(&tmpBuffer);
return NULL;
- } else {
- /*
- * Find the parent for the new namespace.
- */
+ }
- TclGetNamespaceForQualName(interp, name, NULL,
- /*flags*/ (TCL_CREATE_NS_IF_UNKNOWN | TCL_LEAVE_ERR_MSG),
- &parentPtr, &dummy1Ptr, &dummy2Ptr, &simpleName);
+ /*
+ * Find the parent for the new namespace.
+ */
- /*
- * If the unqualified name at the end is empty, there were trailing
- * "::"s after the namespace's name which we ignore. The new namespace
- * was already (recursively) created and is pointed to by parentPtr.
- */
+ TclGetNamespaceForQualName(interp, name, NULL, TCL_CREATE_NS_IF_UNKNOWN,
+ &parentPtr, &dummy1Ptr, &dummy2Ptr, &simpleName);
- if (*simpleName == '\0') {
- return (Tcl_Namespace *) parentPtr;
- }
+ /*
+ * If the unqualified name at the end is empty, there were trailing "::"s
+ * after the namespace's name which we ignore. The new namespace was
+ * already (recursively) created and is pointed to by parentPtr.
+ */
- /*
- * Check for a bad namespace name and make sure that the name does not
- * already exist in the parent namespace.
- */
+ if (*simpleName == '\0') {
+ Tcl_DStringFree(&tmpBuffer);
+ return (Tcl_Namespace *) parentPtr;
+ }
- if (
+ /*
+ * Check for a bad namespace name and make sure that the name does not
+ * already exist in the parent namespace.
+ */
+
+ if (
#ifndef BREAK_NAMESPACE_COMPAT
- Tcl_FindHashEntry(&parentPtr->childTable, simpleName) != NULL
+ Tcl_FindHashEntry(&parentPtr->childTable, simpleName) != NULL
#else
- parentPtr->childTablePtr != NULL &&
- Tcl_FindHashEntry(parentPtr->childTablePtr, simpleName) != NULL
+ parentPtr->childTablePtr != NULL &&
+ Tcl_FindHashEntry(parentPtr->childTablePtr, simpleName) != NULL
#endif
- ) {
- Tcl_AppendResult(interp, "can't create namespace \"", name,
- "\": already exists", NULL);
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NAMESPACE",
- "CREATEEXISTING", NULL);
- return NULL;
- }
+ ) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't create namespace \"%s\": already exists", name));
+ Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NAMESPACE",
+ "CREATEEXISTING", NULL);
+ Tcl_DStringFree(&tmpBuffer);
+ return NULL;
}
/*
@@ -738,6 +769,7 @@ Tcl_CreateNamespace(
* of namespaces created.
*/
+ doCreate:
nsPtr = ckalloc(sizeof(Namespace));
nameLen = strlen(simpleName) + 1;
nsPtr->name = ckalloc(nameLen);
@@ -803,10 +835,9 @@ Tcl_CreateNamespace(
if (ancestorPtr != globalNsPtr) {
register Tcl_DString *tempPtr = namePtr;
- Tcl_DStringAppend(buffPtr, "::", 2);
+ TclDStringAppendLiteral(buffPtr, "::");
Tcl_DStringAppend(buffPtr, ancestorPtr->name, -1);
- Tcl_DStringAppend(buffPtr, Tcl_DStringValue(namePtr),
- Tcl_DStringLength(namePtr));
+ TclDStringAppendDString(buffPtr, namePtr);
/*
* Clear the unwanted buffer or we end up appending to previous
@@ -814,7 +845,7 @@ Tcl_CreateNamespace(
* very wrong (and strange).
*/
- Tcl_DStringSetLength(namePtr, 0);
+ TclDStringClear(namePtr);
/*
* Now swap the buffer pointers so that we build in the other
@@ -834,6 +865,7 @@ Tcl_CreateNamespace(
Tcl_DStringFree(&buffer1);
Tcl_DStringFree(&buffer2);
+ Tcl_DStringFree(&tmpBuffer);
/*
* If compilation of commands originating from the parent NS is
@@ -916,7 +948,7 @@ Tcl_DeleteNamespace(
for (entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
entryPtr != NULL;) {
cmdPtr = Tcl_GetHashValue(entryPtr);
- if (cmdPtr->nreProc == NRInterpCoroutine) {
+ if (cmdPtr->nreProc == TclNRInterpCoroutine) {
Tcl_DeleteCommandFromToken((Tcl_Interp *) iPtr,
(Tcl_Command) cmdPtr);
entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
@@ -1332,14 +1364,13 @@ Tcl_Export(
* Check that the pattern doesn't have namespace qualifiers.
*/
- TclGetNamespaceForQualName(interp, pattern, nsPtr,
- /*flags*/ (TCL_LEAVE_ERR_MSG | TCL_NAMESPACE_ONLY),
+ TclGetNamespaceForQualName(interp, pattern, nsPtr, TCL_NAMESPACE_ONLY,
&exportNsPtr, &dummyPtr, &dummyPtr, &simplePattern);
if ((exportNsPtr != nsPtr) || (strcmp(pattern, simplePattern) != 0)) {
- Tcl_AppendResult(interp, "invalid export pattern \"", pattern,
- "\": pattern can't specify a namespace", NULL);
- Tcl_SetErrorCode(interp, "TCL", "EXPORT", "INVALID", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid export pattern"
+ " \"%s\": pattern can't specify a namespace", pattern));
+ Tcl_SetErrorCode(interp, "TCL", "EXPORT", "INVALID", NULL);
return TCL_ERROR;
}
@@ -1544,30 +1575,29 @@ Tcl_Import(
if (strlen(pattern) == 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("empty import pattern",-1));
- Tcl_SetErrorCode(interp, "TCL", "IMPORT", "EMPTY", NULL);
+ Tcl_SetErrorCode(interp, "TCL", "IMPORT", "EMPTY", NULL);
return TCL_ERROR;
}
- TclGetNamespaceForQualName(interp, pattern, nsPtr,
- /*flags*/ (TCL_LEAVE_ERR_MSG | TCL_NAMESPACE_ONLY),
+ TclGetNamespaceForQualName(interp, pattern, nsPtr, TCL_NAMESPACE_ONLY,
&importNsPtr, &dummyPtr, &dummyPtr, &simplePattern);
if (importNsPtr == NULL) {
- Tcl_AppendResult(interp, "unknown namespace in import pattern \"",
- pattern, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown namespace in import pattern \"%s\"", pattern));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", pattern, NULL);
return TCL_ERROR;
}
if (importNsPtr == nsPtr) {
if (pattern == simplePattern) {
- Tcl_AppendResult(interp,
- "no namespace specified in import pattern \"", pattern,
- "\"", NULL);
- Tcl_SetErrorCode(interp, "TCL", "IMPORT", "ORIGIN", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "no namespace specified in import pattern \"%s\"",
+ pattern));
+ Tcl_SetErrorCode(interp, "TCL", "IMPORT", "ORIGIN", NULL);
} else {
- Tcl_AppendResult(interp, "import pattern \"", pattern,
- "\" tries to import from namespace \"",
- importNsPtr->name, "\" into itself", NULL);
- Tcl_SetErrorCode(interp, "TCL", "IMPORT", "SELF", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "import pattern \"%s\" tries to import from namespace"
+ " \"%s\" into itself", pattern, importNsPtr->name));
+ Tcl_SetErrorCode(interp, "TCL", "IMPORT", "SELF", NULL);
}
return TCL_ERROR;
}
@@ -1667,7 +1697,7 @@ DoImport(
Tcl_DStringInit(&ds);
Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
if (nsPtr != ((Interp *) interp)->globalNsPtr) {
- Tcl_DStringAppend(&ds, "::", 2);
+ TclDStringAppendLiteral(&ds, "::");
}
Tcl_DStringAppend(&ds, cmdName, -1);
@@ -1685,11 +1715,12 @@ DoImport(
dataPtr = linkCmd->objClientData;
linkCmd = dataPtr->realCmdPtr;
if (overwrite == linkCmd) {
- Tcl_AppendResult(interp, "import pattern \"", pattern,
- "\" would create a loop containing command \"",
- Tcl_DStringValue(&ds), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "import pattern \"%s\" would create a loop"
+ " containing command \"%s\"",
+ pattern, Tcl_DStringValue(&ds)));
Tcl_DStringFree(&ds);
- Tcl_SetErrorCode(interp, "TCL", "IMPORT", "LOOP", NULL);
+ Tcl_SetErrorCode(interp, "TCL", "IMPORT", "LOOP", NULL);
return TCL_ERROR;
}
}
@@ -1727,9 +1758,9 @@ DoImport(
return TCL_OK;
}
}
- Tcl_AppendResult(interp, "can't import command \"", cmdName,
- "\": already exists", NULL);
- Tcl_SetErrorCode(interp, "TCL", "IMPORT", "OVERWRITE", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't import command \"%s\": already exists", cmdName));
+ Tcl_SetErrorCode(interp, "TCL", "IMPORT", "OVERWRITE", NULL);
return TCL_ERROR;
}
return TCL_OK;
@@ -1792,14 +1823,13 @@ Tcl_ForgetImport(
* simple pattern.
*/
- TclGetNamespaceForQualName(interp, pattern, nsPtr,
- /*flags*/ (TCL_LEAVE_ERR_MSG | TCL_NAMESPACE_ONLY),
+ TclGetNamespaceForQualName(interp, pattern, nsPtr, TCL_NAMESPACE_ONLY,
&sourceNsPtr, &dummyPtr, &dummyPtr, &simplePattern);
if (sourceNsPtr == NULL) {
- Tcl_AppendResult(interp,
- "unknown namespace in namespace forget pattern \"",
- pattern, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown namespace in namespace forget pattern \"%s\"",
+ pattern));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", pattern, NULL);
return TCL_ERROR;
}
@@ -1946,8 +1976,8 @@ InvokeImportedNRCmd(
ImportedCmdData *dataPtr = clientData;
Command *realCmdPtr = dataPtr->realCmdPtr;
- ((Interp *) interp)->evalFlags |= TCL_EVAL_REDIRECT;
- return Tcl_NRCmdSwap(interp, (Tcl_Command) realCmdPtr, objc, objv, 0);
+ TclSkipTailcall(interp);
+ return TclNREvalObjv(interp, objc, objv, TCL_EVAL_NOERR, realCmdPtr);
}
static int
@@ -2241,7 +2271,7 @@ TclGetNamespaceForQualName(
* qualName since it may be a string constant.
*/
- Tcl_DStringSetLength(&buffer, 0);
+ TclDStringClear(&buffer);
Tcl_DStringAppend(&buffer, start, len);
nsName = Tcl_DStringValue(&buffer);
}
@@ -2403,8 +2433,8 @@ Tcl_FindNamespace(
}
if (flags & TCL_LEAVE_ERR_MSG) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "unknown namespace \"", name, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown namespace \"%s\"", name));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", name, NULL);
}
return NULL;
@@ -2590,8 +2620,8 @@ Tcl_FindCommand(
}
if (flags & TCL_LEAVE_ERR_MSG) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "unknown command \"", name, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown command \"%s\"", name));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", name, NULL);
}
return NULL;
@@ -2916,7 +2946,7 @@ NamespaceChildrenCmd(
} else {
Tcl_DStringAppend(&buffer, nsPtr->fullName, -1);
if (nsPtr != globalNsPtr) {
- Tcl_DStringAppend(&buffer, "::", 2);
+ TclDStringAppendLiteral(&buffer, "::");
}
Tcl_DStringAppend(&buffer, name, -1);
pattern = Tcl_DStringValue(&buffer);
@@ -3171,9 +3201,9 @@ NamespaceDeleteCmd(
namespacePtr = Tcl_FindNamespace(interp, name, NULL, /*flags*/ 0);
if ((namespacePtr == NULL)
|| (((Namespace *) namespacePtr)->flags & NS_KILLED)) {
- Tcl_AppendResult(interp, "unknown namespace \"",
- TclGetString(objv[i]),
- "\" in namespace delete command", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown namespace \"%s\" in namespace delete command",
+ TclGetString(objv[i])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE",
TclGetString(objv[i]), NULL);
return TCL_ERROR;
@@ -3286,12 +3316,12 @@ NRNamespaceEvalCmd(
}
if (iPtr->ensembleRewrite.sourceObjs == NULL) {
- framePtr->objc = objc;
- framePtr->objv = objv;
+ framePtr->objc = objc;
+ framePtr->objv = objv;
} else {
- framePtr->objc = objc + iPtr->ensembleRewrite.numRemovedObjs
- - iPtr->ensembleRewrite.numInsertedObjs;
- framePtr->objv = iPtr->ensembleRewrite.sourceObjs;
+ framePtr->objc = objc + iPtr->ensembleRewrite.numRemovedObjs
+ - iPtr->ensembleRewrite.numInsertedObjs;
+ framePtr->objv = iPtr->ensembleRewrite.sourceObjs;
}
if (objc == 3) {
@@ -3436,10 +3466,7 @@ NamespaceExportCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- Namespace *currNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
- const char *pattern, *string;
- int resetListFirst = 0;
- int firstArg, patternCt, i, result;
+ int firstArg, i;
if (objc < 1) {
Tcl_WrongNumArgs(interp, 1, objv, "?-clear? ?pattern pattern...?");
@@ -3447,42 +3474,27 @@ NamespaceExportCmd(
}
/*
- * Process the optional "-clear" argument.
+ * If no pattern arguments are given, and "-clear" isn't specified, return
+ * the namespace's current export pattern list.
*/
- firstArg = 1;
- if (firstArg < objc) {
- string = TclGetString(objv[firstArg]);
- if (strcmp(string, "-clear") == 0) {
- resetListFirst = 1;
- firstArg++;
- }
+ if (objc == 1) {
+ Tcl_Obj *listPtr = Tcl_NewObj();
+
+ (void) Tcl_AppendExportList(interp, NULL, listPtr);
+ Tcl_SetObjResult(interp, listPtr);
+ return TCL_OK;
}
/*
- * If no pattern arguments are given, and "-clear" isn't specified, return
- * the namespace's current export pattern list.
+ * Process the optional "-clear" argument.
*/
- patternCt = objc - firstArg;
- if (patternCt == 0) {
- if (firstArg > 1) {
- return TCL_OK;
- } else {
- /*
- * Create list with export patterns.
- */
-
- Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL);
-
- result = Tcl_AppendExportList(interp, (Tcl_Namespace *) currNsPtr,
- listPtr);
- if (result != TCL_OK) {
- return result;
- }
- Tcl_SetObjResult(interp, listPtr);
- return TCL_OK;
- }
+ firstArg = 1;
+ if (strcmp("-clear", Tcl_GetString(objv[firstArg])) == 0) {
+ Tcl_Export(interp, NULL, "::", 1);
+ Tcl_ResetResult(interp);
+ firstArg++;
}
/*
@@ -3490,9 +3502,7 @@ NamespaceExportCmd(
*/
for (i = firstArg; i < objc; i++) {
- pattern = TclGetString(objv[i]);
- result = Tcl_Export(interp, (Tcl_Namespace *) currNsPtr, pattern,
- ((i == firstArg)? resetListFirst : 0));
+ int result = Tcl_Export(interp, NULL, Tcl_GetString(objv[i]), 0);
if (result != TCL_OK) {
return result;
}
@@ -3749,12 +3759,12 @@ NRNamespaceInscopeCmd(
}
if (iPtr->ensembleRewrite.sourceObjs == NULL) {
- framePtr->objc = objc;
- framePtr->objv = objv;
+ framePtr->objc = objc;
+ framePtr->objv = objv;
} else {
- framePtr->objc = objc + iPtr->ensembleRewrite.numRemovedObjs
- - iPtr->ensembleRewrite.numInsertedObjs;
- framePtr->objv = iPtr->ensembleRewrite.sourceObjs;
+ framePtr->objc = objc + iPtr->ensembleRewrite.numRemovedObjs
+ - iPtr->ensembleRewrite.numInsertedObjs;
+ framePtr->objv = iPtr->ensembleRewrite.sourceObjs;
}
/*
@@ -3835,8 +3845,8 @@ NamespaceOriginCmd(
command = Tcl_GetCommandFromObj(interp, objv[1]);
if (command == NULL) {
- Tcl_AppendResult(interp, "invalid command name \"",
- TclGetString(objv[1]), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid command name \"%s\"", TclGetString(objv[1])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND",
TclGetString(objv[1]), NULL);
return TCL_ERROR;
@@ -3959,15 +3969,15 @@ NamespacePathCmd(
*/
if (objc == 1) {
- Tcl_Obj *resultObj = Tcl_NewObj();
+ Tcl_Obj *resultObj = Tcl_NewObj();
for (i=0 ; i<nsPtr->commandPathLength ; i++) {
if (nsPtr->commandPathArray[i].nsPtr != NULL) {
- Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
- nsPtr->commandPathArray[i].nsPtr->fullName, -1));
+ Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
+ nsPtr->commandPathArray[i].nsPtr->fullName, -1));
}
}
- Tcl_SetObjResult(interp, resultObj);
+ Tcl_SetObjResult(interp, resultObj);
return TCL_OK;
}
@@ -4844,8 +4854,8 @@ TclLogCommandInfo(
int length, /* Number of bytes in command (-1 means use
* all bytes up to first null byte). */
const unsigned char *pc, /* Current pc of bytecode execution context */
- Tcl_Obj **tosPtr) /* Current stack of bytecode execution
- * context */
+ Tcl_Obj **tosPtr) /* Current stack of bytecode execution
+ * context */
{
register const char *p;
Interp *iPtr = (Interp *) interp;
@@ -4862,55 +4872,55 @@ TclLogCommandInfo(
}
if (command != NULL) {
- /*
- * Compute the line number where the error occurred.
- */
-
- iPtr->errorLine = 1;
- for (p = script; p != command; p++) {
- if (*p == '\n') {
- iPtr->errorLine++;
- }
- }
-
- if (length < 0) {
- length = strlen(command);
- }
- overflow = (length > limit);
- Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ /*
+ * Compute the line number where the error occurred.
+ */
+
+ iPtr->errorLine = 1;
+ for (p = script; p != command; p++) {
+ if (*p == '\n') {
+ iPtr->errorLine++;
+ }
+ }
+
+ if (length < 0) {
+ length = strlen(command);
+ }
+ overflow = (length > limit);
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
"\n %s\n\"%.*s%s\"", ((iPtr->errorInfo == NULL)
? "while executing" : "invoked from within"),
(overflow ? limit : length), command,
(overflow ? "..." : "")));
- varPtr = TclObjLookupVarEx(interp, iPtr->eiVar, NULL, TCL_GLOBAL_ONLY,
+ varPtr = TclObjLookupVarEx(interp, iPtr->eiVar, NULL, TCL_GLOBAL_ONLY,
NULL, 0, 0, &arrayPtr);
- if ((varPtr == NULL) || !TclIsVarTraced(varPtr)) {
- /*
- * Should not happen.
- */
-
- return;
- } else {
- Tcl_HashEntry *hPtr
+ if ((varPtr == NULL) || !TclIsVarTraced(varPtr)) {
+ /*
+ * Should not happen.
+ */
+
+ return;
+ } else {
+ Tcl_HashEntry *hPtr
= Tcl_FindHashEntry(&iPtr->varTraces, (char *) varPtr);
- VarTrace *tracePtr = Tcl_GetHashValue(hPtr);
+ VarTrace *tracePtr = Tcl_GetHashValue(hPtr);
- if (tracePtr->traceProc != EstablishErrorInfoTraces) {
- /*
- * The most recent trace set on ::errorInfo is not the one the
- * core itself puts on last. This means some other code is
+ if (tracePtr->traceProc != EstablishErrorInfoTraces) {
+ /*
+ * The most recent trace set on ::errorInfo is not the one the
+ * core itself puts on last. This means some other code is
* tracing the variable, and the additional trace(s) might be
* write traces that expect the timing of writes to
* ::errorInfo that existed Tcl releases before 8.5. To
* satisfy that compatibility need, we write the current
* -errorinfo value to the ::errorInfo variable.
- */
+ */
- Tcl_ObjSetVar2(interp, iPtr->eiVar, NULL, iPtr->errorInfo,
+ Tcl_ObjSetVar2(interp, iPtr->eiVar, NULL, iPtr->errorInfo,
TCL_GLOBAL_ONLY);
- }
- }
+ }
+ }
}
/*
@@ -4918,60 +4928,60 @@ TclLogCommandInfo(
*/
if (Tcl_IsShared(iPtr->errorStack)) {
- Tcl_Obj *newObj;
-
- newObj = Tcl_DuplicateObj(iPtr->errorStack);
- Tcl_DecrRefCount(iPtr->errorStack);
- Tcl_IncrRefCount(newObj);
- iPtr->errorStack = newObj;
+ Tcl_Obj *newObj;
+
+ newObj = Tcl_DuplicateObj(iPtr->errorStack);
+ Tcl_DecrRefCount(iPtr->errorStack);
+ Tcl_IncrRefCount(newObj);
+ iPtr->errorStack = newObj;
}
if (iPtr->resetErrorStack) {
int len;
- iPtr->resetErrorStack = 0;
+ iPtr->resetErrorStack = 0;
Tcl_ListObjLength(interp, iPtr->errorStack, &len);
- /*
- * Reset while keeping the list intrep as much as possible.
- */
-
- Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, 0, NULL);
- if (pc != NULL) {
- Tcl_Obj *innerContext;
-
- innerContext = TclGetInnerContext(interp, pc, tosPtr);
- if (innerContext != NULL) {
- Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
- iPtr->innerLiteral);
- Tcl_ListObjAppendElement(NULL, iPtr->errorStack, innerContext);
- }
- } else if (command != NULL) {
- Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
- iPtr->innerLiteral);
- Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
- Tcl_NewStringObj(command, length));
- }
+ /*
+ * Reset while keeping the list intrep as much as possible.
+ */
+
+ Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, 0, NULL);
+ if (pc != NULL) {
+ Tcl_Obj *innerContext;
+
+ innerContext = TclGetInnerContext(interp, pc, tosPtr);
+ if (innerContext != NULL) {
+ Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
+ iPtr->innerLiteral);
+ Tcl_ListObjAppendElement(NULL, iPtr->errorStack, innerContext);
+ }
+ } else if (command != NULL) {
+ Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
+ iPtr->innerLiteral);
+ Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
+ Tcl_NewStringObj(command, length));
+ }
}
if (!iPtr->framePtr->objc) {
- /*
- * Special frame, nothing to report.
- */
+ /*
+ * Special frame, nothing to report.
+ */
} else if (iPtr->varFramePtr != iPtr->framePtr) {
- /*
- * uplevel case, [lappend errorstack UP $relativelevel]
- */
+ /*
+ * uplevel case, [lappend errorstack UP $relativelevel]
+ */
- Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->upLiteral);
- Tcl_ListObjAppendElement(NULL, iPtr->errorStack, Tcl_NewIntObj(
+ Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->upLiteral);
+ Tcl_ListObjAppendElement(NULL, iPtr->errorStack, Tcl_NewIntObj(
iPtr->framePtr->level - iPtr->varFramePtr->level));
} else if (iPtr->framePtr != iPtr->rootFramePtr) {
- /*
- * normal case, [lappend errorstack CALL [info level 0]]
- */
+ /*
+ * normal case, [lappend errorstack CALL [info level 0]]
+ */
- Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->callLiteral);
- Tcl_ListObjAppendElement(NULL, iPtr->errorStack, Tcl_NewListObj(
+ Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->callLiteral);
+ Tcl_ListObjAppendElement(NULL, iPtr->errorStack, Tcl_NewListObj(
iPtr->framePtr->objc, iPtr->framePtr->objv));
}
}
@@ -4981,8 +4991,8 @@ TclLogCommandInfo(
*
* TclErrorStackResetIf --
*
- * The TIP 348 reset/no-bc part of TLCI, for specific use by
- * TclCompileSyntaxError.
+ * The TIP 348 reset/no-bc part of TLCI, for specific use by
+ * TclCompileSyntaxError.
*
* Results:
* None.
@@ -5003,27 +5013,27 @@ TclErrorStackResetIf(
Interp *iPtr = (Interp *) interp;
if (Tcl_IsShared(iPtr->errorStack)) {
- Tcl_Obj *newObj;
-
- newObj = Tcl_DuplicateObj(iPtr->errorStack);
- Tcl_DecrRefCount(iPtr->errorStack);
- Tcl_IncrRefCount(newObj);
- iPtr->errorStack = newObj;
+ Tcl_Obj *newObj;
+
+ newObj = Tcl_DuplicateObj(iPtr->errorStack);
+ Tcl_DecrRefCount(iPtr->errorStack);
+ Tcl_IncrRefCount(newObj);
+ iPtr->errorStack = newObj;
}
if (iPtr->resetErrorStack) {
int len;
- iPtr->resetErrorStack = 0;
+ iPtr->resetErrorStack = 0;
Tcl_ListObjLength(interp, iPtr->errorStack, &len);
- /*
- * Reset while keeping the list intrep as much as possible.
- */
+ /*
+ * Reset while keeping the list intrep as much as possible.
+ */
- Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, 0, NULL);
- Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->innerLiteral);
- Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
- Tcl_NewStringObj(msg, length));
+ Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, 0, NULL);
+ Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->innerLiteral);
+ Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
+ Tcl_NewStringObj(msg, length));
}
}
@@ -5066,6 +5076,5 @@ Tcl_LogCommandInfo(
* c-basic-offset: 4
* fill-column: 78
* tab-width: 8
- * indent-tabs-mode: nil
* End:
*/
diff --git a/generic/tclNotify.c b/generic/tclNotify.c
index a6523fc..e76bca8 100644
--- a/generic/tclNotify.c
+++ b/generic/tclNotify.c
@@ -813,11 +813,7 @@ Tcl_SetMaxBlockTime(
*/
if (!tsdPtr->inTraversal) {
- if (tsdPtr->blockTimeSet) {
- Tcl_SetTimer(&tsdPtr->blockTime);
- } else {
- Tcl_SetTimer(NULL);
- }
+ Tcl_SetTimer(&tsdPtr->blockTime);
}
}
diff --git a/generic/tclOO.c b/generic/tclOO.c
index 8b76eeb..de00733 100644
--- a/generic/tclOO.c
+++ b/generic/tclOO.c
@@ -3,7 +3,7 @@
*
* This file contains the object-system core (NB: not Tcl_Obj, but ::oo)
*
- * Copyright (c) 2005-2011 by Donal K. Fellows
+ * Copyright (c) 2005-2012 by Donal K. Fellows
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -28,27 +28,20 @@ static const struct {
{"deletemethod", TclOODefineDeleteMethodObjCmd, 0},
{"destructor", TclOODefineDestructorObjCmd, 0},
{"export", TclOODefineExportObjCmd, 0},
- {"filter", TclOODefineFilterObjCmd, 0},
{"forward", TclOODefineForwardObjCmd, 0},
{"method", TclOODefineMethodObjCmd, 0},
- {"mixin", TclOODefineMixinObjCmd, 0},
{"renamemethod", TclOODefineRenameMethodObjCmd, 0},
{"self", TclOODefineSelfObjCmd, 0},
- {"superclass", TclOODefineSuperclassObjCmd, 0},
{"unexport", TclOODefineUnexportObjCmd, 0},
- {"variable", TclOODefineVariablesObjCmd, 0},
{NULL, NULL, 0}
}, objdefCmds[] = {
{"class", TclOODefineClassObjCmd, 1},
{"deletemethod", TclOODefineDeleteMethodObjCmd, 1},
{"export", TclOODefineExportObjCmd, 1},
- {"filter", TclOODefineFilterObjCmd, 1},
{"forward", TclOODefineForwardObjCmd, 1},
{"method", TclOODefineMethodObjCmd, 1},
- {"mixin", TclOODefineMixinObjCmd, 1},
{"renamemethod", TclOODefineRenameMethodObjCmd, 1},
{"unexport", TclOODefineUnexportObjCmd, 1},
- {"variable", TclOODefineVariablesObjCmd, 1},
{NULL, NULL, 0}
};
@@ -79,7 +72,7 @@ static int FinalizeNext(ClientData data[],
Tcl_Interp *interp, int result);
static int FinalizeObjectCall(ClientData data[],
Tcl_Interp *interp, int result);
-static void InitFoundation(Tcl_Interp *interp);
+static int InitFoundation(Tcl_Interp *interp);
static void KillFoundation(ClientData clientData,
Tcl_Interp *interp);
static void MyDeleted(ClientData clientData);
@@ -88,6 +81,7 @@ 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,
@@ -129,12 +123,92 @@ static const DeclaredClassMethod objMethods[] = {
{NULL, 0, {0, NULL, NULL, NULL, NULL}}
};
-static char initScript[] =
- "package ifneeded TclOO " TCLOO_PATCHLEVEL " {# Already present, OK?};"
- "namespace eval ::oo { variable version " TCLOO_VERSION " };"
- "namespace eval ::oo { variable patchlevel " TCLOO_PATCHLEVEL " };";
-/* "tcl_findLibrary tcloo $oo::version $oo::version" */
-/* " tcloo.tcl OO_LIBRARY oo::library;"; */
+/*
+ * And for the oo::class constructor...
+ */
+
+static const Tcl_MethodType classConstructor = {
+ TCL_OO_METHOD_VERSION_CURRENT,
+ "oo::class constructor",
+ TclOO_Class_Constructor, NULL, NULL
+};
+
+/*
+ * Scripted parts of TclOO. First, the master script (cannot be outside this
+ * file).
+ */
+
+static const char *initScript =
+"package ifneeded TclOO " TCLOO_PATCHLEVEL " {# Already present, OK?};"
+"namespace eval ::oo { variable version " TCLOO_VERSION " };"
+"namespace eval ::oo { variable patchlevel " TCLOO_PATCHLEVEL " };";
+/* "tcl_findLibrary tcloo $oo::version $oo::version" */
+/* " tcloo.tcl OO_LIBRARY oo::library;"; */
+
+/*
+ * The scripted part of the definitions of slots.
+ */
+
+static const char *slotScript =
+"::oo::define ::oo::Slot {\n"
+" method Get {} {error unimplemented}\n"
+" method Set list {error unimplemented}\n"
+" method -set args {\n"
+" uplevel 1 [list [namespace which my] Set $args]\n"
+" }\n"
+" method -append args {\n"
+" uplevel 1 [list [namespace which my] Set [list"
+" {*}[uplevel 1 [list [namespace which my] Get]] {*}$args]]\n"
+" }\n"
+" method -clear {} {uplevel 1 [list [namespace which my] Set {}]}\n"
+" forward --default-operation my -append\n"
+" method unknown {args} {\n"
+" set def --default-operation\n"
+" if {[llength $args] == 0} {\n"
+" return [uplevel 1 [list [namespace which my] $def]]\n"
+" } elseif {![string match -* [lindex $args 0]]} {\n"
+" return [uplevel 1 [list [namespace which my] $def {*}$args]]\n"
+" }\n"
+" next {*}$args\n"
+" }\n"
+" export -set -append -clear\n"
+" unexport unknown destroy\n"
+"}\n"
+"::oo::objdefine ::oo::define::superclass forward --default-operation my -set\n"
+"::oo::objdefine ::oo::define::mixin forward --default-operation my -set\n"
+"::oo::objdefine ::oo::objdefine::mixin forward --default-operation my -set\n";
+
+/*
+ * The body of the <cloned> method of oo::object.
+ */
+
+static const char *clonedBody =
+"foreach p [info procs [info object namespace $originObject]::*] {"
+" set args [info args $p];"
+" set idx -1;"
+" foreach a $args {"
+" lset args [incr idx] "
+" [if {[info default $p $a d]} {list $a $d} {list $a}]"
+" };"
+" set b [info body $p];"
+" set p [namespace tail $p];"
+" proc $p $args $b;"
+"};"
+"foreach v [info vars [info object namespace $originObject]::*] {"
+" upvar 0 $v vOrigin;"
+" namespace upvar [namespace current] [namespace tail $v] vNew;"
+" if {[info exists vOrigin]} {"
+" if {[array exists vOrigin]} {"
+" array set vNew [array get vOrigin];"
+" } else {"
+" set vNew $vOrigin;"
+" }"
+" }"
+"}";
+
+/*
+ * The actual definition of the variable holding the TclOO stub table.
+ */
MODULE_SCOPE const TclOOStubs tclOOStubs;
@@ -144,6 +218,20 @@ MODULE_SCOPE const TclOOStubs tclOOStubs;
#define GetFoundation(interp) \
((Foundation *)((Interp *)(interp))->objectFoundation)
+
+/*
+ * Macros to make inspecting into the guts of an object cleaner.
+ *
+ * The ocPtr parameter (only in these macros) is assumed to work fine with
+ * either an oPtr or a classPtr. Note that the roots oo::object and oo::class
+ * have _both_ their object and class flags tagged with ROOT_OBJECT and
+ * ROOT_CLASS respectively.
+ */
+
+#define Deleted(oPtr) (((Object *)(oPtr))->command == NULL)
+#define IsRootObject(ocPtr) ((ocPtr)->flags & ROOT_OBJECT)
+#define IsRootClass(ocPtr) ((ocPtr)->flags & ROOT_CLASS)
+#define IsRoot(ocPtr) ((ocPtr)->flags & (ROOT_OBJECT|ROOT_CLASS))
/*
* ----------------------------------------------------------------------
@@ -170,7 +258,9 @@ TclOOInit(
* Build the core of the OO system.
*/
- InitFoundation(interp);
+ if (InitFoundation(interp) != TCL_OK) {
+ return TCL_ERROR;
+ }
/*
* Run our initialization script and, if that works, declare the package
@@ -181,7 +271,7 @@ TclOOInit(
return TCL_ERROR;
}
- return Tcl_PkgProvideEx(interp, "TclOO", TCLOO_VERSION,
+ return Tcl_PkgProvideEx(interp, "TclOO", TCLOO_PATCHLEVEL,
(ClientData) &tclOOStubs);
}
@@ -214,7 +304,7 @@ TclOOGetFoundation(
* ----------------------------------------------------------------------
*/
-static void
+static int
InitFoundation(
Tcl_Interp *interp)
{
@@ -224,6 +314,7 @@ InitFoundation(
Foundation *fPtr = ckalloc(sizeof(Foundation));
Tcl_Obj *namePtr, *argsPtr, *bodyPtr;
Tcl_DString buffer;
+ Command *cmdPtr;
int i;
/*
@@ -245,17 +336,19 @@ InitFoundation(
DeletedHelpersNamespace);
fPtr->epoch = 0;
fPtr->tsdPtr = tsdPtr;
- fPtr->unknownMethodNameObj = Tcl_NewStringObj("unknown", -1);
- fPtr->constructorName = Tcl_NewStringObj("<constructor>", -1);
- fPtr->destructorName = Tcl_NewStringObj("<destructor>", -1);
+ TclNewLiteralStringObj(fPtr->unknownMethodNameObj, "unknown");
+ TclNewLiteralStringObj(fPtr->constructorName, "<constructor>");
+ TclNewLiteralStringObj(fPtr->destructorName, "<destructor>");
+ TclNewLiteralStringObj(fPtr->clonedName, "<cloned>");
+ TclNewLiteralStringObj(fPtr->defineName, "::oo::define");
Tcl_IncrRefCount(fPtr->unknownMethodNameObj);
Tcl_IncrRefCount(fPtr->constructorName);
Tcl_IncrRefCount(fPtr->destructorName);
- Tcl_NRCreateCommand(interp, "::oo::UpCatch", TclOOUpcatchCmd,
- TclOONRUpcatch, NULL, NULL);
+ Tcl_IncrRefCount(fPtr->clonedName);
+ Tcl_IncrRefCount(fPtr->defineName);
Tcl_CreateObjCommand(interp, "::oo::UnknownDefinition",
TclOOUnknownDefinition, NULL, NULL);
- namePtr = Tcl_NewStringObj("::oo::UnknownDefinition", -1);
+ TclNewLiteralStringObj(namePtr, "::oo::UnknownDefinition");
Tcl_SetNamespaceUnknownHandler(interp, fPtr->defineNs, namePtr);
Tcl_SetNamespaceUnknownHandler(interp, fPtr->objdefNs, namePtr);
@@ -265,14 +358,14 @@ InitFoundation(
Tcl_DStringInit(&buffer);
for (i=0 ; defineCmds[i].name ; i++) {
- Tcl_DStringAppend(&buffer, "::oo::define::", 14);
+ TclDStringAppendLiteral(&buffer, "::oo::define::");
Tcl_DStringAppend(&buffer, defineCmds[i].name, -1);
Tcl_CreateObjCommand(interp, Tcl_DStringValue(&buffer),
defineCmds[i].objProc, INT2PTR(defineCmds[i].flag), NULL);
Tcl_DStringFree(&buffer);
}
for (i=0 ; objdefCmds[i].name ; i++) {
- Tcl_DStringAppend(&buffer, "::oo::objdefine::", 17);
+ TclDStringAppendLiteral(&buffer, "::oo::objdefine::");
Tcl_DStringAppend(&buffer, objdefCmds[i].name, -1);
Tcl_CreateObjCommand(interp, Tcl_DStringValue(&buffer),
objdefCmds[i].objProc, INT2PTR(objdefCmds[i].flag), NULL);
@@ -292,11 +385,13 @@ InitFoundation(
AllocObject(interp, "::oo::class", NULL));
fPtr->objectCls->thisPtr->selfCls = fPtr->classCls;
fPtr->objectCls->thisPtr->flags |= ROOT_OBJECT;
+ fPtr->objectCls->flags |= ROOT_OBJECT;
fPtr->objectCls->superclasses.num = 0;
ckfree(fPtr->objectCls->superclasses.list);
fPtr->objectCls->superclasses.list = NULL;
fPtr->classCls->thisPtr->selfCls = 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);
AddRef(fPtr->objectCls->thisPtr);
@@ -314,49 +409,58 @@ InitFoundation(
}
/*
+ * Create the default <cloned> method implementation, used when 'oo::copy'
+ * is called to finish the copying of one object to another.
+ */
+
+ TclNewLiteralStringObj(argsPtr, "originObject");
+ Tcl_IncrRefCount(argsPtr);
+ bodyPtr = Tcl_NewStringObj(clonedBody, -1);
+ TclOONewProcMethod(interp, fPtr->objectCls, 0, fPtr->clonedName, argsPtr,
+ bodyPtr, NULL);
+ TclDecrRefCount(argsPtr);
+
+ /*
* Finish setting up the class of classes by marking the 'new' method as
* private; classes, unlike general objects, must have explicit names. We
* also need to create the constructor for classes.
- *
- * The 0xDeadBeef is a special signal to the errorInfo logger that is used
- * by constructors that stops it from generating extra error information
- * that is confusing.
*/
- namePtr = Tcl_NewStringObj("new", -1);
+ TclNewLiteralStringObj(namePtr, "new");
Tcl_NewInstanceMethod(interp, (Tcl_Object) fPtr->classCls->thisPtr,
namePtr /* keeps ref */, 0 /* ==private */, NULL, NULL);
-
- argsPtr = Tcl_NewStringObj("{definitionScript {}}", -1);
- Tcl_IncrRefCount(argsPtr);
- bodyPtr = Tcl_NewStringObj(
- "set script [list ::oo::define [self] $definitionScript];"
- "lassign [::oo::UpCatch $script] msg opts\n"
- "if {[dict get $opts -code] == 1} {"
- " dict set opts -errorline 0xDeadBeef\n"
- "}\n"
- "return -options $opts $msg", -1);
- fPtr->classCls->constructorPtr = TclOONewProcMethod(interp,
- fPtr->classCls, 0, NULL, argsPtr, bodyPtr, NULL);
- Tcl_DecrRefCount(argsPtr);
+ fPtr->classCls->constructorPtr = (Method *) Tcl_NewMethod(interp,
+ (Tcl_Class) fPtr->classCls, NULL, 0, &classConstructor, NULL);
/*
* Create non-object commands and plug ourselves into the Tcl [info]
* ensemble.
*/
- Tcl_CreateObjCommand(interp, "::oo::Helpers::next", TclOONextObjCmd, NULL,
- NULL);
- Tcl_CreateObjCommand(interp, "::oo::Helpers::nextto", TclOONextToObjCmd,
- NULL, NULL);
- Tcl_CreateObjCommand(interp, "::oo::Helpers::self", TclOOSelfObjCmd, NULL,
- NULL);
+ cmdPtr = (Command *) Tcl_NRCreateCommand(interp, "::oo::Helpers::next",
+ NULL, TclOONextObjCmd, NULL, NULL);
+ cmdPtr->compileProc = TclCompileObjectNextCmd;
+ cmdPtr = (Command *) Tcl_NRCreateCommand(interp, "::oo::Helpers::nextto",
+ NULL, TclOONextToObjCmd, NULL, NULL);
+ cmdPtr->compileProc = TclCompileObjectNextToCmd;
+ cmdPtr = (Command *) Tcl_CreateObjCommand(interp, "::oo::Helpers::self",
+ TclOOSelfObjCmd, NULL, NULL);
+ cmdPtr->compileProc = TclCompileObjectSelfCmd;
Tcl_CreateObjCommand(interp, "::oo::define", TclOODefineObjCmd, NULL,
NULL);
Tcl_CreateObjCommand(interp, "::oo::objdefine", TclOOObjDefObjCmd, NULL,
NULL);
Tcl_CreateObjCommand(interp, "::oo::copy", TclOOCopyObjectCmd, NULL,NULL);
TclOOInitInfo(interp);
+
+ /*
+ * Now make the class of slots.
+ */
+
+ if (TclOODefineSlots(fPtr) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ return Tcl_Eval(interp, slotScript);
}
/*
@@ -419,9 +523,11 @@ KillFoundation(
DelRef(fPtr->objectCls->thisPtr);
DelRef(fPtr->objectCls);
- Tcl_DecrRefCount(fPtr->unknownMethodNameObj);
- Tcl_DecrRefCount(fPtr->constructorName);
- Tcl_DecrRefCount(fPtr->destructorName);
+ TclDecrRefCount(fPtr->unknownMethodNameObj);
+ TclDecrRefCount(fPtr->constructorName);
+ TclDecrRefCount(fPtr->destructorName);
+ TclDecrRefCount(fPtr->clonedName);
+ TclDecrRefCount(fPtr->defineName);
ckfree(fPtr);
}
@@ -556,7 +662,7 @@ AllocObject(
Tcl_DStringInit(&buffer);
Tcl_DStringAppend(&buffer,
Tcl_GetCurrentNamespace(interp)->fullName, -1);
- Tcl_DStringAppend(&buffer, "::", 2);
+ TclDStringAppendLiteral(&buffer, "::");
Tcl_DStringAppend(&buffer, nameStr, -1);
oPtr->command = Tcl_CreateObjCommand(interp,
Tcl_DStringValue(&buffer), PublicObjectCmd, oPtr, NULL);
@@ -603,6 +709,27 @@ AllocObject(
/*
* ----------------------------------------------------------------------
*
+ * SquelchCachedName --
+ *
+ * Encapsulates how to throw away a cached object name. Called from
+ * object rename traces and at object destruction.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline void
+SquelchCachedName(
+ Object *oPtr)
+{
+ if (oPtr->cachedNameObj) {
+ Tcl_DecrRefCount(oPtr->cachedNameObj);
+ oPtr->cachedNameObj = NULL;
+ }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
* MyDeleted --
*
* This callback is triggered when the object's [my] command is deleted
@@ -669,8 +796,7 @@ ObjectRenamedTrace(
int flags) /* Why was the object deleted? */
{
Object *oPtr = clientData;
- Class *clsPtr;
- CallContext *contextPtr;
+ Foundation *fPtr = oPtr->fPtr;
/*
* If this is a rename and not a delete of the object, we just flush the
@@ -678,10 +804,7 @@ ObjectRenamedTrace(
*/
if (flags & TCL_TRACE_RENAME) {
- if (oPtr->cachedNameObj) {
- Tcl_DecrRefCount(oPtr->cachedNameObj);
- oPtr->cachedNameObj = NULL;
- }
+ SquelchCachedName(oPtr);
return;
}
@@ -702,24 +825,27 @@ ObjectRenamedTrace(
*/
AddRef(oPtr);
+ AddRef(fPtr->classCls);
+ AddRef(fPtr->objectCls);
+ AddRef(fPtr->classCls->thisPtr);
+ AddRef(fPtr->objectCls->thisPtr);
oPtr->command = NULL;
- oPtr->flags |= OBJECT_DELETED;
- if (!(oPtr->flags & DESTRUCTOR_CALLED) && (!Tcl_InterpDeleted(interp)
- || (oPtr->flags & (ROOT_OBJECT|ROOT_CLASS)))) {
- contextPtr = TclOOGetCallContext(oPtr, NULL, DESTRUCTOR, 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) {
- int result;
- Tcl_InterpState state;
-
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_BackgroundError(interp);
+ Tcl_BackgroundException(interp, result);
}
Tcl_RestoreInterpState(interp, state);
TclOODeleteContext(contextPtr);
@@ -731,25 +857,20 @@ ObjectRenamedTrace(
* and nuke the namespace (which triggers the final crushing of the object
* structure itself).
*
- * The class of classes needs some special care; if it is deleted (and
+ * 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 objects now as well. Due to the incestuous nature of those two
+ * 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)) {
- if ((oPtr->flags & ROOT_OBJECT) && oPtr->fPtr->classCls != NULL) {
- Tcl_DeleteCommandFromToken(interp,
- oPtr->fPtr->classCls->thisPtr->command);
- } else if (oPtr->flags & ROOT_CLASS) {
- oPtr->fPtr->classCls = NULL;
- }
+ if (!Tcl_InterpDeleted(interp) && IsRootObject(oPtr)
+ && !Deleted(fPtr->classCls->thisPtr)) {
+ Tcl_DeleteCommandFromToken(interp, fPtr->classCls->thisPtr->command);
}
- clsPtr = oPtr->classPtr;
- if (clsPtr != NULL) {
- AddRef(clsPtr);
+ if (oPtr->classPtr != NULL) {
+ AddRef(oPtr->classPtr);
ReleaseClassContents(interp, oPtr);
}
@@ -761,9 +882,13 @@ ObjectRenamedTrace(
if (((Namespace *) oPtr->namespacePtr)->earlyDeleteProc != NULL) {
Tcl_DeleteNamespace(oPtr->namespacePtr);
}
- if (clsPtr) {
- DelRef(clsPtr);
+ if (oPtr->classPtr) {
+ DelRef(oPtr->classPtr);
}
+ DelRef(fPtr->classCls->thisPtr);
+ DelRef(fPtr->objectCls->thisPtr);
+ DelRef(fPtr->classCls);
+ DelRef(fPtr->objectCls);
DelRef(oPtr);
}
@@ -783,77 +908,128 @@ ReleaseClassContents(
Tcl_Interp *interp, /* The interpreter containing the class. */
Object *oPtr) /* The object representing the class. */
{
- int i, n;
- Class *clsPtr = oPtr->classPtr, **list;
- Object **insts;
+ FOREACH_HASH_DECLS;
+ int i;
+ Class *clsPtr = oPtr->classPtr, *mixinSubclassPtr, *subclassPtr;
+ Object *instancePtr;
+ Foundation *fPtr = oPtr->fPtr;
/*
- * Must empty list before processing the members of the list so that
- * things happen in the correct order even if something tries to play
- * fast-and-loose.
+ * Sanity check!
*/
- list = clsPtr->mixinSubs.list;
- n = clsPtr->mixinSubs.num;
- clsPtr->mixinSubs.list = NULL;
- clsPtr->mixinSubs.num = 0;
- clsPtr->mixinSubs.size = 0;
- for (i=0 ; i<n ; i++) {
- AddRef(list[i]);
- AddRef(list[i]->thisPtr);
+ if (!Deleted(oPtr)) {
+ if (IsRootClass(oPtr)) {
+ Tcl_Panic("deleting class structure for non-deleted %s",
+ "::oo::class");
+ } 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");
+ }
}
- for (i=0 ; i<n ; i++) {
- if (!(list[i]->thisPtr->flags & OBJECT_DELETED)) {
- list[i]->thisPtr->flags |= OBJECT_DELETED;
- Tcl_DeleteCommandFromToken(interp, list[i]->thisPtr->command);
+
+ /*
+ * 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);
}
- DelRef(list[i]->thisPtr);
- DelRef(list[i]);
}
- if (list != NULL) {
- ckfree(list);
+ FOREACH(subclassPtr, clsPtr->subclasses) {
+ if (subclassPtr != NULL && !IsRoot(subclassPtr)) {
+ AddRef(subclassPtr);
+ AddRef(subclassPtr->thisPtr);
+ }
}
-
- list = clsPtr->subclasses.list;
- n = clsPtr->subclasses.num;
- clsPtr->subclasses.list = NULL;
- clsPtr->subclasses.num = 0;
- clsPtr->subclasses.size = 0;
- for (i=0 ; i<n ; i++) {
- AddRef(list[i]);
- AddRef(list[i]->thisPtr);
+ if (!IsRootClass(oPtr)) {
+ FOREACH(instancePtr, clsPtr->instances) {
+ if (instancePtr != NULL && !IsRoot(instancePtr)) {
+ AddRef(instancePtr);
+ }
+ }
}
- for (i=0 ; i<n ; i++) {
- if (!(list[i]->thisPtr->flags & OBJECT_DELETED)) {
- list[i]->thisPtr->flags |= OBJECT_DELETED;
- Tcl_DeleteCommandFromToken(interp, list[i]->thisPtr->command);
+
+ /*
+ * Squelch classes that this class has been mixed into.
+ */
+
+ FOREACH(mixinSubclassPtr, clsPtr->mixinSubs) {
+ if (mixinSubclassPtr == NULL) {
+ continue;
+ }
+ if (!Deleted(mixinSubclassPtr->thisPtr)) {
+ Tcl_DeleteCommandFromToken(interp,
+ mixinSubclassPtr->thisPtr->command);
}
- DelRef(list[i]->thisPtr);
- DelRef(list[i]);
+ DelRef(mixinSubclassPtr->thisPtr);
+ DelRef(mixinSubclassPtr);
}
- if (list != NULL) {
- ckfree(list);
+ if (clsPtr->mixinSubs.list != NULL) {
+ ckfree(clsPtr->mixinSubs.list);
+ clsPtr->mixinSubs.list = NULL;
+ clsPtr->mixinSubs.num = 0;
}
- insts = clsPtr->instances.list;
- n = clsPtr->instances.num;
- clsPtr->instances.list = NULL;
- clsPtr->instances.num = 0;
- clsPtr->instances.size = 0;
- for (i=0 ; i<n ; i++) {
- AddRef(insts[i]);
+ /*
+ * Squelch subclasses of this class.
+ */
+
+ FOREACH(subclassPtr, clsPtr->subclasses) {
+ if (subclassPtr == NULL || IsRoot(subclassPtr)) {
+ continue;
+ }
+ if (!Deleted(subclassPtr->thisPtr)) {
+ Tcl_DeleteCommandFromToken(interp, subclassPtr->thisPtr->command);
+ }
+ DelRef(subclassPtr->thisPtr);
+ DelRef(subclassPtr);
+ }
+ if (clsPtr->subclasses.list != NULL) {
+ ckfree(clsPtr->subclasses.list);
+ clsPtr->subclasses.list = NULL;
+ clsPtr->subclasses.num = 0;
}
- for (i=0 ; i<n ; i++) {
- if (!(insts[i]->flags & OBJECT_DELETED)) {
- insts[i]->flags |= OBJECT_DELETED;
- Tcl_DeleteCommandFromToken(interp, insts[i]->command);
+
+ /*
+ * 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);
+ }
+ DelRef(instancePtr);
}
- DelRef(insts[i]);
}
- if (insts != NULL) {
- ckfree(insts);
+ 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.
+ */
+
if (clsPtr->constructorChainPtr) {
TclOODeleteChain(clsPtr->constructorChainPtr);
clsPtr->constructorChainPtr = NULL;
@@ -863,7 +1039,6 @@ ReleaseClassContents(
clsPtr->destructorChainPtr = NULL;
}
if (clsPtr->classChainCache) {
- FOREACH_HASH_DECLS;
CallChain *callPtr;
FOREACH_HASH_VALUE(callPtr, clsPtr->classChainCache) {
@@ -874,19 +1049,25 @@ ReleaseClassContents(
clsPtr->classChainCache = NULL;
}
+ /*
+ * Squelch our filter list.
+ */
+
if (clsPtr->filters.num) {
Tcl_Obj *filterObj;
FOREACH(filterObj, clsPtr->filters) {
- Tcl_DecrRefCount(filterObj);
+ TclDecrRefCount(filterObj);
}
ckfree(clsPtr->filters.list);
clsPtr->filters.num = 0;
}
+ /*
+ * Squelch our metadata.
+ */
if (clsPtr->metadataPtr != NULL) {
- FOREACH_HASH_DECLS;
Tcl_ObjectMetadataType *metadataTypePtr;
ClientData value;
@@ -922,7 +1103,7 @@ ObjectNamespaceDeleted(
Class *clsPtr = oPtr->classPtr, *mixinPtr;
Method *mPtr;
Tcl_Obj *filterObj, *variableObj;
- int i, preserved = !(oPtr->flags & OBJECT_DELETED);
+ int i;
/*
* Instruct everyone to no longer use any allocated fields of the object.
@@ -931,27 +1112,19 @@ ObjectNamespaceDeleted(
* point into freed memory, allowing crashes.
*/
- oPtr->flags |= OBJECT_DELETED;
if (oPtr->command) {
Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command);
}
if (oPtr->myCommand) {
Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->myCommand);
}
- if (preserved) {
- AddRef(oPtr);
- if (clsPtr != NULL) {
- AddRef(clsPtr);
- ReleaseClassContents(NULL, oPtr);
- }
- }
/*
* Splice the object out of its context. After this, we must *not* call
* methods on the object.
*/
- if (!(oPtr->flags & ROOT_OBJECT)) {
+ if (!IsRootObject(oPtr)) {
TclOORemoveFromInstances(oPtr, oPtr->selfCls);
}
@@ -963,7 +1136,7 @@ ObjectNamespaceDeleted(
}
FOREACH(filterObj, oPtr->filters) {
- Tcl_DecrRefCount(filterObj);
+ TclDecrRefCount(filterObj);
}
if (i) {
ckfree(oPtr->filters.list);
@@ -978,7 +1151,7 @@ ObjectNamespaceDeleted(
}
FOREACH(variableObj, oPtr->variables) {
- Tcl_DecrRefCount(variableObj);
+ TclDecrRefCount(variableObj);
}
if (i) {
ckfree(oPtr->variables.list);
@@ -988,10 +1161,7 @@ ObjectNamespaceDeleted(
TclOODeleteChainCache(oPtr->chainCache);
}
- if (oPtr->cachedNameObj) {
- Tcl_DecrRefCount(oPtr->cachedNameObj);
- oPtr->cachedNameObj = NULL;
- }
+ SquelchCachedName(oPtr);
if (oPtr->metadataPtr != NULL) {
Tcl_ObjectMetadataType *metadataTypePtr;
@@ -1007,11 +1177,10 @@ ObjectNamespaceDeleted(
if (clsPtr != NULL) {
Class *superPtr;
+ Tcl_ObjectMetadataType *metadataTypePtr;
+ ClientData value;
if (clsPtr->metadataPtr != NULL) {
- Tcl_ObjectMetadataType *metadataTypePtr;
- ClientData value;
-
FOREACH_HASH(metadataTypePtr, value, clsPtr->metadataPtr) {
metadataTypePtr->deleteProc(value);
}
@@ -1021,14 +1190,14 @@ ObjectNamespaceDeleted(
}
FOREACH(filterObj, clsPtr->filters) {
- Tcl_DecrRefCount(filterObj);
+ TclDecrRefCount(filterObj);
}
if (i) {
ckfree(clsPtr->filters.list);
clsPtr->filters.num = 0;
}
FOREACH(mixinPtr, clsPtr->mixins) {
- if (!(mixinPtr->thisPtr->flags & OBJECT_DELETED)) {
+ if (!Deleted(mixinPtr->thisPtr)) {
TclOORemoveFromMixinSubs(clsPtr, mixinPtr);
}
}
@@ -1037,7 +1206,7 @@ ObjectNamespaceDeleted(
clsPtr->mixins.num = 0;
}
FOREACH(superPtr, clsPtr->superclasses) {
- if (!(superPtr->thisPtr->flags & OBJECT_DELETED)) {
+ if (!Deleted(superPtr->thisPtr)) {
TclOORemoveFromSubclasses(clsPtr, superPtr);
}
}
@@ -1066,7 +1235,7 @@ ObjectNamespaceDeleted(
TclOODelMethodRef(clsPtr->destructorPtr);
FOREACH(variableObj, clsPtr->variables) {
- Tcl_DecrRefCount(variableObj);
+ TclDecrRefCount(variableObj);
}
if (i) {
ckfree(clsPtr->variables.list);
@@ -1080,12 +1249,6 @@ ObjectNamespaceDeleted(
*/
DelRef(oPtr);
- if (preserved) {
- if (clsPtr) {
- DelRef(clsPtr);
- }
- DelRef(oPtr);
- }
}
/*
@@ -1116,12 +1279,16 @@ TclOORemoveFromInstances(
return;
removeInstance:
- clsPtr->instances.num--;
- if (i < clsPtr->instances.num) {
- clsPtr->instances.list[i] =
- clsPtr->instances.list[clsPtr->instances.num];
+ if (Deleted(clsPtr->thisPtr)) {
+ clsPtr->instances.list[i] = NULL;
+ } else {
+ clsPtr->instances.num--;
+ if (i < clsPtr->instances.num) {
+ clsPtr->instances.list[i] =
+ clsPtr->instances.list[clsPtr->instances.num];
+ }
+ clsPtr->instances.list[clsPtr->instances.num] = NULL;
}
- clsPtr->instances.list[clsPtr->instances.num] = NULL;
}
/*
@@ -1142,6 +1309,9 @@ 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) {
@@ -1182,12 +1352,16 @@ TclOORemoveFromSubclasses(
return;
removeSubclass:
- superPtr->subclasses.num--;
- if (i < superPtr->subclasses.num) {
- superPtr->subclasses.list[i] =
- superPtr->subclasses.list[superPtr->subclasses.num];
+ if (Deleted(superPtr->thisPtr)) {
+ superPtr->subclasses.list[i] = NULL;
+ } else {
+ 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;
}
- superPtr->subclasses.list[superPtr->subclasses.num] = NULL;
}
/*
@@ -1208,6 +1382,9 @@ TclOOAddToSubclasses(
* is assumed that the class is not already
* present as a subclass in the superclass. */
{
+ if (Deleted(superPtr->thisPtr)) {
+ return;
+ }
if (superPtr->subclasses.num >= superPtr->subclasses.size) {
superPtr->subclasses.size += ALLOC_CHUNK;
if (superPtr->subclasses.size == ALLOC_CHUNK) {
@@ -1248,12 +1425,16 @@ TclOORemoveFromMixinSubs(
return;
removeSubclass:
- superPtr->mixinSubs.num--;
- if (i < superPtr->mixinSubs.num) {
- superPtr->mixinSubs.list[i] =
- superPtr->mixinSubs.list[superPtr->mixinSubs.num];
+ if (Deleted(superPtr->thisPtr)) {
+ superPtr->mixinSubs.list[i] = NULL;
+ } else {
+ superPtr->mixinSubs.num--;
+ if (i < superPtr->mixinSubs.num) {
+ superPtr->mixinSubs.list[i] =
+ superPtr->mixinSubs.list[superPtr->mixinSubs.num];
+ }
+ superPtr->mixinSubs.list[superPtr->mixinSubs.num] = NULL;
}
- superPtr->mixinSubs.list[superPtr->mixinSubs.num] = NULL;
}
/*
@@ -1274,6 +1455,9 @@ TclOOAddToMixinSubs(
* is assumed that the class is not already
* present as a subclass in the superclass. */
{
+ if (Deleted(superPtr->thisPtr)) {
+ return;
+ }
if (superPtr->mixinSubs.num >= superPtr->mixinSubs.size) {
superPtr->mixinSubs.size += ALLOC_CHUNK;
if (superPtr->mixinSubs.size == ALLOC_CHUNK) {
@@ -1402,8 +1586,9 @@ Tcl_NewObjectInstance(
if (nameStr && Tcl_FindCommand(interp, nameStr, NULL,
TCL_NAMESPACE_ONLY)) {
- Tcl_AppendResult(interp, "can't create object \"", nameStr,
- "\": command already exists with that name", NULL);
+ 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;
}
@@ -1444,15 +1629,23 @@ Tcl_NewObjectInstance(
TclOOGetCallContext(oPtr, NULL, CONSTRUCTOR, NULL);
if (contextPtr != NULL) {
- int result, flags;
+ int result;
Tcl_InterpState state;
state = Tcl_SaveInterpState(interp, TCL_OK);
contextPtr->callPtr->flags |= CONSTRUCTOR;
contextPtr->skip = skip;
+
+ /*
+ * Adjust the ensmble tracking record if necessary. [Bug 3514761]
+ */
+
+ if (((Interp*) interp)->ensembleRewrite.sourceObjs) {
+ ((Interp*) interp)->ensembleRewrite.numInsertedObjs += skip-1;
+ ((Interp*) interp)->ensembleRewrite.numRemovedObjs += skip-1;
+ }
result = Tcl_NRCallObjProc(interp, TclOOInvokeContext, contextPtr,
objc, objv);
- flags = oPtr->flags;
/*
* It's an error if the object was whacked in the constructor.
@@ -1460,9 +1653,9 @@ Tcl_NewObjectInstance(
* errors by accident...) [Bug 2903011]
*/
- if (result != TCL_ERROR && (flags & OBJECT_DELETED)) {
- Tcl_SetResult(interp, "object deleted in constructor",
- TCL_STATIC);
+ 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;
}
@@ -1475,7 +1668,7 @@ Tcl_NewObjectInstance(
* bad. [Bug 2903011]
*/
- if (!(flags & OBJECT_DELETED)) {
+ if (!Deleted(oPtr)) {
Tcl_DeleteCommandFromToken(interp, oPtr->command);
}
return NULL;
@@ -1517,8 +1710,9 @@ TclNRNewObjectInstance(
if (nameStr && Tcl_FindCommand(interp, nameStr, NULL,
TCL_NAMESPACE_ONLY)) {
- Tcl_AppendResult(interp, "can't create object \"", nameStr,
- "\": command already exists with that name", NULL);
+ 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;
}
@@ -1569,9 +1763,19 @@ TclNRNewObjectInstance(
contextPtr->skip = skip;
/*
+ * Adjust the ensmble tracking record if necessary. [Bug 3514761]
+ */
+
+ if (((Interp *) interp)->ensembleRewrite.sourceObjs) {
+ ((Interp *) interp)->ensembleRewrite.numInsertedObjs += skip - 1;
+ ((Interp *) interp)->ensembleRewrite.numRemovedObjs += skip - 1;
+ }
+
+ /*
* Fire off the constructors non-recursively.
*/
+ AddRef(oPtr);
TclNRAddCallback(interp, FinalizeAlloc, contextPtr, oPtr, state,
objectPtr);
TclPushTailcallPoint(interp);
@@ -1588,7 +1792,6 @@ FinalizeAlloc(
Object *oPtr = data[1];
Tcl_InterpState state = data[2];
Tcl_Object *objectPtr = data[3];
- int flags = oPtr->flags;
/*
* It's an error if the object was whacked in the constructor. Force this
@@ -1596,8 +1799,9 @@ FinalizeAlloc(
* [Bug 2903011]
*/
- if (result != TCL_ERROR && (flags & OBJECT_DELETED)) {
- Tcl_SetResult(interp, "object deleted in constructor", TCL_STATIC);
+ 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;
}
@@ -1610,13 +1814,15 @@ FinalizeAlloc(
* 2903011]
*/
- if (!(flags & OBJECT_DELETED)) {
+ if (!Deleted(oPtr)) {
Tcl_DeleteCommandFromToken(interp, oPtr->command);
}
+ DelRef(oPtr);
return TCL_ERROR;
}
Tcl_RestoreInterpState(interp, state);
*objectPtr = (Tcl_Object) oPtr;
+ DelRef(oPtr);
return TCL_OK;
}
@@ -1643,21 +1849,17 @@ Tcl_CopyObjectInstance(
FOREACH_HASH_DECLS;
Method *mPtr;
Class *mixinPtr;
- Tcl_Obj *keyPtr, *filterObj;
- int i;
+ CallContext *contextPtr;
+ Tcl_Obj *keyPtr, *filterObj, *variableObj, *args[3];
+ int i, result;
/*
- * Sanity checks.
+ * Sanity check.
*/
- if (targetName == NULL && oPtr->classPtr != NULL) {
- Tcl_AppendResult(interp, "must supply a name when copying a class",
- NULL);
- Tcl_SetErrorCode(interp, "TCL", "OO", "NO_COPY_TARGET", NULL);
- return NULL;
- }
- if (oPtr->flags & ROOT_CLASS) {
- Tcl_AppendResult(interp, "may not clone the class of classes", NULL);
+ if (IsRootClass(oPtr)) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "may not clone the class of classes", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "CLONING_CLASS", NULL);
return NULL;
}
@@ -1712,6 +1914,15 @@ Tcl_CopyObjectInstance(
}
/*
+ * Copy the object's variable resolution list to the new object.
+ */
+
+ DUPLICATE(o2Ptr->variables, oPtr->variables, Tcl_Obj *);
+ FOREACH(variableObj, o2Ptr->variables) {
+ Tcl_IncrRefCount(variableObj);
+ }
+
+ /*
* Copy the object's flags to the new object, clearing those that must be
* kept object-local. The duplicate is never deleted at this point, nor is
* it the root of the object system or in the midst of processing a filter
@@ -1719,7 +1930,7 @@ Tcl_CopyObjectInstance(
*/
o2Ptr->flags = oPtr->flags & ~(
- OBJECT_DELETED | ROOT_OBJECT | FILTER_HANDLING);
+ OBJECT_DELETED | ROOT_OBJECT | ROOT_CLASS | FILTER_HANDLING);
/*
* Copy the object's metadata.
@@ -1794,6 +2005,15 @@ Tcl_CopyObjectInstance(
}
/*
+ * Copy the source class's variable resolution list.
+ */
+
+ DUPLICATE(cls2Ptr->variables, clsPtr->variables, Tcl_Obj *);
+ FOREACH(variableObj, cls2Ptr->variables) {
+ Tcl_IncrRefCount(variableObj);
+ }
+
+ /*
* Duplicate the source class's mixins (which cannot be circular
* references to the duplicate).
*/
@@ -1861,6 +2081,31 @@ Tcl_CopyObjectInstance(
}
}
+ TclResetRewriteEnsemble(interp, 1);
+ contextPtr = TclOOGetCallContext(o2Ptr, oPtr->fPtr->clonedName, 0, NULL);
+ if (contextPtr) {
+ args[0] = TclOOObjectName(interp, o2Ptr);
+ args[1] = oPtr->fPtr->clonedName;
+ args[2] = TclOOObjectName(interp, oPtr);
+ Tcl_IncrRefCount(args[0]);
+ Tcl_IncrRefCount(args[1]);
+ Tcl_IncrRefCount(args[2]);
+ result = Tcl_NRCallObjProc(interp, TclOOInvokeContext, contextPtr, 3,
+ args);
+ TclDecrRefCount(args[0]);
+ TclDecrRefCount(args[1]);
+ TclDecrRefCount(args[2]);
+ TclOODeleteContext(contextPtr);
+ if (result == TCL_ERROR) {
+ Tcl_AddErrorInfo(interp,
+ "\n (while performing post-copy callback)");
+ }
+ if (result != TCL_OK) {
+ Tcl_DeleteCommandFromToken(interp, o2Ptr->command);
+ return NULL;
+ }
+ }
+
return (Tcl_Object) o2Ptr;
}
@@ -2236,9 +2481,15 @@ TclOOObjectCmdCore(
Tcl_Obj *methodNamePtr;
int result;
+ /*
+ * If we've no method name, throw this directly into the unknown
+ * processing.
+ */
+
if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "method ?arg ...?");
- return TCL_ERROR;
+ flags |= FORCE_UNKNOWN;
+ methodNamePtr = NULL;
+ goto noMapping;
}
/*
@@ -2253,7 +2504,7 @@ TclOOObjectCmdCore(
result = oPtr->mapMethodNameProc(interp, (Tcl_Object) oPtr,
(Tcl_Class *) startClsPtr, mappedMethodName);
if (result != TCL_OK) {
- Tcl_DecrRefCount(mappedMethodName);
+ TclDecrRefCount(mappedMethodName);
if (result == TCL_BREAK) {
goto noMapping;
} else if (result == TCL_ERROR) {
@@ -2269,11 +2520,11 @@ TclOOObjectCmdCore(
Tcl_IncrRefCount(mappedMethodName);
contextPtr = TclOOGetCallContext(oPtr, mappedMethodName,
flags | (oPtr->flags & FILTER_HANDLING), methodNamePtr);
- Tcl_DecrRefCount(mappedMethodName);
+ TclDecrRefCount(mappedMethodName);
if (contextPtr == NULL) {
- Tcl_AppendResult(interp, "impossible to invoke method \"",
- TclGetString(methodNamePtr),
- "\": no defined method or unknown method", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "impossible to invoke method \"%s\": no defined method or"
+ " unknown method", TclGetString(methodNamePtr)));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD_MAPPED",
TclGetString(methodNamePtr), NULL);
return TCL_ERROR;
@@ -2287,9 +2538,9 @@ TclOOObjectCmdCore(
contextPtr = TclOOGetCallContext(oPtr, methodNamePtr,
flags | (oPtr->flags & FILTER_HANDLING), NULL);
if (contextPtr == NULL) {
- Tcl_AppendResult(interp, "impossible to invoke method \"",
- TclGetString(methodNamePtr),
- "\": no defined method or unknown method", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "impossible to invoke method \"%s\": no defined method or"
+ " unknown method", TclGetString(methodNamePtr)));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(methodNamePtr), NULL);
return TCL_ERROR;
@@ -2315,8 +2566,8 @@ TclOOObjectCmdCore(
}
}
if (contextPtr->index >= contextPtr->callPtr->numChain) {
- Tcl_SetResult(interp, "no valid method implementation",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "no valid method implementation", -1));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(methodNamePtr), NULL);
TclOODeleteContext(contextPtr);
@@ -2397,8 +2648,8 @@ Tcl_ObjectContextInvokeNext(
methodType = "method";
}
- Tcl_AppendResult(interp, "no next ", methodType, " implementation",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "no next %s implementation", methodType));
Tcl_SetErrorCode(interp, "TCL", "OO", "NOTHING_NEXT", NULL);
return TCL_ERROR;
}
@@ -2466,8 +2717,8 @@ TclNRObjectContextInvokeNext(
methodType = "method";
}
- Tcl_AppendResult(interp, "no next ", methodType, " implementation",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "no next %s implementation", methodType));
Tcl_SetErrorCode(interp, "TCL", "OO", "NOTHING_NEXT", NULL);
return TCL_ERROR;
}
@@ -2544,8 +2795,8 @@ Tcl_GetObjectFromObj(
return cmdPtr->objClientData;
notAnObject:
- Tcl_AppendResult(interp, TclGetString(objPtr),
- " does not refer to an object", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "%s does not refer to an object", TclGetString(objPtr)));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "OBJECT", TclGetString(objPtr),
NULL);
return NULL;
@@ -2692,7 +2943,7 @@ int
Tcl_ObjectDeleted(
Tcl_Object object)
{
- return (((Object *)object)->flags & OBJECT_DELETED) ? 1 : 0;
+ return Deleted(object) ? 1 : 0;
}
Tcl_Object
diff --git a/generic/tclOO.decls b/generic/tclOO.decls
index 027dcd0..265ba88 100644
--- a/generic/tclOO.decls
+++ b/generic/tclOO.decls
@@ -1,12 +1,24 @@
+# tclOO.decls --
+#
+# This file contains the declarations for all supported public functions
+# that are exported by the TclOO package that is embedded within the Tcl
+# library via the stubs table. This file is used to generate the
+# tclOODecls.h, tclOOIntDecls.h and tclOOStubInit.c files.
+#
+# Copyright (c) 2008-2013 by Donal K. Fellows.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
library tclOO
######################################################################
-# public API
+# Public API, exposed for general users of TclOO.
#
interface tclOO
hooks tclOOInt
-scspec EXTERN
+scspec TCLAPI
declare 0 {
Tcl_Object Tcl_CopyObjectInstance(Tcl_Interp *interp,
@@ -116,7 +128,9 @@ declare 28 {
}
######################################################################
-# private API, exposed to support advanced OO systems that plug in on top
+# Private API, exposed to support advanced OO systems that plug in on top of
+# TclOO; not intended for general use and does not have any commitment to
+# long-term support.
#
interface tclOOInt
diff --git a/generic/tclOO.h b/generic/tclOO.h
index c791930..a6e8a22 100644
--- a/generic/tclOO.h
+++ b/generic/tclOO.h
@@ -4,7 +4,7 @@
* This file contains the public API definitions and some of the function
* declarations for the object-system (NB: not Tcl_Obj, but ::oo).
*
- * Copyright (c) 2006-2008 by Donal K. Fellows
+ * Copyright (c) 2006-2010 by Donal K. Fellows
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -12,7 +12,6 @@
#ifndef TCLOO_H_INCLUDED
#define TCLOO_H_INCLUDED
-#include "tcl.h"
/*
* Be careful when it comes to versioning; need to make sure that the
@@ -20,13 +19,32 @@
* version in the files:
*
* tests/oo.test
+ * tests/ooNext2.test
* unix/tclooConfig.sh
* win/tclooConfig.sh
*/
-#define TCLOO_VERSION "0.6.3"
+#define TCLOO_VERSION "1.0.1"
#define TCLOO_PATCHLEVEL TCLOO_VERSION
+#include "tcl.h"
+
+/*
+ * For C++ compilers, use extern "C"
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char *TclOOInitializeStubs(
+ Tcl_Interp *, const char *version);
+#define Tcl_OOInitStubs(interp) \
+ TclOOInitializeStubs((interp), TCLOO_VERSION)
+#ifndef USE_TCL_STUBS
+# define TclOOInitializeStubs(interp, version) (TCLOO_PATCHLEVEL)
+#endif
+
/*
* These are opaque types.
*/
@@ -115,6 +133,9 @@ typedef struct {
#include "tclOODecls.h"
+#ifdef __cplusplus
+}
+#endif
#endif
/*
diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c
index b286088..0b0516b 100644
--- a/generic/tclOOBasic.c
+++ b/generic/tclOOBasic.c
@@ -4,7 +4,7 @@
* This file contains implementations of the "simple" commands and
* methods from the object-system core.
*
- * Copyright (c) 2005-2011 by Donal K. Fellows
+ * Copyright (c) 2005-2013 by Donal K. Fellows
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -17,14 +17,11 @@
#include "tclOOInt.h"
static inline Tcl_Object *AddConstructionFinalizer(Tcl_Interp *interp);
-static int AfterNRDestructor(ClientData data[],
- Tcl_Interp *interp, int result);
-static int FinalizeConstruction(ClientData data[],
- Tcl_Interp *interp, int result);
-static int FinalizeEval(ClientData data[],
- Tcl_Interp *interp, int result);
-static int RestoreFrame(ClientData data[],
- Tcl_Interp *interp, int result);
+static Tcl_NRPostProc AfterNRDestructor;
+static Tcl_NRPostProc DecrRefsPostClassConstructor;
+static Tcl_NRPostProc FinalizeConstruction;
+static Tcl_NRPostProc FinalizeEval;
+static Tcl_NRPostProc NextRestoreFrame;
/*
* ----------------------------------------------------------------------
@@ -70,6 +67,78 @@ FinalizeConstruction(
/*
* ----------------------------------------------------------------------
*
+ * TclOO_Class_Constructor --
+ *
+ * Implementation for oo::class constructor.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOO_Class_Constructor(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tcl_ObjectContext context,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ Object *oPtr = (Object *) Tcl_ObjectContextObject(context);
+ Tcl_Obj **invoke;
+
+ if (objc-1 > Tcl_ObjectContextSkippedArgs(context)) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ "?definitionScript?");
+ return TCL_ERROR;
+ } else if (objc == Tcl_ObjectContextSkippedArgs(context)) {
+ return TCL_OK;
+ }
+
+ /*
+ * Delegate to [oo::define] to do the work.
+ */
+
+ invoke = ckalloc(3 * sizeof(Tcl_Obj *));
+ invoke[0] = oPtr->fPtr->defineName;
+ invoke[1] = TclOOObjectName(interp, oPtr);
+ invoke[2] = objv[objc-1];
+
+ /*
+ * Must add references or errors in configuration script will cause
+ * trouble.
+ */
+
+ Tcl_IncrRefCount(invoke[0]);
+ Tcl_IncrRefCount(invoke[1]);
+ Tcl_IncrRefCount(invoke[2]);
+ TclNRAddCallback(interp, DecrRefsPostClassConstructor,
+ invoke, NULL, NULL, NULL);
+
+ /*
+ * Tricky point: do not want the extra reported level in the Tcl stack
+ * trace, so use TCL_EVAL_NOERR.
+ */
+
+ return TclNREvalObjv(interp, 3, invoke, TCL_EVAL_NOERR, NULL);
+}
+
+static int
+DecrRefsPostClassConstructor(
+ ClientData data[],
+ Tcl_Interp *interp,
+ int result)
+{
+ Tcl_Obj **invoke = data[0];
+
+ TclDecrRefCount(invoke[0]);
+ TclDecrRefCount(invoke[1]);
+ TclDecrRefCount(invoke[2]);
+ ckfree(invoke);
+ return result;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
* TclOO_Class_Create --
*
* Implementation for oo::class->create method.
@@ -98,8 +167,8 @@ TclOO_Class_Create(
if (oPtr->classPtr == NULL) {
Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr);
- Tcl_AppendResult(interp, "object \"", TclGetString(cmdnameObj),
- "\" is not a class", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "object \"%s\" is not a class", TclGetString(cmdnameObj)));
Tcl_SetErrorCode(interp, "TCL", "OO", "INSTANTIATE_NONCLASS", NULL);
return TCL_ERROR;
}
@@ -116,7 +185,8 @@ TclOO_Class_Create(
objName = Tcl_GetStringFromObj(
objv[Tcl_ObjectContextSkippedArgs(context)], &len);
if (len == 0) {
- Tcl_AppendResult(interp, "object name must not be empty", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "object name must not be empty", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", NULL);
return TCL_ERROR;
}
@@ -162,8 +232,8 @@ TclOO_Class_CreateNs(
if (oPtr->classPtr == NULL) {
Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr);
- Tcl_AppendResult(interp, "object \"", TclGetString(cmdnameObj),
- "\" is not a class", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "object \"%s\" is not a class", TclGetString(cmdnameObj)));
Tcl_SetErrorCode(interp, "TCL", "OO", "INSTANTIATE_NONCLASS", NULL);
return TCL_ERROR;
}
@@ -180,14 +250,16 @@ TclOO_Class_CreateNs(
objName = Tcl_GetStringFromObj(
objv[Tcl_ObjectContextSkippedArgs(context)], &len);
if (len == 0) {
- Tcl_AppendResult(interp, "object name must not be empty", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "object name must not be empty", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", NULL);
return TCL_ERROR;
}
nsName = Tcl_GetStringFromObj(
objv[Tcl_ObjectContextSkippedArgs(context)+1], &len);
if (len == 0) {
- Tcl_AppendResult(interp, "namespace name must not be empty", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "namespace name must not be empty", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", NULL);
return TCL_ERROR;
}
@@ -231,8 +303,8 @@ TclOO_Class_New(
if (oPtr->classPtr == NULL) {
Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr);
- Tcl_AppendResult(interp, "object \"", TclGetString(cmdnameObj),
- "\" is not a class", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "object \"%s\" is not a class", TclGetString(cmdnameObj)));
Tcl_SetErrorCode(interp, "TCL", "OO", "INSTANTIATE_NONCLASS", NULL);
return TCL_ERROR;
}
@@ -281,6 +353,7 @@ TclOO_Object_Destroy(
contextPtr->skip = 0;
TclNRAddCallback(interp, AfterNRDestructor, contextPtr,
NULL, NULL, NULL);
+ TclPushTailcallPoint(interp);
return TclOOInvokeContext(contextPtr, interp, 0, NULL);
}
}
@@ -433,9 +506,16 @@ TclOO_Object_Unknown(
Object *oPtr = contextPtr->oPtr;
const char **methodNames;
int numMethodNames, i, skip = Tcl_ObjectContextSkippedArgs(context);
+ Tcl_Obj *errorMsg;
+
+ /*
+ * If no method name, generate an error asking for a method name. (Only by
+ * overriding *this* method can an object handle the absence of a method
+ * name without an error).
+ */
if (objc < skip+1) {
- Tcl_WrongNumArgs(interp, skip, objv, "methodName ?arg ...?");
+ Tcl_WrongNumArgs(interp, skip, objv, "method ?arg ...?");
return TCL_ERROR;
}
@@ -452,31 +532,34 @@ TclOO_Object_Unknown(
if (numMethodNames == 0) {
Tcl_Obj *tmpBuf = TclOOObjectName(interp, oPtr);
+ const char *piece;
- Tcl_AppendResult(interp, "object \"", TclGetString(tmpBuf), NULL);
if (contextPtr->callPtr->flags & PUBLIC_METHOD) {
- Tcl_AppendResult(interp, "\" has no visible methods", NULL);
+ piece = "visible methods";
} else {
- Tcl_AppendResult(interp, "\" has no methods", NULL);
+ piece = "methods";
}
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "object \"%s\" has no %s", TclGetString(tmpBuf), piece));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(objv[skip]), NULL);
return TCL_ERROR;
}
- Tcl_AppendResult(interp, "unknown method \"", TclGetString(objv[skip]),
- "\": must be ", NULL);
+ errorMsg = Tcl_ObjPrintf("unknown method \"%s\": must be ",
+ TclGetString(objv[skip]));
for (i=0 ; i<numMethodNames-1 ; i++) {
if (i) {
- Tcl_AppendResult(interp, ", ", NULL);
+ Tcl_AppendToObj(errorMsg, ", ", -1);
}
- Tcl_AppendResult(interp, methodNames[i], NULL);
+ Tcl_AppendToObj(errorMsg, methodNames[i], -1);
}
if (i) {
- Tcl_AppendResult(interp, " or ", NULL);
+ Tcl_AppendToObj(errorMsg, " or ", -1);
}
- Tcl_AppendResult(interp, methodNames[i], NULL);
+ Tcl_AppendToObj(errorMsg, methodNames[i], -1);
ckfree(methodNames);
+ Tcl_SetObjResult(interp, errorMsg);
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(objv[skip]), NULL);
return TCL_ERROR;
@@ -532,8 +615,9 @@ TclOO_Object_LinkVar(
*/
if (strstr(varName, "::") != NULL) {
- Tcl_AppendResult(interp, "variable name \"", varName,
- "\" illegal: must not contain namespace separator", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "variable name \"%s\" illegal: must not contain namespace"
+ " separator", varName));
Tcl_SetErrorCode(interp, "TCL", "UPVAR", "INVERTED", NULL);
return TCL_ERROR;
}
@@ -602,52 +686,51 @@ TclOO_Object_VarName(
int objc, /* Number of arguments. */
Tcl_Obj *const *objv) /* The actual arguments. */
{
- Interp *iPtr = (Interp *) interp;
Var *varPtr, *aryVar;
- Tcl_Obj *varNamePtr;
+ Tcl_Obj *varNamePtr, *argPtr;
+ const char *arg;
if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
"varName");
return TCL_ERROR;
}
+ argPtr = objv[objc-1];
+ arg = Tcl_GetString(argPtr);
/*
- * Switch to the object's namespace for the duration of this call. Like
- * this, the variable is looked up in the namespace of the object, and not
- * in the namespace of the caller. Otherwise this would only work if the
- * caller was a method of the object itself, which might not be true if
- * the method was exported. This is a bit of a hack, but the simplest way
- * to do this (pushing a stack frame would be horribly expensive by
- * comparison, and is only done when we'd otherwise interfere with the
- * global namespace).
+ * Convert the variable name to fully-qualified form if it wasn't already.
+ * This has to be done prior to lookup because we can run into problems
+ * with resolvers otherwise. [Bug 3603695]
+ *
+ * We still need to do the lookup; the variable could be linked to another
+ * variable and we want the target's name.
*/
- if (iPtr->varFramePtr == NULL) {
- Tcl_CallFrame *dummyFrame;
-
- TclPushStackFrame(interp, &dummyFrame,
- Tcl_GetObjectNamespace(Tcl_ObjectContextObject(context)),0);
- varPtr = TclObjLookupVar(interp, objv[objc-1], NULL,
- TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG, "refer to",1,1,&aryVar);
- TclPopStackFrame(interp);
+ if (arg[0] == ':' && arg[1] == ':') {
+ varNamePtr = argPtr;
} else {
- Namespace *savedNsPtr;
-
- savedNsPtr = iPtr->varFramePtr->nsPtr;
- iPtr->varFramePtr->nsPtr = (Namespace *)
+ Tcl_Namespace *namespacePtr =
Tcl_GetObjectNamespace(Tcl_ObjectContextObject(context));
- varPtr = TclObjLookupVar(interp, objv[objc-1], NULL,
- TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG, "refer to",1,1,&aryVar);
- iPtr->varFramePtr->nsPtr = savedNsPtr;
- }
+ varNamePtr = Tcl_NewStringObj(namespacePtr->fullName, -1);
+ Tcl_AppendToObj(varNamePtr, "::", 2);
+ Tcl_AppendObjToObj(varNamePtr, argPtr);
+ }
+ Tcl_IncrRefCount(varNamePtr);
+ varPtr = TclObjLookupVar(interp, varNamePtr, NULL,
+ TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG, "refer to", 1, 1, &aryVar);
+ Tcl_DecrRefCount(varNamePtr);
if (varPtr == NULL) {
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE",
- TclGetString(objv[objc-1]), NULL);
+ Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", arg, NULL);
return TCL_ERROR;
}
+ /*
+ * Now that we've pinned down what variable we're really talking about
+ * (including traversing variable links), convert back to a name.
+ */
+
varNamePtr = Tcl_NewObj();
if (aryVar != NULL) {
Tcl_HashEntry *hPtr;
@@ -707,8 +790,9 @@ TclOONextObjCmd(
*/
if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
- Tcl_AppendResult(interp, TclGetString(objv[0]),
- " may only be called from inside a method", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "%s may only be called from inside a method",
+ TclGetString(objv[0])));
Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
return TCL_ERROR;
}
@@ -719,7 +803,7 @@ TclOONextObjCmd(
* that this is like [uplevel 1] and not [eval].
*/
- TclNRAddCallback(interp, RestoreFrame, framePtr, NULL, NULL, NULL);
+ TclNRAddCallback(interp, NextRestoreFrame, framePtr, NULL,NULL,NULL);
iPtr->varFramePtr = framePtr->callerVarPtr;
return TclNRObjectContextInvokeNext(interp, context, objc, objv, 1);
}
@@ -737,6 +821,7 @@ TclOONextToObjCmd(
CallContext *contextPtr;
int i;
Tcl_Object object;
+ const char *methodType;
/*
* Start with sanity checks on the calling context to make sure that we
@@ -745,8 +830,9 @@ TclOONextToObjCmd(
*/
if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
- Tcl_AppendResult(interp, TclGetString(objv[0]),
- " may only be called from inside a method", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "%s may only be called from inside a method",
+ TclGetString(objv[0])));
Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
return TCL_ERROR;
}
@@ -766,8 +852,9 @@ TclOONextToObjCmd(
}
classPtr = ((Object *)object)->classPtr;
if (classPtr == NULL) {
- Tcl_AppendResult(interp, "\"", TclGetString(objv[1]),
- "\" is not a class", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" is not a class", TclGetString(objv[1])));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_REQUIRED", NULL);
return TCL_ERROR;
}
@@ -786,8 +873,8 @@ TclOONextToObjCmd(
* context. Note that this is like [uplevel 1] and not [eval].
*/
- TclNRAddCallback(interp, RestoreFrame, framePtr, contextPtr,
- INT2PTR(contextPtr->index), NULL);
+ TclNRAddCallback(interp, NextRestoreFrame, framePtr,
+ contextPtr, INT2PTR(contextPtr->index), NULL);
contextPtr->index = i-1;
iPtr->varFramePtr = framePtr->callerVarPtr;
return TclNRObjectContextInvokeNext(interp,
@@ -800,23 +887,35 @@ TclOONextToObjCmd(
* is on the chain but unreachable, or not on the chain at all.
*/
+ if (contextPtr->callPtr->flags & CONSTRUCTOR) {
+ methodType = "constructor";
+ } else if (contextPtr->callPtr->flags & DESTRUCTOR) {
+ methodType = "destructor";
+ } else {
+ methodType = "method";
+ }
+
for (i=contextPtr->index ; i>=0 ; i--) {
struct MInvoke *miPtr = contextPtr->callPtr->chain + i;
if (!miPtr->isFilter && miPtr->mPtr->declaringClassPtr == classPtr) {
- Tcl_AppendResult(interp, "method implementation by \"",
- TclGetString(objv[1]), "\" not reachable from here",
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "%s implementation by \"%s\" not reachable from here",
+ methodType, TclGetString(objv[1])));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_NOT_REACHABLE",
NULL);
return TCL_ERROR;
}
}
- Tcl_AppendResult(interp, "method has no non-filter implementation by \"",
- TclGetString(objv[1]), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "%s has no non-filter implementation by \"%s\"",
+ methodType, TclGetString(objv[1])));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_NOT_THERE", NULL);
return TCL_ERROR;
}
static int
-RestoreFrame(
+NextRestoreFrame(
ClientData data[],
Tcl_Interp *interp,
int result)
@@ -871,8 +970,9 @@ TclOOSelfObjCmd(
*/
if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
- Tcl_AppendResult(interp, TclGetString(objv[0]),
- " may only be called from inside a method", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "%s may only be called from inside a method",
+ TclGetString(objv[0])));
Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
return TCL_ERROR;
}
@@ -906,7 +1006,8 @@ TclOOSelfObjCmd(
Class *clsPtr = CurrentlyInvoked(contextPtr).mPtr->declaringClassPtr;
if (clsPtr == NULL) {
- Tcl_AppendResult(interp, "method not defined by a class", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "method not defined by a class", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", NULL);
return TCL_ERROR;
}
@@ -926,7 +1027,8 @@ TclOOSelfObjCmd(
return TCL_OK;
case SELF_FILTER:
if (!CurrentlyInvoked(contextPtr).isFilter) {
- Tcl_AppendResult(interp, "not inside a filtering context", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "not inside a filtering context", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", NULL);
return TCL_ERROR;
} else {
@@ -951,7 +1053,8 @@ TclOOSelfObjCmd(
case SELF_CALLER:
if ((framePtr->callerVarPtr == NULL) ||
!(framePtr->callerVarPtr->isProcCallFrame & FRAME_IS_METHOD)){
- Tcl_AppendResult(interp, "caller is not an object", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "caller is not an object", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
return TCL_ERROR;
} else {
@@ -968,7 +1071,8 @@ TclOOSelfObjCmd(
* This should be unreachable code.
*/
- Tcl_AppendResult(interp, "method without declarer!", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "method without declarer!", -1));
return TCL_ERROR;
}
@@ -999,7 +1103,8 @@ TclOOSelfObjCmd(
* This should be unreachable code.
*/
- Tcl_AppendResult(interp, "method without declarer!", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "method without declarer!", -1));
return TCL_ERROR;
}
@@ -1016,7 +1121,8 @@ TclOOSelfObjCmd(
return TCL_OK;
case SELF_TARGET:
if (!CurrentlyInvoked(contextPtr).isFilter) {
- Tcl_AppendResult(interp, "not inside a filtering context", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "not inside a filtering context", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", NULL);
return TCL_ERROR;
} else {
@@ -1042,7 +1148,8 @@ TclOOSelfObjCmd(
* This should be unreachable code.
*/
- Tcl_AppendResult(interp, "method without declarer!", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "method without declarer!", -1));
return TCL_ERROR;
}
result[0] = TclOOObjectName(interp, declarerPtr);
@@ -1113,7 +1220,7 @@ TclOOCopyObjectCmd(
Tcl_DStringAppend(&buffer,
iPtr->varFramePtr->nsPtr->fullName, -1);
}
- Tcl_DStringAppend(&buffer, "::", 2);
+ TclDStringAppendLiteral(&buffer, "::");
Tcl_DStringAppend(&buffer, name, -1);
name = Tcl_DStringValue(&buffer);
}
@@ -1134,74 +1241,6 @@ TclOOCopyObjectCmd(
}
/*
- * ----------------------------------------------------------------------
- *
- * TclOOUpcatchCmd --
- *
- * Implementation of the [oo::UpCatch] command, which is a combination of
- * [uplevel 1] and [catch] that makes it easier to write transparent
- * error handling in scripts.
- *
- * ----------------------------------------------------------------------
- */
-
-int
-TclOOUpcatchCmd(
- ClientData ignored,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *const objv[])
-{
- return Tcl_NRCallObjProc(interp, TclOONRUpcatch, NULL, objc, objv);
-}
-
-static int
-UpcatchCallback(
- ClientData data[],
- Tcl_Interp *interp,
- int result)
-{
- Interp *iPtr = (Interp *) interp;
- CallFrame *savedFramePtr = data[0];
- Tcl_Obj *resultObj[2];
- int rewind = iPtr->execEnvPtr->rewind;
-
- iPtr->varFramePtr = savedFramePtr;
- if (rewind || Tcl_LimitExceeded(interp)) {
- Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
- "\n (\"UpCatch\" body line %d)", Tcl_GetErrorLine(interp)));
- return TCL_ERROR;
- }
- resultObj[0] = Tcl_GetObjResult(interp);
- resultObj[1] = Tcl_GetReturnOptions(interp, result);
- Tcl_SetObjResult(interp, Tcl_NewListObj(2, resultObj));
- return TCL_OK;
-}
-
-int
-TclOONRUpcatch(
- ClientData ignored,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *const objv[])
-{
- Interp *iPtr = (Interp *) interp;
- CallFrame *savedFramePtr = iPtr->varFramePtr;
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "script");
- return TCL_ERROR;
- }
- if (iPtr->varFramePtr->callerVarPtr != NULL) {
- iPtr->varFramePtr = iPtr->varFramePtr->callerVarPtr;
- }
-
- Tcl_NRAddCallback(interp, UpcatchCallback, savedFramePtr, NULL,NULL,NULL);
- return TclNREvalObjEx(interp, objv[1], TCL_EVAL_NOERR,
- iPtr->cmdFramePtr, 1);
-}
-
-/*
* Local Variables:
* mode: c
* c-basic-offset: 4
diff --git a/generic/tclOOCall.c b/generic/tclOOCall.c
index 9c9f3c0..26fd09f 100644
--- a/generic/tclOOCall.c
+++ b/generic/tclOOCall.c
@@ -4,7 +4,7 @@
* This file contains the method call chain management code for the
* object-system core.
*
- * Copyright (c) 2005-2011 by Donal K. Fellows
+ * Copyright (c) 2005-2012 by Donal K. Fellows
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -37,7 +37,7 @@ struct ChainBuilder {
#define DEFINITE_PROTECTED 0x100000
#define DEFINITE_PUBLIC 0x200000
#define KNOWN_STATE (DEFINITE_PROTECTED | DEFINITE_PUBLIC)
-#define SPECIAL (CONSTRUCTOR | DESTRUCTOR)
+#define SPECIAL (CONSTRUCTOR | DESTRUCTOR | FORCE_UNKNOWN)
/*
* Function declarations for things defined in this file.
@@ -178,7 +178,7 @@ StashCallChain(
callPtr->refCount++;
TclFreeIntRep(objPtr);
objPtr->typePtr = &methodNameType;
- objPtr->internalRep.otherValuePtr = callPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = callPtr;
}
void
@@ -205,10 +205,10 @@ DupMethodNameRep(
Tcl_Obj *srcPtr,
Tcl_Obj *dstPtr)
{
- register CallChain *callPtr = srcPtr->internalRep.otherValuePtr;
+ register CallChain *callPtr = srcPtr->internalRep.twoPtrValue.ptr1;
dstPtr->typePtr = &methodNameType;
- dstPtr->internalRep.otherValuePtr = callPtr;
+ dstPtr->internalRep.twoPtrValue.ptr1 = callPtr;
callPtr->refCount++;
}
@@ -216,10 +216,9 @@ static void
FreeMethodNameRep(
Tcl_Obj *objPtr)
{
- register CallChain *callPtr = objPtr->internalRep.otherValuePtr;
+ register CallChain *callPtr = objPtr->internalRep.twoPtrValue.ptr1;
TclOODeleteChain(callPtr);
- objPtr->internalRep.otherValuePtr = NULL;
objPtr->typePtr = NULL;
}
@@ -952,7 +951,7 @@ TclOOGetCallContext(
const int reuseMask = ((flags & PUBLIC_METHOD) ? ~0 : ~PUBLIC_METHOD);
if (cacheInThisObj->typePtr == &methodNameType) {
- callPtr = cacheInThisObj->internalRep.otherValuePtr;
+ callPtr = cacheInThisObj->internalRep.twoPtrValue.ptr1;
if (IsStillValid(callPtr, oPtr, flags, reuseMask)) {
callPtr->refCount++;
goto returnContext;
@@ -997,6 +996,22 @@ TclOOGetCallContext(
cb.oPtr = oPtr;
/*
+ * If we're working with a forced use of unknown, do that now.
+ */
+
+ if (flags & FORCE_UNKNOWN) {
+ AddSimpleChainToCallContext(oPtr, oPtr->fPtr->unknownMethodNameObj,
+ &cb, NULL, 0, NULL);
+ callPtr->flags |= OO_UNKNOWN_METHOD;
+ callPtr->epoch = -1;
+ if (callPtr->numChain == 0) {
+ TclOODeleteChain(callPtr);
+ return NULL;
+ }
+ goto returnContext;
+ }
+
+ /*
* Add all defined filters (if any, and if we're going to be processing
* them; they're not processed for constructors, destructors or when we're
* in the middle of processing a filter).
diff --git a/generic/tclOODecls.h b/generic/tclOODecls.h
index 80a10bb..9fd62ec 100644
--- a/generic/tclOODecls.h
+++ b/generic/tclOODecls.h
@@ -5,133 +5,125 @@
#ifndef _TCLOODECLS
#define _TCLOODECLS
-#undef TCL_STORAGE_CLASS
-#ifdef BUILD_tcl
-# define TCL_STORAGE_CLASS DLLEXPORT
-#else
-# ifdef USE_TCL_STUBS
-# define TCL_STORAGE_CLASS
+#ifndef TCLAPI
+# ifdef BUILD_tcl
+# define TCLAPI extern DLLEXPORT
# else
-# define TCL_STORAGE_CLASS DLLIMPORT
+# define TCLAPI extern DLLIMPORT
# endif
#endif
-/*
- * WARNING: This file is automatically generated by the tools/genStubs.tcl
- * script. Any modifications to the function declarations below should be made
- * in the generic/tclOO.decls script.
- */
-
-#if defined(USE_TCL_STUBS)
-extern const char *TclOOInitializeStubs(Tcl_Interp *, const char *version);
-#define Tcl_OOInitStubs(interp) TclOOInitializeStubs((interp),TCLOO_VERSION)
-#else
-#define Tcl_OOInitStubs(interp) \
- Tcl_PkgRequire((interp),"TclOO",TCLOO_VERSION,0)
+#ifdef USE_TCL_STUBS
+# undef USE_TCLOO_STUBS
+# define USE_TCLOO_STUBS
#endif
-
+
/* !BEGIN!: Do not edit below this line. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Exported function declarations:
*/
/* 0 */
-EXTERN Tcl_Object Tcl_CopyObjectInstance(Tcl_Interp *interp,
+TCLAPI Tcl_Object Tcl_CopyObjectInstance(Tcl_Interp *interp,
Tcl_Object sourceObject,
const char *targetName,
const char *targetNamespaceName);
/* 1 */
-EXTERN Tcl_Object Tcl_GetClassAsObject(Tcl_Class clazz);
+TCLAPI Tcl_Object Tcl_GetClassAsObject(Tcl_Class clazz);
/* 2 */
-EXTERN Tcl_Class Tcl_GetObjectAsClass(Tcl_Object object);
+TCLAPI Tcl_Class Tcl_GetObjectAsClass(Tcl_Object object);
/* 3 */
-EXTERN Tcl_Command Tcl_GetObjectCommand(Tcl_Object object);
+TCLAPI Tcl_Command Tcl_GetObjectCommand(Tcl_Object object);
/* 4 */
-EXTERN Tcl_Object Tcl_GetObjectFromObj(Tcl_Interp *interp,
+TCLAPI Tcl_Object Tcl_GetObjectFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr);
/* 5 */
-EXTERN Tcl_Namespace * Tcl_GetObjectNamespace(Tcl_Object object);
+TCLAPI Tcl_Namespace * Tcl_GetObjectNamespace(Tcl_Object object);
/* 6 */
-EXTERN Tcl_Class Tcl_MethodDeclarerClass(Tcl_Method method);
+TCLAPI Tcl_Class Tcl_MethodDeclarerClass(Tcl_Method method);
/* 7 */
-EXTERN Tcl_Object Tcl_MethodDeclarerObject(Tcl_Method method);
+TCLAPI Tcl_Object Tcl_MethodDeclarerObject(Tcl_Method method);
/* 8 */
-EXTERN int Tcl_MethodIsPublic(Tcl_Method method);
+TCLAPI int Tcl_MethodIsPublic(Tcl_Method method);
/* 9 */
-EXTERN int Tcl_MethodIsType(Tcl_Method method,
+TCLAPI int Tcl_MethodIsType(Tcl_Method method,
const Tcl_MethodType *typePtr,
ClientData *clientDataPtr);
/* 10 */
-EXTERN Tcl_Obj * Tcl_MethodName(Tcl_Method method);
+TCLAPI Tcl_Obj * Tcl_MethodName(Tcl_Method method);
/* 11 */
-EXTERN Tcl_Method Tcl_NewInstanceMethod(Tcl_Interp *interp,
+TCLAPI Tcl_Method Tcl_NewInstanceMethod(Tcl_Interp *interp,
Tcl_Object object, Tcl_Obj *nameObj,
int isPublic, const Tcl_MethodType *typePtr,
ClientData clientData);
/* 12 */
-EXTERN Tcl_Method Tcl_NewMethod(Tcl_Interp *interp, Tcl_Class cls,
+TCLAPI Tcl_Method Tcl_NewMethod(Tcl_Interp *interp, Tcl_Class cls,
Tcl_Obj *nameObj, int isPublic,
const Tcl_MethodType *typePtr,
ClientData clientData);
/* 13 */
-EXTERN Tcl_Object Tcl_NewObjectInstance(Tcl_Interp *interp,
+TCLAPI Tcl_Object Tcl_NewObjectInstance(Tcl_Interp *interp,
Tcl_Class cls, const char *nameStr,
const char *nsNameStr, int objc,
Tcl_Obj *const *objv, int skip);
/* 14 */
-EXTERN int Tcl_ObjectDeleted(Tcl_Object object);
+TCLAPI int Tcl_ObjectDeleted(Tcl_Object object);
/* 15 */
-EXTERN int Tcl_ObjectContextIsFiltering(
+TCLAPI int Tcl_ObjectContextIsFiltering(
Tcl_ObjectContext context);
/* 16 */
-EXTERN Tcl_Method Tcl_ObjectContextMethod(Tcl_ObjectContext context);
+TCLAPI Tcl_Method Tcl_ObjectContextMethod(Tcl_ObjectContext context);
/* 17 */
-EXTERN Tcl_Object Tcl_ObjectContextObject(Tcl_ObjectContext context);
+TCLAPI Tcl_Object Tcl_ObjectContextObject(Tcl_ObjectContext context);
/* 18 */
-EXTERN int Tcl_ObjectContextSkippedArgs(
+TCLAPI int Tcl_ObjectContextSkippedArgs(
Tcl_ObjectContext context);
/* 19 */
-EXTERN ClientData Tcl_ClassGetMetadata(Tcl_Class clazz,
+TCLAPI ClientData Tcl_ClassGetMetadata(Tcl_Class clazz,
const Tcl_ObjectMetadataType *typePtr);
/* 20 */
-EXTERN void Tcl_ClassSetMetadata(Tcl_Class clazz,
+TCLAPI void Tcl_ClassSetMetadata(Tcl_Class clazz,
const Tcl_ObjectMetadataType *typePtr,
ClientData metadata);
/* 21 */
-EXTERN ClientData Tcl_ObjectGetMetadata(Tcl_Object object,
+TCLAPI ClientData Tcl_ObjectGetMetadata(Tcl_Object object,
const Tcl_ObjectMetadataType *typePtr);
/* 22 */
-EXTERN void Tcl_ObjectSetMetadata(Tcl_Object object,
+TCLAPI void Tcl_ObjectSetMetadata(Tcl_Object object,
const Tcl_ObjectMetadataType *typePtr,
ClientData metadata);
/* 23 */
-EXTERN int Tcl_ObjectContextInvokeNext(Tcl_Interp *interp,
+TCLAPI int Tcl_ObjectContextInvokeNext(Tcl_Interp *interp,
Tcl_ObjectContext context, int objc,
Tcl_Obj *const *objv, int skip);
/* 24 */
-EXTERN Tcl_ObjectMapMethodNameProc * Tcl_ObjectGetMethodNameMapper(
+TCLAPI Tcl_ObjectMapMethodNameProc * Tcl_ObjectGetMethodNameMapper(
Tcl_Object object);
/* 25 */
-EXTERN void Tcl_ObjectSetMethodNameMapper(Tcl_Object object,
+TCLAPI void Tcl_ObjectSetMethodNameMapper(Tcl_Object object,
Tcl_ObjectMapMethodNameProc *mapMethodNameProc);
/* 26 */
-EXTERN void Tcl_ClassSetConstructor(Tcl_Interp *interp,
+TCLAPI void Tcl_ClassSetConstructor(Tcl_Interp *interp,
Tcl_Class clazz, Tcl_Method method);
/* 27 */
-EXTERN void Tcl_ClassSetDestructor(Tcl_Interp *interp,
+TCLAPI void Tcl_ClassSetDestructor(Tcl_Interp *interp,
Tcl_Class clazz, Tcl_Method method);
/* 28 */
-EXTERN Tcl_Obj * Tcl_GetObjectName(Tcl_Interp *interp,
+TCLAPI Tcl_Obj * Tcl_GetObjectName(Tcl_Interp *interp,
Tcl_Object object);
-typedef struct TclOOStubHooks {
+typedef struct {
const struct TclOOIntStubs *tclOOIntStubs;
} TclOOStubHooks;
typedef struct TclOOStubs {
int magic;
- const struct TclOOStubHooks *hooks;
+ const TclOOStubHooks *hooks;
Tcl_Object (*tcl_CopyObjectInstance) (Tcl_Interp *interp, Tcl_Object sourceObject, const char *targetName, const char *targetNamespaceName); /* 0 */
Tcl_Object (*tcl_GetClassAsObject) (Tcl_Class clazz); /* 1 */
@@ -164,10 +156,8 @@ typedef struct TclOOStubs {
Tcl_Obj * (*tcl_GetObjectName) (Tcl_Interp *interp, Tcl_Object object); /* 28 */
} TclOOStubs;
-#ifdef __cplusplus
-extern "C" {
-#endif
extern const TclOOStubs *tclOOStubsPtr;
+
#ifdef __cplusplus
}
#endif
@@ -240,8 +230,5 @@ extern const TclOOStubs *tclOOStubsPtr;
#endif /* defined(USE_TCLOO_STUBS) */
/* !END!: Do not edit above this line. */
-
-#undef TCL_STORAGE_CLASS
-#define TCL_STORAGE_CLASS DLLIMPORT
#endif /* _TCLOODECLS */
diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c
index 72732da..5a6c0ad 100644
--- a/generic/tclOODefineCmds.c
+++ b/generic/tclOODefineCmds.c
@@ -4,7 +4,7 @@
* This file contains the implementation of the ::oo::define command,
* part of the object-system core (NB: not Tcl_Obj, but ::oo).
*
- * Copyright (c) 2006-2008 by Donal K. Fellows
+ * Copyright (c) 2006-2013 by Donal K. Fellows
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -17,12 +17,38 @@
#include "tclOOInt.h"
/*
+ * The maximum length of fully-qualified object name to use in an errorinfo
+ * message. Longer than this will be curtailed.
+ */
+
+#define OBJNAME_LENGTH_IN_ERRORINFO_LIMIT 30
+
+/*
+ * Some things that make it easier to declare a slot.
+ */
+
+struct DeclaredSlot {
+ const char *name;
+ const Tcl_MethodType getterType;
+ const Tcl_MethodType setterType;
+};
+
+#define SLOT(name,getter,setter) \
+ {"::oo::" name, \
+ {TCL_OO_METHOD_VERSION_CURRENT, "core method: " name " Getter", \
+ getter, NULL, NULL}, \
+ {TCL_OO_METHOD_VERSION_CURRENT, "core method: " name " Setter", \
+ setter, NULL, NULL}}
+
+/*
* Forward declarations.
*/
static inline void BumpGlobalEpoch(Tcl_Interp *interp, Class *classPtr);
static Tcl_Command FindCommand(Tcl_Interp *interp, Tcl_Obj *stringObj,
Tcl_Namespace *const namespacePtr);
+static void GenerateErrorInfo(Tcl_Interp *interp, Object *oPtr,
+ Tcl_Obj *savedNameObj, const char *typeOfSubject);
static inline Class * GetClassInOuterContext(Tcl_Interp *interp,
Tcl_Obj *className, const char *errMsg);
static inline int InitDefineContext(Tcl_Interp *interp,
@@ -32,6 +58,63 @@ static inline void RecomputeClassCacheFlag(Object *oPtr);
static int RenameDeleteMethod(Tcl_Interp *interp, Object *oPtr,
int useClass, Tcl_Obj *const fromPtr,
Tcl_Obj *const toPtr);
+static int ClassFilterGet(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
+static int ClassFilterSet(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
+static int ClassMixinGet(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
+static int ClassMixinSet(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
+static int ClassSuperGet(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
+static int ClassSuperSet(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
+static int ClassVarsGet(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
+static int ClassVarsSet(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
+static int ObjFilterGet(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
+static int ObjFilterSet(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
+static int ObjMixinGet(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
+static int ObjMixinSet(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
+static int ObjVarsGet(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
+static int ObjVarsSet(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
+
+/*
+ * Now define the slots used in declarations.
+ */
+
+static const struct DeclaredSlot slots[] = {
+ SLOT("define::filter", ClassFilterGet, ClassFilterSet),
+ SLOT("define::mixin", ClassMixinGet, ClassMixinSet),
+ SLOT("define::superclass", ClassSuperGet, ClassSuperSet),
+ SLOT("define::variable", ClassVarsGet, ClassVarsSet),
+ SLOT("objdefine::filter", ObjFilterGet, ObjFilterSet),
+ SLOT("objdefine::mixin", ObjMixinGet, ObjMixinSet),
+ SLOT("objdefine::variable", ObjVarsGet, ObjVarsSet),
+ {NULL, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}}
+};
/*
* ----------------------------------------------------------------------
@@ -340,8 +423,8 @@ RenameDeleteMethod(
if (!useClass) {
if (!oPtr->methodsPtr) {
noSuchMethod:
- Tcl_AppendResult(interp, "method ", TclGetString(fromPtr),
- " does not exist", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "method %s does not exist", TclGetString(fromPtr)));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(fromPtr), NULL);
return TCL_ERROR;
@@ -355,14 +438,15 @@ RenameDeleteMethod(
&isNew);
if (hPtr == newHPtr) {
renameToSelf:
- Tcl_AppendResult(interp, "cannot rename method to itself",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "cannot rename method to itself", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "RENAME_TO_SELF", NULL);
return TCL_ERROR;
} else if (!isNew) {
renameToExisting:
- Tcl_AppendResult(interp, "method called ",
- TclGetString(toPtr), " already exists", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "method called %s already exists",
+ TclGetString(toPtr)));
Tcl_SetErrorCode(interp, "TCL", "OO", "RENAME_OVER", NULL);
return TCL_ERROR;
}
@@ -430,7 +514,8 @@ TclOOUnknownDefinition(
const char *soughtStr, *matchedStr = NULL;
if (objc < 2) {
- Tcl_AppendResult(interp, "bad call of unknown handler", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "bad call of unknown handler", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_UNKNOWN", NULL);
return TCL_ERROR;
}
@@ -475,7 +560,8 @@ TclOOUnknownDefinition(
}
noMatch:
- Tcl_AppendResult(interp, "invalid command name \"",soughtStr,"\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid command name \"%s\"", soughtStr));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", soughtStr, NULL);
return TCL_ERROR;
}
@@ -563,9 +649,9 @@ InitDefineContext(
int result;
if (namespacePtr == NULL) {
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"cannot process definitions; support namespace deleted",
- NULL);
+ -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return TCL_ERROR;
}
@@ -599,16 +685,25 @@ TclOOGetDefineCmdContext(
Tcl_Interp *interp)
{
Interp *iPtr = (Interp *) interp;
+ Tcl_Object object;
if ((iPtr->varFramePtr == NULL)
|| (iPtr->varFramePtr->isProcCallFrame != FRAME_IS_OO_DEFINE)) {
- Tcl_AppendResult(interp, "this command may only be called from within"
- " the context of an ::oo::define or ::oo::objdefine command",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "this command may only be called from within the context of"
+ " an ::oo::define or ::oo::objdefine command", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+ return NULL;
+ }
+ object = iPtr->varFramePtr->clientData;
+ if (Tcl_ObjectDeleted(object)) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "this command cannot be called when the object has been"
+ " deleted", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return NULL;
}
- return (Tcl_Object) iPtr->varFramePtr->clientData;
+ return object;
}
/*
@@ -645,7 +740,7 @@ GetClassInOuterContext(
return NULL;
}
if (oPtr->classPtr == NULL) {
- Tcl_AppendResult(interp, errMsg, NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, -1));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
TclGetString(className), NULL);
return NULL;
@@ -656,6 +751,44 @@ GetClassInOuterContext(
/*
* ----------------------------------------------------------------------
*
+ * GenerateErrorInfo --
+ * Factored out code to generate part of the error trace messages.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+GenerateErrorInfo(
+ Tcl_Interp *interp, /* Where to store the error info trace. */
+ Object *oPtr, /* What object (or class) was being configured
+ * when the error occurred? */
+ Tcl_Obj *savedNameObj, /* Name of object saved from before script was
+ * evaluated, which is needed if the object
+ * goes away part way through execution. OTOH,
+ * if the object isn't deleted then its
+ * current name (post-execution) has to be
+ * used. This matters, because the object
+ * could have been renamed... */
+ const char *typeOfSubject) /* Part of the message, saying whether it was
+ * an object, class or class-as-object that
+ * was being configured. */
+{
+ int length;
+ Tcl_Obj *realNameObj = Tcl_ObjectDeleted((Tcl_Object) oPtr)
+ ? savedNameObj : TclOOObjectName(interp, oPtr);
+ const char *objName = Tcl_GetStringFromObj(realNameObj, &length);
+ int limit = OBJNAME_LENGTH_IN_ERRORINFO_LIMIT;
+ int overflow = (length > limit);
+
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (in definition script for %s \"%.*s%s\" line %d)",
+ typeOfSubject, (overflow ? limit : length), objName,
+ (overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
* TclOODefineObjCmd --
* Implementation of the "oo::define" command. Works by effectively doing
* the same as 'namespace eval', but with extra magic applied so that the
@@ -687,8 +820,8 @@ TclOODefineObjCmd(
return TCL_ERROR;
}
if (oPtr->classPtr == NULL) {
- Tcl_AppendResult(interp, TclGetString(objv[1]),
- " does not refer to a class", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "%s does not refer to a class",TclGetString(objv[1])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
TclGetString(objv[1]), NULL);
return TCL_ERROR;
@@ -705,20 +838,15 @@ TclOODefineObjCmd(
AddRef(oPtr);
if (objc == 3) {
+ Tcl_Obj *objNameObj = TclOOObjectName(interp, oPtr);
+
+ Tcl_IncrRefCount(objNameObj);
result = TclEvalObjEx(interp, objv[2], 0,
((Interp *)interp)->cmdFramePtr, 2);
-
if (result == TCL_ERROR) {
- int length;
- const char *objName = Tcl_GetStringFromObj(objv[1], &length);
- int limit = 60;
- int overflow = (length > limit);
-
- Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
- "\n (in definition script for object \"%.*s%s\" line %d)",
- (overflow ? limit : length), objName,
- (overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
+ GenerateErrorInfo(interp, oPtr, objNameObj, "class");
}
+ TclDecrRefCount(objNameObj);
} else {
Tcl_Obj *objPtr, *obj2Ptr, **objs;
Interp *iPtr = (Interp *) interp;
@@ -824,20 +952,15 @@ TclOOObjDefObjCmd(
AddRef(oPtr);
if (objc == 3) {
+ Tcl_Obj *objNameObj = TclOOObjectName(interp, oPtr);
+
+ Tcl_IncrRefCount(objNameObj);
result = TclEvalObjEx(interp, objv[2], 0,
((Interp *)interp)->cmdFramePtr, 2);
-
if (result == TCL_ERROR) {
- int length;
- const char *objName = Tcl_GetStringFromObj(objv[1], &length);
- int limit = 60;
- int overflow = (length > limit);
-
- Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
- "\n (in definition script for object \"%.*s%s\" line %d)",
- (overflow ? limit : length), objName,
- (overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
+ GenerateErrorInfo(interp, oPtr, objNameObj, "object");
}
+ TclDecrRefCount(objNameObj);
} else {
Tcl_Obj *objPtr, *obj2Ptr, **objs;
Interp *iPtr = (Interp *) interp;
@@ -943,21 +1066,15 @@ TclOODefineSelfObjCmd(
AddRef(oPtr);
if (objc == 2) {
+ Tcl_Obj *objNameObj = TclOOObjectName(interp, oPtr);
+
+ Tcl_IncrRefCount(objNameObj);
result = TclEvalObjEx(interp, objv[1], 0,
((Interp *)interp)->cmdFramePtr, 2);
-
if (result == TCL_ERROR) {
- int length;
- const char *objName = Tcl_GetStringFromObj(
- TclOOObjectName(interp, oPtr), &length);
- int limit = 60;
- int overflow = (length > limit);
-
- Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
- "\n (in definition script for object \"%.*s%s\" line %d)",
- (overflow ? limit : length), objName,
- (overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
+ GenerateErrorInfo(interp, oPtr, objNameObj, "class object");
}
+ TclDecrRefCount(objNameObj);
} else {
Tcl_Obj *objPtr, *obj2Ptr, **objs;
Interp *iPtr = (Interp *) interp;
@@ -1048,14 +1165,14 @@ TclOODefineClassObjCmd(
return TCL_ERROR;
}
if (oPtr->flags & ROOT_OBJECT) {
- Tcl_AppendResult(interp,
- "may not modify the class of the root object class", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "may not modify the class of the root object class", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return TCL_ERROR;
}
if (oPtr->flags & ROOT_CLASS) {
- Tcl_AppendResult(interp,
- "may not modify the class of the class of classes", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "may not modify the class of the class of classes", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return TCL_ERROR;
}
@@ -1081,9 +1198,10 @@ TclOODefineClassObjCmd(
*/
if ((oPtr->classPtr==NULL) == TclOOIsReachable(fPtr->classCls, clsPtr)) {
- Tcl_AppendResult(interp, "may not change a ",
- (oPtr->classPtr==NULL ? "non-" : ""), "class object into a ",
- (oPtr->classPtr==NULL ? "" : "non-"), "class object", NULL);
+ 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);
return TCL_ERROR;
}
@@ -1204,7 +1322,8 @@ TclOODefineDeleteMethodObjCmd(
return TCL_ERROR;
}
if (!isInstanceDeleteMethod && !oPtr->classPtr) {
- Tcl_AppendResult(interp, "attempt to misuse API", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return TCL_ERROR;
}
@@ -1327,7 +1446,8 @@ TclOODefineExportObjCmd(
}
clsPtr = oPtr->classPtr;
if (!isInstanceExport && !clsPtr) {
- Tcl_AppendResult(interp, "attempt to misuse API", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return TCL_ERROR;
}
@@ -1388,43 +1508,6 @@ TclOODefineExportObjCmd(
/*
* ----------------------------------------------------------------------
*
- * TclOODefineFilterObjCmd --
- * Implementation of the "filter" subcommand of the "oo::define" and
- * "oo::objdefine" commands.
- *
- * ----------------------------------------------------------------------
- */
-
-int
-TclOODefineFilterObjCmd(
- ClientData clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *const *objv)
-{
- int isInstanceFilter = (clientData != NULL);
- Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
-
- if (oPtr == NULL) {
- return TCL_ERROR;
- }
- if (!isInstanceFilter && !oPtr->classPtr) {
- Tcl_AppendResult(interp, "attempt to misuse API", NULL);
- Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
- return TCL_ERROR;
- }
-
- if (!isInstanceFilter) {
- TclOOClassSetFilters(interp, oPtr->classPtr, objc-1, objv+1);
- } else {
- TclOOObjectSetFilters(oPtr, objc-1, objv+1);
- }
- return TCL_OK;
-}
-
-/*
- * ----------------------------------------------------------------------
- *
* TclOODefineForwardObjCmd --
* Implementation of the "forward" subcommand of the "oo::define" and
* "oo::objdefine" commands.
@@ -1455,7 +1538,8 @@ TclOODefineForwardObjCmd(
return TCL_ERROR;
}
if (!isInstanceForward && !oPtr->classPtr) {
- Tcl_AppendResult(interp, "attempt to misuse API", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return TCL_ERROR;
}
@@ -1512,7 +1596,8 @@ TclOODefineMethodObjCmd(
return TCL_ERROR;
}
if (!isInstanceMethod && !oPtr->classPtr) {
- Tcl_AppendResult(interp, "attempt to misuse API", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return TCL_ERROR;
}
@@ -1563,7 +1648,8 @@ TclOODefineMixinObjCmd(
return TCL_ERROR;
}
if (!isInstanceMixin && !oPtr->classPtr) {
- Tcl_AppendResult(interp, "attempt to misuse API", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return TCL_ERROR;
}
@@ -1577,7 +1663,8 @@ TclOODefineMixinObjCmd(
goto freeAndError;
}
if (!isInstanceMixin && TclOOIsReachable(oPtr->classPtr, clsPtr)) {
- Tcl_AppendResult(interp, "may not mix a class into itself", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "may not mix a class into itself", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", NULL);
goto freeAndError;
}
@@ -1628,7 +1715,8 @@ TclOODefineRenameMethodObjCmd(
return TCL_ERROR;
}
if (!isInstanceRenameMethod && !oPtr->classPtr) {
- Tcl_AppendResult(interp, "attempt to misuse API", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return TCL_ERROR;
}
@@ -1656,112 +1744,6 @@ TclOODefineRenameMethodObjCmd(
/*
* ----------------------------------------------------------------------
*
- * TclOODefineSuperclassObjCmd --
- * Implementation of the "superclass" subcommand of the "oo::define"
- * command.
- *
- * ----------------------------------------------------------------------
- */
-
-int
-TclOODefineSuperclassObjCmd(
- ClientData clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *const *objv)
-{
- Object *oPtr;
- Class **superclasses, *superPtr;
- int i, j;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "className ?className ...?");
- return TCL_ERROR;
- }
-
- /*
- * Get the class to operate on.
- */
-
- oPtr = (Object *) TclOOGetDefineCmdContext(interp);
- if (oPtr == NULL) {
- return TCL_ERROR;
- }
- if (oPtr->classPtr == NULL) {
- Tcl_AppendResult(interp, "only classes may have superclasses defined",
- NULL);
- Tcl_SetErrorCode(interp, "TCL", "OO", "OBJECT_NOT_CLASS", NULL);
- return TCL_ERROR;
- }
- if (oPtr->flags & ROOT_OBJECT) {
- Tcl_AppendResult(interp,
- "may not modify the superclass of the root object", NULL);
- Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
- return TCL_ERROR;
- }
-
- /*
- * Allocate some working space.
- */
-
- superclasses = ckalloc(sizeof(Class *) * (objc-1));
-
- /*
- * Parse the arguments to get the class to use as superclasses.
- */
-
- for (i=0 ; i<objc-1 ; i++) {
- Class *clsPtr = GetClassInOuterContext(interp, objv[i+1],
- "only a class can be a superclass");
-
- if (clsPtr == NULL) {
- goto failedAfterAlloc;
- }
- for (j=0 ; j<i ; j++) {
- if (superclasses[j] == clsPtr) {
- Tcl_AppendResult(interp,
- "class should only be a direct superclass once",NULL);
- Tcl_SetErrorCode(interp, "TCL", "OO", "REPETITIOUS", NULL);
- goto failedAfterAlloc;
- }
- }
- if (TclOOIsReachable(oPtr->classPtr, clsPtr)) {
- Tcl_AppendResult(interp,
- "attempt to form circular dependency graph", NULL);
- Tcl_SetErrorCode(interp, "TCL", "OO", "CIRCULARITY", NULL);
- failedAfterAlloc:
- ckfree(superclasses);
- return TCL_ERROR;
- }
- superclasses[i] = clsPtr;
- }
-
- /*
- * Install the list of superclasses into the class. Note that this also
- * involves splicing the class out of the superclasses' subclass list that
- * it used to be a member of and splicing it into the new superclasses'
- * subclass list.
- */
-
- if (oPtr->classPtr->superclasses.num != 0) {
- FOREACH(superPtr, oPtr->classPtr->superclasses) {
- TclOORemoveFromSubclasses(oPtr->classPtr, superPtr);
- }
- ckfree(oPtr->classPtr->superclasses.list);
- }
- oPtr->classPtr->superclasses.list = superclasses;
- oPtr->classPtr->superclasses.num = objc-1;
- FOREACH(superPtr, oPtr->classPtr->superclasses) {
- TclOOAddToSubclasses(oPtr->classPtr, superPtr);
- }
- BumpGlobalEpoch(interp, oPtr->classPtr);
-
- return TCL_OK;
-}
-
-/*
- * ----------------------------------------------------------------------
- *
* TclOODefineUnexportObjCmd --
* Implementation of the "unexport" subcommand of the "oo::define" and
* "oo::objdefine" commands.
@@ -1794,7 +1776,8 @@ TclOODefineUnexportObjCmd(
}
clsPtr = oPtr->classPtr;
if (!isInstanceUnexport && !clsPtr) {
- Tcl_AppendResult(interp, "attempt to misuse API", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return TCL_ERROR;
}
@@ -1855,141 +1838,854 @@ TclOODefineUnexportObjCmd(
/*
* ----------------------------------------------------------------------
*
- * TclOODefineVariablesObjCmd --
- * Implementation of the "variable" subcommand of the "oo::define" and
- * "oo::objdefine" commands.
+ * Tcl_ClassSetConstructor, Tcl_ClassSetDestructor --
+ * How to install a constructor or destructor into a class; API to call
+ * from C.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+Tcl_ClassSetConstructor(
+ Tcl_Interp *interp,
+ Tcl_Class clazz,
+ Tcl_Method method)
+{
+ Class *clsPtr = (Class *) clazz;
+
+ if (method != (Tcl_Method) clsPtr->constructorPtr) {
+ TclOODelMethodRef(clsPtr->constructorPtr);
+ clsPtr->constructorPtr = (Method *) method;
+
+ /*
+ * Remember to invalidate the cached constructor chain for this class.
+ * [Bug 2531577]
+ */
+
+ if (clsPtr->constructorChainPtr) {
+ TclOODeleteChain(clsPtr->constructorChainPtr);
+ clsPtr->constructorChainPtr = NULL;
+ }
+ BumpGlobalEpoch(interp, clsPtr);
+ }
+}
+
+void
+Tcl_ClassSetDestructor(
+ Tcl_Interp *interp,
+ Tcl_Class clazz,
+ Tcl_Method method)
+{
+ Class *clsPtr = (Class *) clazz;
+
+ if (method != (Tcl_Method) clsPtr->destructorPtr) {
+ TclOODelMethodRef(clsPtr->destructorPtr);
+ clsPtr->destructorPtr = (Method *) method;
+ if (clsPtr->destructorChainPtr) {
+ TclOODeleteChain(clsPtr->destructorChainPtr);
+ clsPtr->destructorChainPtr = NULL;
+ }
+ BumpGlobalEpoch(interp, clsPtr);
+ }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODefineSlots --
+ * Create the "::oo::Slot" class and its standard instances. Class
+ * definition is empty at the stage (added by scripting).
*
* ----------------------------------------------------------------------
*/
int
-TclOODefineVariablesObjCmd(
+TclOODefineSlots(
+ Foundation *fPtr)
+{
+ const struct DeclaredSlot *slotInfoPtr;
+ Tcl_Obj *getName = Tcl_NewStringObj("Get", -1);
+ Tcl_Obj *setName = Tcl_NewStringObj("Set", -1);
+ Class *slotCls;
+
+ slotCls = ((Object *) Tcl_NewObjectInstance(fPtr->interp, (Tcl_Class)
+ fPtr->classCls, "::oo::Slot", NULL, -1, NULL, 0))->classPtr;
+ if (slotCls == NULL) {
+ return TCL_ERROR;
+ }
+ Tcl_IncrRefCount(getName);
+ Tcl_IncrRefCount(setName);
+ for (slotInfoPtr = slots ; slotInfoPtr->name ; slotInfoPtr++) {
+ Tcl_Object slotObject = Tcl_NewObjectInstance(fPtr->interp,
+ (Tcl_Class) slotCls, slotInfoPtr->name, NULL,-1,NULL,0);
+
+ if (slotObject == NULL) {
+ continue;
+ }
+ Tcl_NewInstanceMethod(fPtr->interp, slotObject, getName, 0,
+ &slotInfoPtr->getterType, NULL);
+ Tcl_NewInstanceMethod(fPtr->interp, slotObject, setName, 0,
+ &slotInfoPtr->setterType, NULL);
+ }
+ Tcl_DecrRefCount(getName);
+ Tcl_DecrRefCount(setName);
+ return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ClassFilterGet, ClassFilterSet --
+ * Implementation of the "filter" slot accessors of the "oo::define"
+ * command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+ClassFilterGet(
ClientData clientData,
Tcl_Interp *interp,
+ Tcl_ObjectContext context,
int objc,
Tcl_Obj *const *objv)
{
- int isInstanceVars = (clientData != NULL);
Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
- Tcl_Obj *variableObj;
+ Tcl_Obj *resultObj, *filterObj;
int i;
+ if (Tcl_ObjectContextSkippedArgs(context) != objc) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ NULL);
+ return TCL_ERROR;
+ }
if (oPtr == NULL) {
return TCL_ERROR;
+ } else if (!oPtr->classPtr) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+ return TCL_ERROR;
+ }
+
+ resultObj = Tcl_NewObj();
+ FOREACH(filterObj, oPtr->classPtr->filters) {
+ Tcl_ListObjAppendElement(NULL, resultObj, filterObj);
+ }
+ Tcl_SetObjResult(interp, resultObj);
+ return TCL_OK;
+}
+
+static int
+ClassFilterSet(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tcl_ObjectContext context,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+ int filterc;
+ Tcl_Obj **filterv;
+
+ if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ "filterList");
+ return TCL_ERROR;
}
- if (!isInstanceVars && !oPtr->classPtr) {
- Tcl_AppendResult(interp, "attempt to misuse API", NULL);
+ objv += Tcl_ObjectContextSkippedArgs(context);
+
+ if (oPtr == NULL) {
+ return TCL_ERROR;
+ } else if (!oPtr->classPtr) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return TCL_ERROR;
+ } else if (Tcl_ListObjGetElements(interp, objv[0], &filterc,
+ &filterv) != TCL_OK) {
+ return TCL_ERROR;
}
- for (i=1 ; i<objc ; i++) {
- const char *varName = Tcl_GetString(objv[i]);
+ TclOOClassSetFilters(interp, oPtr->classPtr, filterc, filterv);
+ return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ClassMixinGet, ClassMixinSet --
+ * Implementation of the "mixin" slot accessors of the "oo::define"
+ * command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+ClassMixinGet(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tcl_ObjectContext context,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+ Tcl_Obj *resultObj;
+ Class *mixinPtr;
+ int i;
+
+ if (Tcl_ObjectContextSkippedArgs(context) != objc) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ NULL);
+ return TCL_ERROR;
+ }
+ if (oPtr == NULL) {
+ return TCL_ERROR;
+ } else if (!oPtr->classPtr) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+ return TCL_ERROR;
+ }
+
+ resultObj = Tcl_NewObj();
+ FOREACH(mixinPtr, oPtr->classPtr->mixins) {
+ Tcl_ListObjAppendElement(NULL, resultObj,
+ TclOOObjectName(interp, mixinPtr->thisPtr));
+ }
+ Tcl_SetObjResult(interp, resultObj);
+ return TCL_OK;
+
+}
+
+static int
+ClassMixinSet(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tcl_ObjectContext context,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+ int mixinc, i;
+ Tcl_Obj **mixinv;
+ Class **mixins;
+
+ if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ "mixinList");
+ return TCL_ERROR;
+ }
+ objv += Tcl_ObjectContextSkippedArgs(context);
+
+ if (oPtr == NULL) {
+ return TCL_ERROR;
+ } else if (!oPtr->classPtr) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+ return TCL_ERROR;
+ } else if (Tcl_ListObjGetElements(interp, objv[0], &mixinc,
+ &mixinv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ mixins = TclStackAlloc(interp, sizeof(Class *) * mixinc);
+
+ for (i=0 ; i<mixinc ; i++) {
+ mixins[i] = GetClassInOuterContext(interp, mixinv[i],
+ "may only mix in classes");
+ if (mixins[i] == NULL) {
+ goto freeAndError;
+ }
+ if (TclOOIsReachable(oPtr->classPtr, mixins[i])) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "may not mix a class into itself", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", NULL);
+ goto freeAndError;
+ }
+ }
+
+ TclOOClassSetMixins(interp, oPtr->classPtr, mixinc, mixins);
+ TclStackFree(interp, mixins);
+ return TCL_OK;
+
+ freeAndError:
+ TclStackFree(interp, mixins);
+ return TCL_ERROR;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ClassSuperGet, ClassSuperSet --
+ * Implementation of the "superclass" slot accessors of the "oo::define"
+ * command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+ClassSuperGet(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tcl_ObjectContext context,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+ Tcl_Obj *resultObj;
+ Class *superPtr;
+ int i;
+
+ if (Tcl_ObjectContextSkippedArgs(context) != objc) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ NULL);
+ return TCL_ERROR;
+ }
+ if (oPtr == NULL) {
+ return TCL_ERROR;
+ } else if (!oPtr->classPtr) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+ return TCL_ERROR;
+ }
+
+ resultObj = Tcl_NewObj();
+ FOREACH(superPtr, oPtr->classPtr->superclasses) {
+ Tcl_ListObjAppendElement(NULL, resultObj,
+ TclOOObjectName(interp, superPtr->thisPtr));
+ }
+ Tcl_SetObjResult(interp, resultObj);
+ return TCL_OK;
+}
+
+static int
+ClassSuperSet(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tcl_ObjectContext context,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+ int superc, i, j;
+ Tcl_Obj **superv;
+ Class **superclasses, *superPtr;
+
+ if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ "superclassList");
+ return TCL_ERROR;
+ }
+ objv += Tcl_ObjectContextSkippedArgs(context);
+
+ if (oPtr == NULL) {
+ return TCL_ERROR;
+ } else if (!oPtr->classPtr) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+ return TCL_ERROR;
+ } else if (oPtr == oPtr->fPtr->objectCls->thisPtr) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "may not modify the superclass of the root object", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+ return TCL_ERROR;
+ } else if (Tcl_ListObjGetElements(interp, objv[0], &superc,
+ &superv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Allocate some working space.
+ */
+
+ superclasses = (Class **) ckalloc(sizeof(Class *) * superc);
+
+ /*
+ * Parse the arguments to get the class to use as superclasses.
+ *
+ * Note that zero classes is special, as it is equivalent to just the
+ * class of objects. [Bug 9d61624b3d]
+ */
+
+ 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 {
+ for (i=0 ; i<superc ; i++) {
+ superclasses[i] = GetClassInOuterContext(interp, superv[i],
+ "only a class can be a superclass");
+ if (superclasses[i] == NULL) {
+ goto failedAfterAlloc;
+ }
+ for (j=0 ; j<i ; j++) {
+ if (superclasses[j] == superclasses[i]) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "class should only be a direct superclass once",
+ -1));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "REPETITIOUS",NULL);
+ goto failedAfterAlloc;
+ }
+ }
+ if (TclOOIsReachable(oPtr->classPtr, superclasses[i])) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to form circular dependency graph", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "CIRCULARITY", NULL);
+ failedAfterAlloc:
+ ckfree((char *) superclasses);
+ return TCL_ERROR;
+ }
+ }
+ }
+
+ /*
+ * Install the list of superclasses into the class. Note that this also
+ * involves splicing the class out of the superclasses' subclass list that
+ * it used to be a member of and splicing it into the new superclasses'
+ * subclass list.
+ */
+
+ if (oPtr->classPtr->superclasses.num != 0) {
+ FOREACH(superPtr, oPtr->classPtr->superclasses) {
+ TclOORemoveFromSubclasses(oPtr->classPtr, superPtr);
+ }
+ ckfree((char *) oPtr->classPtr->superclasses.list);
+ }
+ oPtr->classPtr->superclasses.list = superclasses;
+ oPtr->classPtr->superclasses.num = superc;
+ FOREACH(superPtr, oPtr->classPtr->superclasses) {
+ TclOOAddToSubclasses(oPtr->classPtr, superPtr);
+ }
+ BumpGlobalEpoch(interp, oPtr->classPtr);
+
+ return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ClassVarsGet, ClassVarsSet --
+ * Implementation of the "variable" slot accessors of the "oo::define"
+ * command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+ClassVarsGet(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tcl_ObjectContext context,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+ Tcl_Obj *resultObj, *variableObj;
+ int i;
+
+ if (Tcl_ObjectContextSkippedArgs(context) != objc) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ NULL);
+ return TCL_ERROR;
+ }
+ if (oPtr == NULL) {
+ return TCL_ERROR;
+ } else if (!oPtr->classPtr) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+ return TCL_ERROR;
+ }
+
+ resultObj = Tcl_NewObj();
+ FOREACH(variableObj, oPtr->classPtr->variables) {
+ Tcl_ListObjAppendElement(NULL, resultObj, variableObj);
+ }
+ Tcl_SetObjResult(interp, resultObj);
+ return TCL_OK;
+}
+
+static int
+ClassVarsSet(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tcl_ObjectContext context,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+ int varc;
+ Tcl_Obj **varv, *variableObj;
+ int i;
+
+ if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ "filterList");
+ return TCL_ERROR;
+ }
+ objv += Tcl_ObjectContextSkippedArgs(context);
+
+ if (oPtr == NULL) {
+ return TCL_ERROR;
+ } else if (!oPtr->classPtr) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "attempt to misuse API", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+ return TCL_ERROR;
+ } else if (Tcl_ListObjGetElements(interp, objv[0], &varc,
+ &varv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ for (i=0 ; i<varc ; i++) {
+ const char *varName = Tcl_GetString(varv[i]);
if (strstr(varName, "::") != NULL) {
- Tcl_AppendResult(interp, "invalid declared variable name \"",
- varName, "\": must not contain namespace separators",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid declared variable name \"%s\": must not %s",
+ varName, "contain namespace separators"));
Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_DECLVAR", NULL);
return TCL_ERROR;
}
if (Tcl_StringMatch(varName, "*(*)")) {
- Tcl_AppendResult(interp, "invalid declared variable name \"",
- varName, "\": must not refer to an array element", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid declared variable name \"%s\": must not %s",
+ varName, "refer to an array element"));
Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_DECLVAR", NULL);
return TCL_ERROR;
}
}
- for (i=1 ; i<objc ; i++) {
- Tcl_IncrRefCount(objv[i]);
- }
- if (!isInstanceVars) {
- FOREACH(variableObj, oPtr->classPtr->variables) {
- Tcl_DecrRefCount(variableObj);
- }
- if (i != objc-1) {
- if (objc == 1) {
- ckfree(oPtr->classPtr->variables.list);
- } else if (i) {
- oPtr->classPtr->variables.list =
- ckrealloc(oPtr->classPtr->variables.list,
- sizeof(Tcl_Obj *) * (objc-1));
- } else {
- oPtr->classPtr->variables.list =
- ckalloc(sizeof(Tcl_Obj *) * (objc-1));
- }
- }
- if (objc > 1) {
- memcpy(oPtr->classPtr->variables.list, objv+1,
- sizeof(Tcl_Obj *) * (objc-1));
+ for (i=0 ; i<varc ; i++) {
+ Tcl_IncrRefCount(varv[i]);
+ }
+ FOREACH(variableObj, oPtr->classPtr->variables) {
+ Tcl_DecrRefCount(variableObj);
+ }
+ if (i != varc) {
+ if (varc == 0) {
+ ckfree((char *) oPtr->classPtr->variables.list);
+ } else if (i) {
+ oPtr->classPtr->variables.list = (Tcl_Obj **)
+ ckrealloc((char *) oPtr->classPtr->variables.list,
+ sizeof(Tcl_Obj *) * varc);
+ } else {
+ oPtr->classPtr->variables.list = (Tcl_Obj **)
+ ckalloc(sizeof(Tcl_Obj *) * varc);
}
- oPtr->classPtr->variables.num = objc-1;
- } else {
- FOREACH(variableObj, oPtr->variables) {
- Tcl_DecrRefCount(variableObj);
- }
- if (i != objc-1) {
- if (objc == 1) {
- ckfree(oPtr->variables.list);
- } else if (i) {
- oPtr->variables.list = ckrealloc(oPtr->variables.list,
- sizeof(Tcl_Obj *) * (objc-1));
+ }
+
+ oPtr->classPtr->variables.num = 0;
+ if (varc > 0) {
+ int created, n;
+ Tcl_HashTable uniqueTable;
+
+ Tcl_InitObjHashTable(&uniqueTable);
+ for (i=n=0 ; i<varc ; i++) {
+ Tcl_CreateHashEntry(&uniqueTable, varv[i], &created);
+ if (created) {
+ oPtr->classPtr->variables.list[n++] = varv[i];
} else {
- oPtr->variables.list =
- ckalloc(sizeof(Tcl_Obj *) * (objc-1));
+ Tcl_DecrRefCount(varv[i]);
}
}
- if (objc > 1) {
- memcpy(oPtr->variables.list, objv+1, sizeof(Tcl_Obj *)*(objc-1));
- }
- oPtr->variables.num = objc-1;
+ oPtr->classPtr->variables.num = n;
+
+ /*
+ * Shouldn't be necessary, but maintain num/list invariant.
+ */
+
+ oPtr->classPtr->variables.list = (Tcl_Obj **)
+ ckrealloc((char *) oPtr->classPtr->variables.list,
+ sizeof(Tcl_Obj *) * n);
+ Tcl_DeleteHashTable(&uniqueTable);
}
return TCL_OK;
}
-void
-Tcl_ClassSetConstructor(
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ObjectFilterGet, ObjectFilterSet --
+ * Implementation of the "filter" slot accessors of the "oo::objdefine"
+ * command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+ObjFilterGet(
+ ClientData clientData,
Tcl_Interp *interp,
- Tcl_Class clazz,
- Tcl_Method method)
+ Tcl_ObjectContext context,
+ int objc,
+ Tcl_Obj *const *objv)
{
- Class *clsPtr = (Class *) clazz;
+ Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+ Tcl_Obj *resultObj, *filterObj;
+ int i;
- if (method != (Tcl_Method) clsPtr->constructorPtr) {
- TclOODelMethodRef(clsPtr->constructorPtr);
- clsPtr->constructorPtr = (Method *) method;
+ if (Tcl_ObjectContextSkippedArgs(context) != objc) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ NULL);
+ return TCL_ERROR;
+ } else if (oPtr == NULL) {
+ return TCL_ERROR;
+ }
- /*
- * Remember to invalidate the cached constructor chain for this class.
- * [Bug 2531577]
- */
+ resultObj = Tcl_NewObj();
+ FOREACH(filterObj, oPtr->filters) {
+ Tcl_ListObjAppendElement(NULL, resultObj, filterObj);
+ }
+ Tcl_SetObjResult(interp, resultObj);
+ return TCL_OK;
+}
- if (clsPtr->constructorChainPtr) {
- TclOODeleteChain(clsPtr->constructorChainPtr);
- clsPtr->constructorChainPtr = NULL;
+static int
+ObjFilterSet(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tcl_ObjectContext context,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+ int filterc;
+ Tcl_Obj **filterv;
+
+ if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ "filterList");
+ return TCL_ERROR;
+ } else if (oPtr == NULL) {
+ return TCL_ERROR;
+ }
+ objv += Tcl_ObjectContextSkippedArgs(context);
+ if (Tcl_ListObjGetElements(interp, objv[0], &filterc,
+ &filterv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ TclOOObjectSetFilters(oPtr, filterc, filterv);
+ return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ObjectMixinGet, ObjectMixinSet --
+ * Implementation of the "mixin" slot accessors of the "oo::objdefine"
+ * command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+ObjMixinGet(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tcl_ObjectContext context,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+ Tcl_Obj *resultObj;
+ Class *mixinPtr;
+ int i;
+
+ if (Tcl_ObjectContextSkippedArgs(context) != objc) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ NULL);
+ return TCL_ERROR;
+ } else if (oPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ resultObj = Tcl_NewObj();
+ FOREACH(mixinPtr, oPtr->mixins) {
+ Tcl_ListObjAppendElement(NULL, resultObj,
+ TclOOObjectName(interp, mixinPtr->thisPtr));
+ }
+ Tcl_SetObjResult(interp, resultObj);
+ return TCL_OK;
+}
+
+static int
+ObjMixinSet(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tcl_ObjectContext context,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+ int mixinc;
+ Tcl_Obj **mixinv;
+ Class **mixins;
+ int i;
+
+ if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ "mixinList");
+ return TCL_ERROR;
+ } else if (oPtr == NULL) {
+ return TCL_ERROR;
+ }
+ objv += Tcl_ObjectContextSkippedArgs(context);
+ if (Tcl_ListObjGetElements(interp, objv[0], &mixinc,
+ &mixinv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ mixins = TclStackAlloc(interp, sizeof(Class *) * mixinc);
+
+ for (i=0 ; i<mixinc ; i++) {
+ mixins[i] = GetClassInOuterContext(interp, mixinv[i],
+ "may only mix in classes");
+ if (mixins[i] == NULL) {
+ TclStackFree(interp, mixins);
+ return TCL_ERROR;
}
- BumpGlobalEpoch(interp, clsPtr);
}
+
+ TclOOObjectSetMixins(oPtr, mixinc, mixins);
+ TclStackFree(interp, mixins);
+ return TCL_OK;
}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ObjectVarsGet, ObjectVarsSet --
+ * Implementation of the "variable" slot accessors of the "oo::objdefine"
+ * command.
+ *
+ * ----------------------------------------------------------------------
+ */
-void
-Tcl_ClassSetDestructor(
+static int
+ObjVarsGet(
+ ClientData clientData,
Tcl_Interp *interp,
- Tcl_Class clazz,
- Tcl_Method method)
+ Tcl_ObjectContext context,
+ int objc,
+ Tcl_Obj *const *objv)
{
- Class *clsPtr = (Class *) clazz;
+ Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+ Tcl_Obj *resultObj, *variableObj;
+ int i;
- if (method != (Tcl_Method) clsPtr->destructorPtr) {
- TclOODelMethodRef(clsPtr->destructorPtr);
- clsPtr->destructorPtr = (Method *) method;
- if (clsPtr->destructorChainPtr) {
- TclOODeleteChain(clsPtr->destructorChainPtr);
- clsPtr->destructorChainPtr = NULL;
+ if (Tcl_ObjectContextSkippedArgs(context) != objc) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ NULL);
+ return TCL_ERROR;
+ } else if (oPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ resultObj = Tcl_NewObj();
+ FOREACH(variableObj, oPtr->variables) {
+ Tcl_ListObjAppendElement(NULL, resultObj, variableObj);
+ }
+ Tcl_SetObjResult(interp, resultObj);
+ return TCL_OK;
+}
+
+static int
+ObjVarsSet(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tcl_ObjectContext context,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+ int varc, i;
+ Tcl_Obj **varv, *variableObj;
+
+ if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+ Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+ "variableList");
+ return TCL_ERROR;
+ } else if (oPtr == NULL) {
+ return TCL_ERROR;
+ }
+ objv += Tcl_ObjectContextSkippedArgs(context);
+ if (Tcl_ListObjGetElements(interp, objv[0], &varc,
+ &varv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ for (i=0 ; i<varc ; i++) {
+ const char *varName = Tcl_GetString(varv[i]);
+
+ if (strstr(varName, "::") != NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid declared variable name \"%s\": must not %s",
+ varName, "contain namespace separators"));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_DECLVAR", NULL);
+ return TCL_ERROR;
+ }
+ if (Tcl_StringMatch(varName, "*(*)")) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid declared variable name \"%s\": must not %s",
+ varName, "refer to an array element"));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_DECLVAR", NULL);
+ return TCL_ERROR;
+ }
+ }
+ for (i=0 ; i<varc ; i++) {
+ Tcl_IncrRefCount(varv[i]);
+ }
+
+ FOREACH(variableObj, oPtr->variables) {
+ Tcl_DecrRefCount(variableObj);
+ }
+ if (i != varc) {
+ if (varc == 0) {
+ ckfree((char *) oPtr->variables.list);
+ } else if (i) {
+ oPtr->variables.list = (Tcl_Obj **)
+ ckrealloc((char *) oPtr->variables.list,
+ sizeof(Tcl_Obj *) * varc);
+ } else {
+ oPtr->variables.list = (Tcl_Obj **)
+ ckalloc(sizeof(Tcl_Obj *) * varc);
}
- BumpGlobalEpoch(interp, clsPtr);
}
+ oPtr->variables.num = 0;
+ if (varc > 0) {
+ int created, n;
+ Tcl_HashTable uniqueTable;
+
+ Tcl_InitObjHashTable(&uniqueTable);
+ for (i=n=0 ; i<varc ; i++) {
+ Tcl_CreateHashEntry(&uniqueTable, varv[i], &created);
+ if (created) {
+ oPtr->variables.list[n++] = varv[i];
+ } else {
+ Tcl_DecrRefCount(varv[i]);
+ }
+ }
+ oPtr->variables.num = n;
+
+ /*
+ * Shouldn't be necessary, but maintain num/list invariant.
+ */
+
+ oPtr->variables.list = (Tcl_Obj **)
+ ckrealloc((char *) oPtr->variables.list,
+ sizeof(Tcl_Obj *) * n);
+ Tcl_DeleteHashTable(&uniqueTable);
+ }
+ return TCL_OK;
}
/*
diff --git a/generic/tclOOInfo.c b/generic/tclOOInfo.c
index f298320..3217f98 100644
--- a/generic/tclOOInfo.c
+++ b/generic/tclOOInfo.c
@@ -4,7 +4,7 @@
* This file contains the implementation of the ::oo-related [info]
* subcommands.
*
- * Copyright (c) 2006-2008 by Donal K. Fellows
+ * Copyright (c) 2006-2011 by Donal K. Fellows
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -43,47 +43,45 @@ static Tcl_ObjCmdProc InfoClassSubsCmd;
static Tcl_ObjCmdProc InfoClassSupersCmd;
static Tcl_ObjCmdProc InfoClassVariablesCmd;
-struct NameProcMap { const char *name; Tcl_ObjCmdProc *proc; };
-
/*
* List of commands that are used to implement the [info object] subcommands.
*/
-static const struct NameProcMap infoObjectCmds[] = {
- {"::oo::InfoObject::call", InfoObjectCallCmd},
- {"::oo::InfoObject::class", InfoObjectClassCmd},
- {"::oo::InfoObject::definition", InfoObjectDefnCmd},
- {"::oo::InfoObject::filters", InfoObjectFiltersCmd},
- {"::oo::InfoObject::forward", InfoObjectForwardCmd},
- {"::oo::InfoObject::isa", InfoObjectIsACmd},
- {"::oo::InfoObject::methods", InfoObjectMethodsCmd},
- {"::oo::InfoObject::methodtype", InfoObjectMethodTypeCmd},
- {"::oo::InfoObject::mixins", InfoObjectMixinsCmd},
- {"::oo::InfoObject::namespace", InfoObjectNsCmd},
- {"::oo::InfoObject::variables", InfoObjectVariablesCmd},
- {"::oo::InfoObject::vars", InfoObjectVarsCmd},
- {NULL, NULL}
+static const EnsembleImplMap infoObjectCmds[] = {
+ {"call", InfoObjectCallCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"class", InfoObjectClassCmd, TclCompileInfoObjectClassCmd, NULL, NULL, 0},
+ {"definition", InfoObjectDefnCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"filters", InfoObjectFiltersCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"forward", InfoObjectForwardCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"isa", InfoObjectIsACmd, TclCompileInfoObjectIsACmd, NULL, NULL, 0},
+ {"methods", InfoObjectMethodsCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
+ {"methodtype", InfoObjectMethodTypeCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"mixins", InfoObjectMixinsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"namespace", InfoObjectNsCmd, TclCompileInfoObjectNamespaceCmd, NULL, NULL, 0},
+ {"variables", InfoObjectVariablesCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"vars", InfoObjectVarsCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+ {NULL, NULL, NULL, NULL, NULL, 0}
};
/*
* List of commands that are used to implement the [info class] subcommands.
*/
-static const struct NameProcMap infoClassCmds[] = {
- {"::oo::InfoClass::call", InfoClassCallCmd},
- {"::oo::InfoClass::constructor", InfoClassConstrCmd},
- {"::oo::InfoClass::definition", InfoClassDefnCmd},
- {"::oo::InfoClass::destructor", InfoClassDestrCmd},
- {"::oo::InfoClass::filters", InfoClassFiltersCmd},
- {"::oo::InfoClass::forward", InfoClassForwardCmd},
- {"::oo::InfoClass::instances", InfoClassInstancesCmd},
- {"::oo::InfoClass::methods", InfoClassMethodsCmd},
- {"::oo::InfoClass::methodtype", InfoClassMethodTypeCmd},
- {"::oo::InfoClass::mixins", InfoClassMixinsCmd},
- {"::oo::InfoClass::subclasses", InfoClassSubsCmd},
- {"::oo::InfoClass::superclasses", InfoClassSupersCmd},
- {"::oo::InfoClass::variables", InfoClassVariablesCmd},
- {NULL, NULL}
+static const EnsembleImplMap infoClassCmds[] = {
+ {"call", InfoClassCallCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"constructor", InfoClassConstrCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"definition", InfoClassDefnCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"destructor", InfoClassDestrCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"filters", InfoClassFiltersCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"forward", InfoClassForwardCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"instances", InfoClassInstancesCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+ {"methods", InfoClassMethodsCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
+ {"methodtype", InfoClassMethodTypeCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"mixins", InfoClassMixinsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"subclasses", InfoClassSubsCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+ {"superclasses", InfoClassSupersCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"variables", InfoClassVariablesCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {NULL, NULL, NULL, NULL, NULL, 0}
};
/*
@@ -101,58 +99,27 @@ void
TclOOInitInfo(
Tcl_Interp *interp)
{
- Tcl_Namespace *nsPtr;
Tcl_Command infoCmd;
- int i;
-
- /*
- * Build the ensemble used to implement [info object].
- */
-
- nsPtr = Tcl_CreateNamespace(interp, "::oo::InfoObject", NULL, NULL);
- Tcl_CreateEnsemble(interp, nsPtr->fullName, nsPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, nsPtr, "[a-z]*", 1);
- for (i=0 ; infoObjectCmds[i].name!=NULL ; i++) {
- Tcl_CreateObjCommand(interp, infoObjectCmds[i].name,
- infoObjectCmds[i].proc, NULL, NULL);
- }
+ Tcl_Obj *mapDict;
/*
- * Build the ensemble used to implement [info class].
+ * Build the ensembles used to implement [info object] and [info class].
*/
- nsPtr = Tcl_CreateNamespace(interp, "::oo::InfoClass", NULL, NULL);
- Tcl_CreateEnsemble(interp, nsPtr->fullName, nsPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, nsPtr, "[a-z]*", 1);
- for (i=0 ; infoClassCmds[i].name!=NULL ; i++) {
- Tcl_CreateObjCommand(interp, infoClassCmds[i].name,
- infoClassCmds[i].proc, NULL, NULL);
- }
+ TclMakeEnsemble(interp, "::oo::InfoObject", infoObjectCmds);
+ TclMakeEnsemble(interp, "::oo::InfoClass", infoClassCmds);
/*
* Install into the master [info] ensemble.
*/
infoCmd = Tcl_FindCommand(interp, "info", NULL, TCL_GLOBAL_ONLY);
- if (infoCmd != NULL && Tcl_IsEnsemble(infoCmd)) {
- Tcl_Obj *mapDict, *objectObj, *classObj;
-
- Tcl_GetEnsembleMappingDict(NULL, infoCmd, &mapDict);
- if (mapDict != NULL) {
- objectObj = Tcl_NewStringObj("object", -1);
- classObj = Tcl_NewStringObj("class", -1);
-
- Tcl_IncrRefCount(objectObj);
- Tcl_IncrRefCount(classObj);
- Tcl_DictObjPut(NULL, mapDict, objectObj,
- Tcl_NewStringObj("::oo::InfoObject", -1));
- Tcl_DictObjPut(NULL, mapDict, classObj,
- Tcl_NewStringObj("::oo::InfoClass", -1));
- Tcl_DecrRefCount(objectObj);
- Tcl_DecrRefCount(classObj);
- Tcl_SetEnsembleMappingDict(interp, infoCmd, mapDict);
- }
- }
+ Tcl_GetEnsembleMappingDict(NULL, infoCmd, &mapDict);
+ Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("object", -1),
+ Tcl_NewStringObj("::oo::InfoObject", -1));
+ Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("class", -1),
+ Tcl_NewStringObj("::oo::InfoClass", -1));
+ Tcl_SetEnsembleMappingDict(interp, infoCmd, mapDict);
}
/*
@@ -177,8 +144,8 @@ GetClassFromObj(
return NULL;
}
if (oPtr->classPtr == NULL) {
- Tcl_AppendResult(interp, "\"", TclGetString(objPtr),
- "\" is not a class", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" is not a class", TclGetString(objPtr)));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
TclGetString(objPtr), NULL);
return NULL;
@@ -279,16 +246,16 @@ InfoObjectDefnCmd(
hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[2]);
if (hPtr == NULL) {
unknownMethod:
- Tcl_AppendResult(interp, "unknown method \"", TclGetString(objv[2]),
- "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown method \"%s\"", TclGetString(objv[2])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(objv[2]), NULL);
return TCL_ERROR;
}
procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr));
if (procPtr == NULL) {
- Tcl_AppendResult(interp,
- "definition not available for this kind of method", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "definition not available for this kind of method", -1));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(objv[2]), NULL);
return TCL_ERROR;
@@ -390,17 +357,17 @@ InfoObjectForwardCmd(
hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[2]);
if (hPtr == NULL) {
unknownMethod:
- Tcl_AppendResult(interp, "unknown method \"", TclGetString(objv[2]),
- "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown method \"%s\"", TclGetString(objv[2])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(objv[2]), NULL);
return TCL_ERROR;
}
prefixObj = TclOOGetFwdFromMethod(Tcl_GetHashValue(hPtr));
if (prefixObj == NULL) {
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"prefix argument list not available for this kind of method",
- NULL);
+ -1));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(objv[2]), NULL);
return TCL_ERROR;
@@ -491,7 +458,8 @@ InfoObjectIsACmd(
return TCL_ERROR;
}
if (o2Ptr->classPtr == NULL) {
- Tcl_AppendResult(interp, "non-classes cannot be mixins", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "non-classes cannot be mixins", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "NONCLASS", NULL);
return TCL_ERROR;
} else {
@@ -516,7 +484,8 @@ InfoObjectIsACmd(
return TCL_ERROR;
}
if (o2Ptr->classPtr == NULL) {
- Tcl_AppendResult(interp, "non-classes cannot be types", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "non-classes cannot be types", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "NONCLASS", NULL);
return TCL_ERROR;
}
@@ -651,8 +620,8 @@ InfoObjectMethodTypeCmd(
hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[2]);
if (hPtr == NULL) {
unknownMethod:
- Tcl_AppendResult(interp, "unknown method \"", TclGetString(objv[2]),
- "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown method \"%s\"", TclGetString(objv[2])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(objv[2]), NULL);
return TCL_ERROR;
@@ -878,8 +847,8 @@ InfoClassConstrCmd(
}
procPtr = TclOOGetProcFromMethod(clsPtr->constructorPtr);
if (procPtr == NULL) {
- Tcl_AppendResult(interp,
- "definition not available for this kind of method", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "definition not available for this kind of method", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "METHOD_TYPE", NULL);
return TCL_ERROR;
}
@@ -937,16 +906,16 @@ InfoClassDefnCmd(
}
hPtr = Tcl_FindHashEntry(&clsPtr->classMethods, (char *) objv[2]);
if (hPtr == NULL) {
- Tcl_AppendResult(interp, "unknown method \"", TclGetString(objv[2]),
- "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown method \"%s\"", TclGetString(objv[2])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(objv[2]), NULL);
return TCL_ERROR;
}
procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr));
if (procPtr == NULL) {
- Tcl_AppendResult(interp,
- "definition not available for this kind of method", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "definition not available for this kind of method", -1));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(objv[2]), NULL);
return TCL_ERROR;
@@ -1006,8 +975,8 @@ InfoClassDestrCmd(
}
procPtr = TclOOGetProcFromMethod(clsPtr->destructorPtr);
if (procPtr == NULL) {
- Tcl_AppendResult(interp,
- "definition not available for this kind of method", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "definition not available for this kind of method", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "METHOD_TYPE", NULL);
return TCL_ERROR;
}
@@ -1085,17 +1054,17 @@ InfoClassForwardCmd(
}
hPtr = Tcl_FindHashEntry(&clsPtr->classMethods, (char *) objv[2]);
if (hPtr == NULL) {
- Tcl_AppendResult(interp, "unknown method \"", TclGetString(objv[2]),
- "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown method \"%s\"", TclGetString(objv[2])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(objv[2]), NULL);
return TCL_ERROR;
}
prefixObj = TclOOGetFwdFromMethod(Tcl_GetHashValue(hPtr));
if (prefixObj == NULL) {
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"prefix argument list not available for this kind of method",
- NULL);
+ -1));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(objv[2]), NULL);
return TCL_ERROR;
@@ -1269,8 +1238,8 @@ InfoClassMethodTypeCmd(
hPtr = Tcl_FindHashEntry(&clsPtr->classMethods, (char *) objv[2]);
if (hPtr == NULL) {
unknownMethod:
- Tcl_AppendResult(interp, "unknown method \"", TclGetString(objv[2]),
- "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown method \"%s\"", TclGetString(objv[2])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(objv[2]), NULL);
return TCL_ERROR;
@@ -1494,7 +1463,8 @@ InfoObjectCallCmd(
contextPtr = TclOOGetCallContext(oPtr, objv[2], PUBLIC_METHOD, NULL);
if (contextPtr == NULL) {
- Tcl_AppendResult(interp, "cannot construct any call chain", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "cannot construct any call chain", -1));
return TCL_ERROR;
}
Tcl_SetObjResult(interp,
@@ -1538,7 +1508,8 @@ InfoClassCallCmd(
callPtr = TclOOGetStereotypeCallChain(clsPtr, objv[2], PUBLIC_METHOD);
if (callPtr == NULL) {
- Tcl_AppendResult(interp, "cannot construct any call chain", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "cannot construct any call chain", -1));
return TCL_ERROR;
}
Tcl_SetObjResult(interp, TclOORenderCallChain(interp, callPtr));
diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h
index b151183..c0e4022 100644
--- a/generic/tclOOInt.h
+++ b/generic/tclOOInt.h
@@ -4,7 +4,7 @@
* This file contains the structure definitions and some of the function
* declarations for the object-system (NB: not Tcl_Obj, but ::oo).
*
- * Copyright (c) 2006-2011 by Donal K. Fellows
+ * Copyright (c) 2006-2012 by Donal K. Fellows
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -122,12 +122,6 @@ typedef struct ForwardMethod {
Tcl_Obj *prefixObj; /* The list of values to use to replace the
* object and method name with. Will be a
* non-empty list. */
- int fullyQualified; /* If 1, the command name is fully qualified
- * and we should let the default Tcl mechanism
- * handle the command lookup because it is
- * more efficient. If 0, we need to do a
- * specialized lookup based on the current
- * object's namespace. */
} ForwardMethod;
/*
@@ -214,6 +208,8 @@ typedef struct Object {
* class of classes, and should be treated
* specially during teardown (and in a few
* other spots). */
+#define FORCE_UNKNOWN 0x10000 /* States that we are *really* looking up the
+ * unknown method handler at that point. */
/*
* And the definition of a class. Note that every class also has an associated
@@ -318,6 +314,9 @@ typedef struct Foundation {
* constructor. */
Tcl_Obj *destructorName; /* Shared object containing the "name" of a
* destructor. */
+ Tcl_Obj *clonedName; /* Shared object containing the name of a
+ * "<cloned>" pseudo-constructor. */
+ Tcl_Obj *defineName; /* Fully qualified name of oo::define. */
} Foundation;
/*
@@ -377,21 +376,6 @@ typedef struct CallContext {
#define DESTRUCTOR 0x10 /* This is a destructor. */
/*
- * Assorted flags for call frames. Note that bits 1 and 2 are already taken by
- * Tcl itself.
- */
-
-#if 0
-#define FRAME_IS_METHOD 0x4 /* The frame is a method body, and the frame's
- * clientData field contains a CallContext
- * reference. */
-#define FRAME_IS_OO_DEFINE 0x8 /* The frame is part of the inside workings of
- * the [oo::define] command; the clientData
- * field contains an Object reference that has
- * been confirmed to refer to a class. */
-#endif
-
-/*
* Structure containing definition information about basic class methods.
*/
@@ -426,30 +410,18 @@ MODULE_SCOPE int TclOODefineDestructorObjCmd(ClientData clientData,
MODULE_SCOPE int TclOODefineExportObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const *objv);
-MODULE_SCOPE int TclOODefineFilterObjCmd(ClientData clientData,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *const *objv);
MODULE_SCOPE int TclOODefineForwardObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const *objv);
MODULE_SCOPE int TclOODefineMethodObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const *objv);
-MODULE_SCOPE int TclOODefineMixinObjCmd(ClientData clientData,
- Tcl_Interp *interp, const int objc,
- Tcl_Obj *const *objv);
MODULE_SCOPE int TclOODefineRenameMethodObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const *objv);
-MODULE_SCOPE int TclOODefineSuperclassObjCmd(ClientData clientData,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *const *objv);
MODULE_SCOPE int TclOODefineUnexportObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const *objv);
-MODULE_SCOPE int TclOODefineVariablesObjCmd(ClientData clientData,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *const *objv);
MODULE_SCOPE int TclOODefineClassObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const *objv);
@@ -476,6 +448,9 @@ MODULE_SCOPE int TclOOSelfObjCmd(ClientData clientData,
* Method implementations (in tclOOBasic.c).
*/
+MODULE_SCOPE int TclOO_Class_Constructor(ClientData clientData,
+ Tcl_Interp *interp, Tcl_ObjectContext context,
+ int objc, Tcl_Obj *const *objv);
MODULE_SCOPE int TclOO_Class_Create(ClientData clientData,
Tcl_Interp *interp, Tcl_ObjectContext context,
int objc, Tcl_Obj *const *objv);
@@ -514,6 +489,7 @@ MODULE_SCOPE int TclNRNewObjectInstance(Tcl_Interp *interp,
const char *nsNameStr, int objc,
Tcl_Obj *const *objv, int skip,
Tcl_Object *objectPtr);
+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);
@@ -541,8 +517,6 @@ MODULE_SCOPE int TclNRObjectContextInvokeNext(Tcl_Interp *interp,
Tcl_Obj *const *objv, int skip);
MODULE_SCOPE void TclOONewBasicMethod(Tcl_Interp *interp, Class *clsPtr,
const DeclaredClassMethod *dcm);
-MODULE_SCOPE int TclOONRUpcatch(ClientData ignored, Tcl_Interp *interp,
- int objc, Tcl_Obj *const objv[]);
MODULE_SCOPE Tcl_Obj * TclOOObjectName(Tcl_Interp *interp, Object *oPtr);
MODULE_SCOPE void TclOORemoveFromInstances(Object *oPtr, Class *clsPtr);
MODULE_SCOPE void TclOORemoveFromMixinSubs(Class *subPtr,
@@ -554,9 +528,6 @@ MODULE_SCOPE Tcl_Obj * TclOORenderCallChain(Tcl_Interp *interp,
MODULE_SCOPE void TclOOStashContext(Tcl_Obj *objPtr,
CallContext *contextPtr);
MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr);
-MODULE_SCOPE int TclOOUpcatchCmd(ClientData ignored,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *const objv[]);
/*
* Include all the private API, generated from tclOO.decls.
diff --git a/generic/tclOOIntDecls.h b/generic/tclOOIntDecls.h
index b9600f2..74a8d81 100644
--- a/generic/tclOOIntDecls.h
+++ b/generic/tclOOIntDecls.h
@@ -5,70 +5,57 @@
#ifndef _TCLOOINTDECLS
#define _TCLOOINTDECLS
-#undef TCL_STORAGE_CLASS
-#ifdef BUILD_tcl
-# define TCL_STORAGE_CLASS DLLEXPORT
-#else
-# ifdef USE_TCL_STUBS
-# define TCL_STORAGE_CLASS
-# else
-# define TCL_STORAGE_CLASS DLLIMPORT
-# endif
-#endif
-
-/*
- * WARNING: This file is automatically generated by the tools/genStubs.tcl
- * script. Any modifications to the function declarations below should be made
- * in the generic/tclOO.decls script.
- */
-
/* !BEGIN!: Do not edit below this line. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Exported function declarations:
*/
/* 0 */
-EXTERN Tcl_Object TclOOGetDefineCmdContext(Tcl_Interp *interp);
+TCLAPI Tcl_Object TclOOGetDefineCmdContext(Tcl_Interp *interp);
/* 1 */
-EXTERN Tcl_Method TclOOMakeProcInstanceMethod(Tcl_Interp *interp,
+TCLAPI Tcl_Method TclOOMakeProcInstanceMethod(Tcl_Interp *interp,
Object *oPtr, int flags, Tcl_Obj *nameObj,
Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
const Tcl_MethodType *typePtr,
ClientData clientData, Proc **procPtrPtr);
/* 2 */
-EXTERN Tcl_Method TclOOMakeProcMethod(Tcl_Interp *interp,
+TCLAPI Tcl_Method TclOOMakeProcMethod(Tcl_Interp *interp,
Class *clsPtr, int flags, Tcl_Obj *nameObj,
const char *namePtr, Tcl_Obj *argsObj,
Tcl_Obj *bodyObj,
const Tcl_MethodType *typePtr,
ClientData clientData, Proc **procPtrPtr);
/* 3 */
-EXTERN Method * TclOONewProcInstanceMethod(Tcl_Interp *interp,
+TCLAPI Method * TclOONewProcInstanceMethod(Tcl_Interp *interp,
Object *oPtr, int flags, Tcl_Obj *nameObj,
Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
ProcedureMethod **pmPtrPtr);
/* 4 */
-EXTERN Method * TclOONewProcMethod(Tcl_Interp *interp, Class *clsPtr,
+TCLAPI Method * TclOONewProcMethod(Tcl_Interp *interp, Class *clsPtr,
int flags, Tcl_Obj *nameObj,
Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
ProcedureMethod **pmPtrPtr);
/* 5 */
-EXTERN int TclOOObjectCmdCore(Object *oPtr, Tcl_Interp *interp,
+TCLAPI int TclOOObjectCmdCore(Object *oPtr, Tcl_Interp *interp,
int objc, Tcl_Obj *const *objv,
int publicOnly, Class *startCls);
/* 6 */
-EXTERN int TclOOIsReachable(Class *targetPtr, Class *startPtr);
+TCLAPI int TclOOIsReachable(Class *targetPtr, Class *startPtr);
/* 7 */
-EXTERN Method * TclOONewForwardMethod(Tcl_Interp *interp,
+TCLAPI Method * TclOONewForwardMethod(Tcl_Interp *interp,
Class *clsPtr, int isPublic,
Tcl_Obj *nameObj, Tcl_Obj *prefixObj);
/* 8 */
-EXTERN Method * TclOONewForwardInstanceMethod(Tcl_Interp *interp,
+TCLAPI Method * TclOONewForwardInstanceMethod(Tcl_Interp *interp,
Object *oPtr, int isPublic, Tcl_Obj *nameObj,
Tcl_Obj *prefixObj);
/* 9 */
-EXTERN Tcl_Method TclOONewProcInstanceMethodEx(Tcl_Interp *interp,
+TCLAPI Tcl_Method TclOONewProcInstanceMethodEx(Tcl_Interp *interp,
Tcl_Object oPtr,
TclOO_PreCallProc *preCallPtr,
TclOO_PostCallProc *postCallPtr,
@@ -77,7 +64,7 @@ EXTERN Tcl_Method TclOONewProcInstanceMethodEx(Tcl_Interp *interp,
Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
int flags, void **internalTokenPtr);
/* 10 */
-EXTERN Tcl_Method TclOONewProcMethodEx(Tcl_Interp *interp,
+TCLAPI Tcl_Method TclOONewProcMethodEx(Tcl_Interp *interp,
Tcl_Class clsPtr,
TclOO_PreCallProc *preCallPtr,
TclOO_PostCallProc *postCallPtr,
@@ -86,28 +73,28 @@ EXTERN Tcl_Method TclOONewProcMethodEx(Tcl_Interp *interp,
Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
int flags, void **internalTokenPtr);
/* 11 */
-EXTERN int TclOOInvokeObject(Tcl_Interp *interp,
+TCLAPI int TclOOInvokeObject(Tcl_Interp *interp,
Tcl_Object object, Tcl_Class startCls,
int publicPrivate, int objc,
Tcl_Obj *const *objv);
/* 12 */
-EXTERN void TclOOObjectSetFilters(Object *oPtr, int numFilters,
+TCLAPI void TclOOObjectSetFilters(Object *oPtr, int numFilters,
Tcl_Obj *const *filters);
/* 13 */
-EXTERN void TclOOClassSetFilters(Tcl_Interp *interp,
+TCLAPI void TclOOClassSetFilters(Tcl_Interp *interp,
Class *classPtr, int numFilters,
Tcl_Obj *const *filters);
/* 14 */
-EXTERN void TclOOObjectSetMixins(Object *oPtr, int numMixins,
+TCLAPI void TclOOObjectSetMixins(Object *oPtr, int numMixins,
Class *const *mixins);
/* 15 */
-EXTERN void TclOOClassSetMixins(Tcl_Interp *interp,
+TCLAPI void TclOOClassSetMixins(Tcl_Interp *interp,
Class *classPtr, int numMixins,
Class *const *mixins);
typedef struct TclOOIntStubs {
int magic;
- const struct TclOOIntStubHooks *hooks;
+ void *hooks;
Tcl_Object (*tclOOGetDefineCmdContext) (Tcl_Interp *interp); /* 0 */
Tcl_Method (*tclOOMakeProcInstanceMethod) (Tcl_Interp *interp, Object *oPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, const Tcl_MethodType *typePtr, ClientData clientData, Proc **procPtrPtr); /* 1 */
@@ -127,10 +114,8 @@ typedef struct TclOOIntStubs {
void (*tclOOClassSetMixins) (Tcl_Interp *interp, Class *classPtr, int numMixins, Class *const *mixins); /* 15 */
} TclOOIntStubs;
-#ifdef __cplusplus
-extern "C" {
-#endif
extern const TclOOIntStubs *tclOOIntStubsPtr;
+
#ifdef __cplusplus
}
#endif
@@ -178,7 +163,4 @@ extern const TclOOIntStubs *tclOOIntStubsPtr;
/* !END!: Do not edit above this line. */
-#undef TCL_STORAGE_CLASS
-#define TCL_STORAGE_CLASS DLLIMPORT
-
#endif /* _TCLOOINTDECLS */
diff --git a/generic/tclOOMethod.c b/generic/tclOOMethod.c
index 4e7edb8..61215de 100644
--- a/generic/tclOOMethod.c
+++ b/generic/tclOOMethod.c
@@ -3,7 +3,7 @@
*
* This file contains code to create and manage methods.
*
- * Copyright (c) 2005-2008 by Donal K. Fellows
+ * Copyright (c) 2005-2011 by Donal K. Fellows
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -513,8 +513,8 @@ TclOOMakeProcInstanceMethod(
cfPtr->data.eval.path = context.data.eval.path;
Tcl_IncrRefCount(cfPtr->data.eval.path);
- cfPtr->cmd.str.cmd = NULL;
- cfPtr->cmd.str.len = 0;
+ cfPtr->cmd = NULL;
+ cfPtr->len = 0;
hPtr = Tcl_CreateHashEntry(iPtr->linePBodyPtr,
(char *) procPtr, &isNew);
@@ -626,8 +626,8 @@ TclOOMakeProcMethod(
cfPtr->data.eval.path = context.data.eval.path;
Tcl_IncrRefCount(cfPtr->data.eval.path);
- cfPtr->cmd.str.cmd = NULL;
- cfPtr->cmd.str.len = 0;
+ cfPtr->cmd = NULL;
+ cfPtr->len = 0;
hPtr = Tcl_CreateHashEntry(iPtr->linePBodyPtr,
(char *) procPtr, &isNew);
@@ -860,7 +860,7 @@ PushMethodCallFrame(
if (pmPtr->procPtr->bodyPtr->typePtr == &tclByteCodeType) {
ByteCode *codePtr =
- pmPtr->procPtr->bodyPtr->internalRep.otherValuePtr;
+ pmPtr->procPtr->bodyPtr->internalRep.twoPtrValue.ptr1;
codePtr->nsPtr = nsPtr;
}
@@ -1204,15 +1204,6 @@ ConstructorErrorHandler(
const char *objectName, *kindName;
int objectNameLen;
- if (Tcl_GetErrorLine(interp) == (int) 0xDEADBEEF) {
- /*
- * Horrible hack to deal with certain constructors that must not add
- * information to the error trace.
- */
-
- return;
- }
-
if (mPtr->declaringObjectPtr != NULL) {
declarerPtr = mPtr->declaringObjectPtr;
kindName = "object";
@@ -1299,11 +1290,57 @@ CloneProcedureMethod(
ClientData *newClientData)
{
ProcedureMethod *pmPtr = clientData;
- ProcedureMethod *pm2Ptr = ckalloc(sizeof(ProcedureMethod));
+ ProcedureMethod *pm2Ptr;
+ Tcl_Obj *bodyObj, *argsObj;
+ CompiledLocal *localPtr;
+
+ /*
+ * Copy the argument list.
+ */
+
+ argsObj = Tcl_NewObj();
+ for (localPtr=pmPtr->procPtr->firstLocalPtr; localPtr!=NULL;
+ localPtr=localPtr->nextPtr) {
+ if (TclIsVarArgument(localPtr)) {
+ Tcl_Obj *argObj = Tcl_NewObj();
+
+ Tcl_ListObjAppendElement(NULL, argObj,
+ Tcl_NewStringObj(localPtr->name, -1));
+ if (localPtr->defValuePtr != NULL) {
+ Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr);
+ }
+ Tcl_ListObjAppendElement(NULL, argsObj, argObj);
+ }
+ }
+ /*
+ * Must strip the internal representation in order to ensure that any
+ * bound references to instance variables are removed. [Bug 3609693]
+ */
+
+ bodyObj = Tcl_DuplicateObj(pmPtr->procPtr->bodyPtr);
+ TclFreeIntRep(bodyObj);
+
+ /*
+ * Create the actual copy of the method record, manufacturing a new proc
+ * record.
+ */
+
+ pm2Ptr = ckalloc(sizeof(ProcedureMethod));
memcpy(pm2Ptr, pmPtr, sizeof(ProcedureMethod));
pm2Ptr->refCount = 1;
- pm2Ptr->procPtr->refCount++;
+ Tcl_IncrRefCount(argsObj);
+ Tcl_IncrRefCount(bodyObj);
+ if (TclCreateProc(interp, NULL, "", argsObj, bodyObj,
+ &pm2Ptr->procPtr) != TCL_OK) {
+ Tcl_DecrRefCount(argsObj);
+ Tcl_DecrRefCount(bodyObj);
+ ckfree(pm2Ptr);
+ return TCL_ERROR;
+ }
+ Tcl_DecrRefCount(argsObj);
+ Tcl_DecrRefCount(bodyObj);
+
if (pmPtr->cloneClientdataProc) {
pm2Ptr->clientData = pmPtr->cloneClientdataProc(pmPtr->clientData);
}
@@ -1338,8 +1375,8 @@ TclOONewForwardInstanceMethod(
return NULL;
}
if (prefixLen < 1) {
- Tcl_AppendResult(interp, "method forward prefix must be non-empty",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "method forward prefix must be non-empty", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_FORWARD", NULL);
return NULL;
}
@@ -1347,7 +1384,6 @@ TclOONewForwardInstanceMethod(
fmPtr = ckalloc(sizeof(ForwardMethod));
fmPtr->prefixObj = prefixObj;
Tcl_ListObjIndex(interp, prefixObj, 0, &cmdObj);
- fmPtr->fullyQualified = (strncmp(TclGetString(cmdObj), "::", 2) == 0);
Tcl_IncrRefCount(prefixObj);
return (Method *) Tcl_NewInstanceMethod(interp, (Tcl_Object) oPtr,
nameObj, flags, &fwdMethodType, fmPtr);
@@ -1380,8 +1416,8 @@ TclOONewForwardMethod(
return NULL;
}
if (prefixLen < 1) {
- Tcl_AppendResult(interp, "method forward prefix must be non-empty",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "method forward prefix must be non-empty", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_FORWARD", NULL);
return NULL;
}
@@ -1389,7 +1425,6 @@ TclOONewForwardMethod(
fmPtr = ckalloc(sizeof(ForwardMethod));
fmPtr->prefixObj = prefixObj;
Tcl_ListObjIndex(interp, prefixObj, 0, &cmdObj);
- fmPtr->fullyQualified = (strncmp(TclGetString(cmdObj), "::", 2) == 0);
Tcl_IncrRefCount(prefixObj);
return (Method *) Tcl_NewMethod(interp, (Tcl_Class) clsPtr, nameObj,
flags, &fwdMethodType, fmPtr);
@@ -1418,7 +1453,6 @@ InvokeForwardMethod(
ForwardMethod *fmPtr = clientData;
Tcl_Obj **argObjs, **prefixObjs;
int numPrefixes, len, skip = contextPtr->skip;
- Command *cmdPtr;
/*
* Build the real list of arguments to use. Note that we know that the
@@ -1430,15 +1464,10 @@ InvokeForwardMethod(
Tcl_ListObjGetElements(NULL, fmPtr->prefixObj, &numPrefixes, &prefixObjs);
argObjs = InitEnsembleRewrite(interp, objc, objv, skip,
numPrefixes, prefixObjs, &len);
-
- if (fmPtr->fullyQualified) {
- cmdPtr = NULL;
- } else {
- cmdPtr = (Command *) Tcl_FindCommand(interp, TclGetString(argObjs[0]),
- contextPtr->oPtr->namespacePtr, 0 /* normal lookup */);
- }
Tcl_NRAddCallback(interp, FinalizeForwardCall, argObjs, NULL, NULL, NULL);
- return TclNREvalObjv(interp, len, argObjs, TCL_EVAL_INVOKE, cmdPtr);
+ ((Interp *)interp)->lookupNsPtr
+ = (Namespace *) contextPtr->oPtr->namespacePtr;
+ return TclNREvalObjv(interp, len, argObjs, TCL_EVAL_NOERR, NULL);
}
static int
@@ -1483,7 +1512,6 @@ CloneForwardMethod(
ForwardMethod *fm2Ptr = ckalloc(sizeof(ForwardMethod));
fm2Ptr->prefixObj = fmPtr->prefixObj;
- fm2Ptr->fullyQualified = fmPtr->fullyQualified;
Tcl_IncrRefCount(fm2Ptr->prefixObj);
*newClientData = fm2Ptr;
return TCL_OK;
diff --git a/generic/tclOOStubLib.c b/generic/tclOOStubLib.c
index 3b6ce37..a9fa212 100644
--- a/generic/tclOOStubLib.c
+++ b/generic/tclOOStubLib.c
@@ -2,19 +2,6 @@
* ORIGINAL SOURCE: tk/generic/tkStubLib.c, version 1.9 2004/03/17
*/
-/*
- * We need to ensure that we use the tcl stub macros so that this file
- * contains no references to any of the tcl stub functions.
- */
-
-#undef USE_TCL_STUBS
-#define USE_TCL_STUBS
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#define USE_TCLOO_STUBS 1
#include "tclOOInt.h"
MODULE_SCOPE const TclOOStubs *tclOOStubsPtr;
@@ -35,50 +22,50 @@ const TclOOIntStubs *tclOOIntStubsPtr = NULL;
* to indicate that an error occurred.
*
* Side effects:
- * Sets the stub table pointer.
+ * Sets the stub table pointers.
*
*----------------------------------------------------------------------
*/
+#undef TclOOInitializeStubs
+
MODULE_SCOPE const char *
TclOOInitializeStubs(
- Tcl_Interp *interp, const char *version)
+ Tcl_Interp *interp,
+ const char *version)
{
int exact = 0;
const char *packageName = "TclOO";
const char *errMsg = NULL;
- ClientData clientData = NULL;
- const char *actualVersion =
- Tcl_PkgRequireEx(interp, packageName,version, exact, &clientData);
+ TclOOStubs *stubsPtr = NULL;
+ const char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
+ packageName, version, exact, &stubsPtr);
- if (clientData == NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "Error loading ", packageName, " package; ",
- "package not present or incomplete", NULL);
+ if (actualVersion == NULL) {
return NULL;
+ }
+ if (stubsPtr == NULL) {
+ errMsg = "missing stub table pointer";
} else {
- const TclOOStubs * const stubsPtr = clientData;
- const TclOOIntStubs * const intStubsPtr = stubsPtr->hooks ?
- stubsPtr->hooks->tclOOIntStubs : NULL;
-
- if (!actualVersion) {
- return NULL;
- }
-
- if (!stubsPtr || !intStubsPtr) {
- errMsg = "missing stub table pointer";
- goto error;
- }
-
tclOOStubsPtr = stubsPtr;
- tclOOIntStubsPtr = intStubsPtr;
+ if (stubsPtr->hooks) {
+ tclOOIntStubsPtr = stubsPtr->hooks->tclOOIntStubs;
+ } else {
+ tclOOIntStubsPtr = NULL;
+ }
return actualVersion;
-
- error:
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "Error loading ", packageName, " package",
- " (requested version '", version, "', loaded version '",
- actualVersion, "'): ", errMsg, NULL);
- return NULL;
}
+ tclStubsPtr->tcl_ResetResult(interp);
+ tclStubsPtr->tcl_AppendResult(interp, "Error loading ", packageName,
+ " (requested version ", version, ", actual version ",
+ actualVersion, "): ", errMsg, NULL);
+ return NULL;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclObj.c b/generic/tclObj.c
index 099b67d..930e1fd 100644
--- a/generic/tclObj.c
+++ b/generic/tclObj.c
@@ -97,7 +97,6 @@ typedef struct ThreadSpecificData {
static Tcl_ThreadDataKey dataKey;
-static void ContLineLocFree(char *clientData);
static void TclThreadFinalizeContLines(ClientData clientData);
static ThreadSpecificData *TclGetContLineTable(void);
@@ -208,12 +207,11 @@ static Tcl_ThreadDataKey pendingObjDataKey;
*/
static int ParseBoolean(Tcl_Obj *objPtr);
-static int SetBooleanFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int SetDoubleFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int SetIntFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static void UpdateStringOfDouble(Tcl_Obj *objPtr);
static void UpdateStringOfInt(Tcl_Obj *objPtr);
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
static void UpdateStringOfWideInt(Tcl_Obj *objPtr);
static int SetWideIntFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
#endif
@@ -250,14 +248,14 @@ static const Tcl_ObjType oldBooleanType = {
NULL, /* freeIntRepProc */
NULL, /* dupIntRepProc */
NULL, /* updateStringProc */
- SetBooleanFromAny /* setFromAnyProc */
+ TclSetBooleanFromAny /* setFromAnyProc */
};
const Tcl_ObjType tclBooleanType = {
"booleanString", /* name */
NULL, /* freeIntRepProc */
NULL, /* dupIntRepProc */
NULL, /* updateStringProc */
- SetBooleanFromAny /* setFromAnyProc */
+ TclSetBooleanFromAny /* setFromAnyProc */
};
const Tcl_ObjType tclDoubleType = {
"double", /* name */
@@ -273,7 +271,7 @@ const Tcl_ObjType tclIntType = {
UpdateStringOfInt, /* updateStringProc */
SetIntFromAny /* setFromAnyProc */
};
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
const Tcl_ObjType tclWideIntType = {
"wideInt", /* name */
NULL, /* freeIntRepProc */
@@ -411,7 +409,7 @@ TclInitObjSubsystem(void)
/* For backward compatibility only ... */
Tcl_RegisterObjType(&oldBooleanType);
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
Tcl_RegisterObjType(&tclWideIntType);
#endif
@@ -806,14 +804,7 @@ TclThreadFinalizeContLines(
for (hPtr = Tcl_FirstHashEntry(tsdPtr->lineCLPtr, &hSearch);
hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) {
- /*
- * We are not using Tcl_EventuallyFree (as in TclFreeObj()) because
- * here we can be sure that the compiler will not hold references to
- * the data in the hashtable, and using TEF might bork the
- * finalization sequence.
- */
-
- ContLineLocFree(Tcl_GetHashValue(hPtr));
+ ckfree(Tcl_GetHashValue(hPtr));
Tcl_DeleteHashEntry(hPtr);
}
Tcl_DeleteHashTable(tsdPtr->lineCLPtr);
@@ -822,30 +813,6 @@ TclThreadFinalizeContLines(
}
/*
- *----------------------------------------------------------------------
- *
- * ContLineLocFree --
- *
- * The freProc for continuation line location tables.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Releases memory.
- *
- * TIP #280
- *----------------------------------------------------------------------
- */
-
-static void
-ContLineLocFree(
- char *clientData)
-{
- ckfree(clientData);
-}
-
-/*
*--------------------------------------------------------------
*
* Tcl_RegisterObjType --
@@ -1006,7 +973,12 @@ Tcl_ConvertToType(
*/
if (typePtr->setFromAnyProc == NULL) {
- Tcl_Panic("may not convert object to type %s", typePtr->name);
+ if (interp) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't convert value to type %s", typePtr->name));
+ Tcl_SetErrorCode(interp, "TCL", "API_ABUSE", NULL);
+ }
+ return TCL_ERROR;
}
return typePtr->setFromAnyProc(interp, objPtr);
@@ -1255,7 +1227,7 @@ Tcl_DbNewObj(
* Side effects:
* tclFreeObjList, the head of the list of free Tcl_Objs, is set to the
* first of a number of free Tcl_Obj's linked together by their
- * internalRep.otherValuePtrs.
+ * internalRep.twoPtrValue.ptr1's.
*
*----------------------------------------------------------------------
*/
@@ -1284,7 +1256,7 @@ TclAllocateFreeObjects(void)
prevPtr = NULL;
objPtr = (Tcl_Obj *) basePtr;
for (i = 0; i < OBJS_TO_ALLOC_EACH_TIME; i++) {
- objPtr->internalRep.otherValuePtr = prevPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = prevPtr;
prevPtr = objPtr;
objPtr++;
}
@@ -1329,9 +1301,21 @@ TclFreeObj(
ObjInitDeletionContext(context);
+ /*
+ * Check for a double free of the same value. This is slightly tricky
+ * because it is customary to free a Tcl_Obj when its refcount falls
+ * either from 1 to 0, or from 0 to -1. Falling from -1 to -2, though,
+ * and so on, is always a sign of a botch in the caller.
+ */
if (objPtr->refCount < -1) {
Tcl_Panic("Reference count for %p was negative", objPtr);
}
+ /*
+ * Now, in case we just approved drop from 1 to 0 as acceptable, make
+ * sure we do not accept a second free when falling from 0 to -1.
+ * Skip that possibility so any double free will trigger the panic.
+ */
+ objPtr->refCount = -1;
/*
* Invalidate the string rep first so we can use the bytes value for our
@@ -1389,7 +1373,7 @@ TclFreeObj(
if (tsdPtr->lineCLPtr) {
hPtr = Tcl_FindHashEntry(tsdPtr->lineCLPtr, objPtr);
if (hPtr) {
- Tcl_EventuallyFree(Tcl_GetHashValue(hPtr), ContLineLocFree);
+ ckfree(Tcl_GetHashValue(hPtr));
Tcl_DeleteHashEntry(hPtr);
}
}
@@ -1480,7 +1464,7 @@ TclFreeObj(
if (tsdPtr->lineCLPtr) {
hPtr = Tcl_FindHashEntry(tsdPtr->lineCLPtr, objPtr);
if (hPtr) {
- Tcl_EventuallyFree(Tcl_GetHashValue(hPtr), ContLineLocFree);
+ ckfree(Tcl_GetHashValue(hPtr));
Tcl_DeleteHashEntry(hPtr);
}
}
@@ -1729,8 +1713,8 @@ Tcl_InvalidateStringRep(
*----------------------------------------------------------------------
*/
-#ifdef TCL_MEM_DEBUG
#undef Tcl_NewBooleanObj
+#ifdef TCL_MEM_DEBUG
Tcl_Obj *
Tcl_NewBooleanObj(
@@ -1778,6 +1762,7 @@ Tcl_NewBooleanObj(
*----------------------------------------------------------------------
*/
+#undef Tcl_DbNewBooleanObj
#ifdef TCL_MEM_DEBUG
Tcl_Obj *
@@ -1830,6 +1815,7 @@ Tcl_DbNewBooleanObj(
*----------------------------------------------------------------------
*/
+#undef Tcl_SetBooleanObj
void
Tcl_SetBooleanObj(
register Tcl_Obj *objPtr, /* Object whose internal rep to init. */
@@ -1897,7 +1883,7 @@ Tcl_GetBooleanFromObj(
*boolPtr = 1;
return TCL_OK;
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if (objPtr->typePtr == &tclWideIntType) {
*boolPtr = (objPtr->internalRep.wideValue != 0);
return TCL_OK;
@@ -1911,7 +1897,7 @@ Tcl_GetBooleanFromObj(
/*
*----------------------------------------------------------------------
*
- * SetBooleanFromAny --
+ * TclSetBooleanFromAny --
*
* Attempt to generate a boolean internal form for the Tcl object
* "objPtr".
@@ -1928,8 +1914,8 @@ Tcl_GetBooleanFromObj(
*----------------------------------------------------------------------
*/
-static int
-SetBooleanFromAny(
+int
+TclSetBooleanFromAny(
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
register Tcl_Obj *objPtr) /* The object to convert. */
{
@@ -1952,7 +1938,7 @@ SetBooleanFromAny(
goto badBoolean;
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if (objPtr->typePtr == &tclWideIntType) {
goto badBoolean;
}
@@ -2284,7 +2270,7 @@ Tcl_GetDoubleFromObj(
*dblPtr = TclBignumToDouble(&big);
return TCL_OK;
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if (objPtr->typePtr == &tclWideIntType) {
*dblPtr = (double) objPtr->internalRep.wideValue;
return TCL_OK;
@@ -2389,8 +2375,8 @@ UpdateStringOfDouble(
*----------------------------------------------------------------------
*/
-#ifdef TCL_MEM_DEBUG
#undef Tcl_NewIntObj
+#ifdef TCL_MEM_DEBUG
Tcl_Obj *
Tcl_NewIntObj(
@@ -2430,6 +2416,7 @@ Tcl_NewIntObj(
*----------------------------------------------------------------------
*/
+#undef Tcl_SetIntObj
void
Tcl_SetIntObj(
register Tcl_Obj *objPtr, /* Object whose internal rep to init. */
@@ -2741,7 +2728,7 @@ Tcl_GetLongFromObj(
*longPtr = objPtr->internalRep.longValue;
return TCL_OK;
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if (objPtr->typePtr == &tclWideIntType) {
/*
* We return any integer in the range -ULONG_MAX to ULONG_MAX
@@ -2799,7 +2786,7 @@ Tcl_GetLongFromObj(
return TCL_OK;
}
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
tooLarge:
#endif
if (interp != NULL) {
@@ -2815,7 +2802,7 @@ Tcl_GetLongFromObj(
TCL_PARSE_INTEGER_ONLY)==TCL_OK);
return TCL_ERROR;
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
/*
*----------------------------------------------------------------------
@@ -2857,7 +2844,7 @@ UpdateStringOfWideInt(
memcpy(objPtr->bytes, buffer, len + 1);
objPtr->length = len;
}
-#endif /* !NO_WIDE_TYPE */
+#endif /* !TCL_WIDE_INT_IS_LONG */
/*
*----------------------------------------------------------------------
@@ -3012,7 +2999,7 @@ Tcl_SetWideIntObj(
&& (wideValue <= (Tcl_WideInt) LONG_MAX)) {
TclSetLongObj(objPtr, (long) wideValue);
} else {
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
TclSetWideIntObj(objPtr, wideValue);
#else
mp_int big;
@@ -3052,7 +3039,7 @@ Tcl_GetWideIntFromObj(
/* Place to store resulting long. */
{
do {
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if (objPtr->typePtr == &tclWideIntType) {
*wideIntPtr = objPtr->internalRep.wideValue;
return TCL_OK;
@@ -3112,7 +3099,7 @@ Tcl_GetWideIntFromObj(
TCL_PARSE_INTEGER_ONLY)==TCL_OK);
return TCL_ERROR;
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
/*
*----------------------------------------------------------------------
@@ -3138,7 +3125,7 @@ SetWideIntFromAny(
Tcl_WideInt w;
return Tcl_GetWideIntFromObj(interp, objPtr, &w);
}
-#endif /* !NO_WIDE_TYPE */
+#endif /* !TCL_WIDE_INT_IS_LONG */
/*
*----------------------------------------------------------------------
@@ -3386,7 +3373,7 @@ GetBignumFromObj(
TclBNInitBignumFromLong(bignumValue, objPtr->internalRep.longValue);
return TCL_OK;
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if (objPtr->typePtr == &tclWideIntType) {
TclBNInitBignumFromWideInt(bignumValue,
objPtr->internalRep.wideValue);
@@ -3525,7 +3512,7 @@ Tcl_SetBignumObj(
return;
}
tooLargeForLong:
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if ((size_t) bignumValue->used
<= (CHAR_BIT * sizeof(Tcl_WideInt) + DIGIT_BIT - 1) / DIGIT_BIT) {
Tcl_WideUInt value = 0;
@@ -3637,7 +3624,7 @@ TclGetNumberFromObj(
*clientDataPtr = &objPtr->internalRep.longValue;
return TCL_OK;
}
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if (objPtr->typePtr == &tclWideIntType) {
*typePtr = TCL_NUMBER_WIDE;
*clientDataPtr = &objPtr->internalRep.wideValue;
@@ -4171,7 +4158,7 @@ Tcl_GetCommandFromObj(
* had is invalid one way or another.
*/
- if (tclCmdNameType.setFromAnyProc(interp, objPtr) != TCL_OK) {
+ if (SetCmdNameFromAny(interp, objPtr) != TCL_OK) {
return NULL;
}
resPtr = objPtr->internalRep.twoPtrValue.ptr1;
@@ -4390,7 +4377,7 @@ SetCmdNameFromAny(
if (cmdPtr) {
cmdPtr->refCount++;
- resPtr = objPtr->internalRep.otherValuePtr;
+ resPtr = objPtr->internalRep.twoPtrValue.ptr1;
if ((objPtr->typePtr == &tclCmdNameType)
&& resPtr && (resPtr->refCount == 1)) {
/*
@@ -4462,11 +4449,8 @@ Tcl_RepresentationCmd(
int objc,
Tcl_Obj *const objv[])
{
- char refcountBuffer[TCL_INTEGER_SPACE+1];
- char objPtrBuffer[TCL_INTEGER_SPACE+3];
- char internalRepBuffer[2*(TCL_INTEGER_SPACE+2)+2];
-#define TCLOBJ_TRUNCATE_STRINGREP 16
- char stringRepBuffer[TCLOBJ_TRUNCATE_STRINGREP+1];
+ char ptrBuffer[2*TCL_INTEGER_SPACE+6];
+ Tcl_Obj *descObj;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "value");
@@ -4479,27 +4463,30 @@ Tcl_RepresentationCmd(
* "1872361827361287"
*/
- sprintf(refcountBuffer, "%d", objv[1]->refCount);
- sprintf(objPtrBuffer, "%p", (void *)objv[1]);
- Tcl_AppendResult(interp, "value is a ", objv[1]->typePtr ?
- objv[1]->typePtr->name : "pure string", " with a refcount of ",
- refcountBuffer, ", object pointer at ", objPtrBuffer, NULL);
+ sprintf(ptrBuffer, "%p", (void *) objv[1]);
+ descObj = Tcl_ObjPrintf("value is a %s with a refcount of %d,"
+ " object pointer at %s",
+ objv[1]->typePtr ? objv[1]->typePtr->name : "pure string",
+ objv[1]->refCount, ptrBuffer);
+
if (objv[1]->typePtr) {
- sprintf(internalRepBuffer, "%p:%p",
- (void *)objv[1]->internalRep.twoPtrValue.ptr1,
- (void *)objv[1]->internalRep.twoPtrValue.ptr2);
- Tcl_AppendResult(interp, ", internal representation ",
- internalRepBuffer, NULL);
+ sprintf(ptrBuffer, "%p:%p",
+ (void *) objv[1]->internalRep.twoPtrValue.ptr1,
+ (void *) objv[1]->internalRep.twoPtrValue.ptr2);
+ Tcl_AppendPrintfToObj(descObj, ", internal representation %s",
+ ptrBuffer);
}
+
if (objv[1]->bytes) {
- strncpy(stringRepBuffer, objv[1]->bytes, TCLOBJ_TRUNCATE_STRINGREP);
- stringRepBuffer[TCLOBJ_TRUNCATE_STRINGREP] = 0;
- Tcl_AppendResult(interp, ", string representation \"",
- stringRepBuffer, objv[1]->length > TCLOBJ_TRUNCATE_STRINGREP ?
- "\"..." : "\".", NULL);
+ Tcl_AppendToObj(descObj, ", string representation \"", -1);
+ Tcl_AppendLimitedToObj(descObj, objv[1]->bytes, objv[1]->length,
+ 16, "...");
+ Tcl_AppendToObj(descObj, "\"", -1);
} else {
- Tcl_AppendResult(interp, ", no string representation.", NULL);
+ Tcl_AppendToObj(descObj, ", no string representation", -1);
}
+
+ Tcl_SetObjResult(interp, descObj);
return TCL_OK;
}
diff --git a/generic/tclOptimize.c b/generic/tclOptimize.c
new file mode 100644
index 0000000..827d89d
--- /dev/null
+++ b/generic/tclOptimize.c
@@ -0,0 +1,444 @@
+/*
+ * tclOptimize.c --
+ *
+ * This file contains the bytecode optimizer.
+ *
+ * Copyright (c) 2013 by Donal Fellows.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h"
+#include <assert.h>
+
+/*
+ * Forward declarations.
+ */
+
+static void AdvanceJumps(CompileEnv *envPtr);
+static void ConvertZeroEffectToNOP(CompileEnv *envPtr);
+static void LocateTargetAddresses(CompileEnv *envPtr,
+ Tcl_HashTable *tablePtr);
+static void TrimUnreachable(CompileEnv *envPtr);
+
+/*
+ * Helper macros.
+ */
+
+#define DefineTargetAddress(tablePtr, address) \
+ ((void) Tcl_CreateHashEntry((tablePtr), (void *) (address), &isNew))
+#define IsTargetAddress(tablePtr, address) \
+ (Tcl_FindHashEntry((tablePtr), (void *) (address)) != NULL)
+#define AddrLength(address) \
+ (tclInstructionTable[*(unsigned char *)(address)].numBytes)
+#define InstLength(instruction) \
+ (tclInstructionTable[(unsigned char)(instruction)].numBytes)
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * LocateTargetAddresses --
+ *
+ * Populate a hash table with places that we need to be careful around
+ * because they're the targets of various kinds of jumps and other
+ * non-local behavior.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+LocateTargetAddresses(
+ CompileEnv *envPtr,
+ Tcl_HashTable *tablePtr)
+{
+ unsigned char *currentInstPtr, *targetInstPtr;
+ int isNew, i;
+ Tcl_HashEntry *hPtr;
+ Tcl_HashSearch hSearch;
+
+ Tcl_InitHashTable(tablePtr, TCL_ONE_WORD_KEYS);
+
+ /*
+ * The starts of commands represent target addresses.
+ */
+
+ for (i=0 ; i<envPtr->numCommands ; i++) {
+ DefineTargetAddress(tablePtr,
+ envPtr->codeStart + envPtr->cmdMapPtr[i].codeOffset);
+ }
+
+ /*
+ * Find places where we should be careful about replacing instructions
+ * because they are the targets of various types of jumps.
+ */
+
+ for (currentInstPtr = envPtr->codeStart ;
+ currentInstPtr < envPtr->codeNext ;
+ currentInstPtr += AddrLength(currentInstPtr)) {
+ switch (*currentInstPtr) {
+ case INST_JUMP1:
+ case INST_JUMP_TRUE1:
+ case INST_JUMP_FALSE1:
+ targetInstPtr = currentInstPtr+TclGetInt1AtPtr(currentInstPtr+1);
+ goto storeTarget;
+ case INST_JUMP4:
+ case INST_JUMP_TRUE4:
+ case INST_JUMP_FALSE4:
+ case INST_START_CMD:
+ targetInstPtr = currentInstPtr+TclGetInt4AtPtr(currentInstPtr+1);
+ goto storeTarget;
+ case INST_BEGIN_CATCH4:
+ targetInstPtr = envPtr->codeStart + envPtr->exceptArrayPtr[
+ TclGetUInt4AtPtr(currentInstPtr+1)].codeOffset;
+ storeTarget:
+ DefineTargetAddress(tablePtr, targetInstPtr);
+ break;
+ case INST_JUMP_TABLE:
+ hPtr = Tcl_FirstHashEntry(
+ &JUMPTABLEINFO(envPtr, currentInstPtr+1)->hashTable,
+ &hSearch);
+ for (; hPtr ; hPtr = Tcl_NextHashEntry(&hSearch)) {
+ targetInstPtr = currentInstPtr +
+ PTR2INT(Tcl_GetHashValue(hPtr));
+ DefineTargetAddress(tablePtr, targetInstPtr);
+ }
+ break;
+ case INST_RETURN_CODE_BRANCH:
+ for (i=TCL_ERROR ; i<TCL_CONTINUE+1 ; i++) {
+ DefineTargetAddress(tablePtr, currentInstPtr + 2*i - 1);
+ }
+ break;
+ }
+ }
+
+ /*
+ * Add a marker *after* the last bytecode instruction. WARNING: points to
+ * one past the end!
+ */
+
+ DefineTargetAddress(tablePtr, currentInstPtr);
+
+ /*
+ * Enter in the targets of exception ranges.
+ */
+
+ for (i=0 ; i<envPtr->exceptArrayNext ; i++) {
+ ExceptionRange *rangePtr = &envPtr->exceptArrayPtr[i];
+
+ if (rangePtr->type == CATCH_EXCEPTION_RANGE) {
+ targetInstPtr = envPtr->codeStart + rangePtr->catchOffset;
+ DefineTargetAddress(tablePtr, targetInstPtr);
+ } else {
+ targetInstPtr = envPtr->codeStart + rangePtr->breakOffset;
+ DefineTargetAddress(tablePtr, targetInstPtr);
+ if (rangePtr->continueOffset >= 0) {
+ targetInstPtr = envPtr->codeStart + rangePtr->continueOffset;
+ DefineTargetAddress(tablePtr, targetInstPtr);
+ }
+ }
+ }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TrimUnreachable --
+ *
+ * Converts code that provably can't be executed into NOPs and reduces
+ * the overall reported length of the bytecode where that is possible.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+TrimUnreachable(
+ CompileEnv *envPtr)
+{
+ unsigned char *currentInstPtr;
+ Tcl_HashTable targets;
+
+ LocateTargetAddresses(envPtr, &targets);
+
+ for (currentInstPtr = envPtr->codeStart ;
+ currentInstPtr < envPtr->codeNext-1 ;
+ currentInstPtr += AddrLength(currentInstPtr)) {
+ int clear = 0;
+
+ if (*currentInstPtr != INST_DONE) {
+ continue;
+ }
+
+ while (!IsTargetAddress(&targets, currentInstPtr + 1 + clear)) {
+ clear += AddrLength(currentInstPtr + 1 + clear);
+ }
+ if (currentInstPtr + 1 + clear == envPtr->codeNext) {
+ envPtr->codeNext -= clear;
+ } else {
+ while (clear --> 0) {
+ *(currentInstPtr + 1 + clear) = INST_NOP;
+ }
+ }
+ }
+
+ Tcl_DeleteHashTable(&targets);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ConvertZeroEffectToNOP --
+ *
+ * Replace PUSH/POP sequences (when non-hazardous) with NOPs. Also
+ * replace PUSH empty/STR_CONCAT and TRY_CVT_NUMERIC (when followed by an
+ * operation that guarantees the check for arithmeticity) and eliminate
+ * LNOT when we can invert the following JUMP condition.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+ConvertZeroEffectToNOP(
+ CompileEnv *envPtr)
+{
+ unsigned char *currentInstPtr;
+ int size;
+ Tcl_HashTable targets;
+
+ LocateTargetAddresses(envPtr, &targets);
+ for (currentInstPtr = envPtr->codeStart ;
+ currentInstPtr < envPtr->codeNext ; currentInstPtr += size) {
+ int blank = 0, i, nextInst;
+
+ size = AddrLength(currentInstPtr);
+ while ((currentInstPtr + size < envPtr->codeNext)
+ && *(currentInstPtr+size) == INST_NOP) {
+ if (IsTargetAddress(&targets, currentInstPtr + size)) {
+ break;
+ }
+ size += InstLength(INST_NOP);
+ }
+ if (IsTargetAddress(&targets, currentInstPtr + size)) {
+ continue;
+ }
+ nextInst = *(currentInstPtr + size);
+ switch (*currentInstPtr) {
+ case INST_PUSH1:
+ if (nextInst == INST_POP) {
+ blank = size + InstLength(nextInst);
+ } else if (nextInst == INST_STR_CONCAT1
+ && TclGetUInt1AtPtr(currentInstPtr + size + 1) == 2) {
+ Tcl_Obj *litPtr = TclFetchLiteral(envPtr,
+ TclGetUInt1AtPtr(currentInstPtr + 1));
+ int numBytes;
+
+ (void) Tcl_GetStringFromObj(litPtr, &numBytes);
+ if (numBytes == 0) {
+ blank = size + InstLength(nextInst);
+ }
+ }
+ break;
+ case INST_PUSH4:
+ if (nextInst == INST_POP) {
+ blank = size + 1;
+ } else if (nextInst == INST_STR_CONCAT1
+ && TclGetUInt1AtPtr(currentInstPtr + size + 1) == 2) {
+ Tcl_Obj *litPtr = TclFetchLiteral(envPtr,
+ TclGetUInt4AtPtr(currentInstPtr + 1));
+ int numBytes;
+
+ (void) Tcl_GetStringFromObj(litPtr, &numBytes);
+ if (numBytes == 0) {
+ blank = size + InstLength(nextInst);
+ }
+ }
+ break;
+
+ case INST_LNOT:
+ switch (nextInst) {
+ case INST_JUMP_TRUE1:
+ blank = size;
+ *(currentInstPtr + size) = INST_JUMP_FALSE1;
+ break;
+ case INST_JUMP_FALSE1:
+ blank = size;
+ *(currentInstPtr + size) = INST_JUMP_TRUE1;
+ break;
+ case INST_JUMP_TRUE4:
+ blank = size;
+ *(currentInstPtr + size) = INST_JUMP_FALSE4;
+ break;
+ case INST_JUMP_FALSE4:
+ blank = size;
+ *(currentInstPtr + size) = INST_JUMP_TRUE4;
+ break;
+ }
+ break;
+
+ case INST_TRY_CVT_TO_NUMERIC:
+ switch (nextInst) {
+ case INST_JUMP_TRUE1:
+ case INST_JUMP_TRUE4:
+ case INST_JUMP_FALSE1:
+ case INST_JUMP_FALSE4:
+ case INST_INCR_SCALAR1:
+ case INST_INCR_ARRAY1:
+ case INST_INCR_ARRAY_STK:
+ case INST_INCR_SCALAR_STK:
+ case INST_INCR_STK:
+ case INST_LOR:
+ case INST_LAND:
+ case INST_EQ:
+ case INST_NEQ:
+ case INST_LT:
+ case INST_LE:
+ case INST_GT:
+ case INST_GE:
+ case INST_MOD:
+ case INST_LSHIFT:
+ case INST_RSHIFT:
+ case INST_BITOR:
+ case INST_BITXOR:
+ case INST_BITAND:
+ case INST_EXPON:
+ case INST_ADD:
+ case INST_SUB:
+ case INST_DIV:
+ case INST_MULT:
+ case INST_LNOT:
+ case INST_BITNOT:
+ case INST_UMINUS:
+ case INST_UPLUS:
+ case INST_TRY_CVT_TO_NUMERIC:
+ blank = size;
+ break;
+ }
+ break;
+ }
+
+ if (blank > 0) {
+ for (i=0 ; i<blank ; i++) {
+ *(currentInstPtr + i) = INST_NOP;
+ }
+ size = blank;
+ }
+ }
+ Tcl_DeleteHashTable(&targets);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * AdvanceJumps --
+ *
+ * Advance jumps past NOPs and chained JUMPs. After this runs, the only
+ * JUMPs that jump to a NOP or a JUMP will be length-1 ones that run out
+ * of room in their opcode to be targeted to where they really belong.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+AdvanceJumps(
+ CompileEnv *envPtr)
+{
+ unsigned char *currentInstPtr;
+ Tcl_HashTable jumps;
+
+ for (currentInstPtr = envPtr->codeStart ;
+ currentInstPtr < envPtr->codeNext-1 ;
+ currentInstPtr += AddrLength(currentInstPtr)) {
+ int offset, delta, isNew;
+
+ switch (*currentInstPtr) {
+ case INST_JUMP1:
+ case INST_JUMP_TRUE1:
+ case INST_JUMP_FALSE1:
+ offset = TclGetInt1AtPtr(currentInstPtr + 1);
+ Tcl_InitHashTable(&jumps, TCL_ONE_WORD_KEYS);
+ for (delta=0 ; offset+delta != 0 ;) {
+ if (offset + delta < -128 || offset + delta > 127) {
+ break;
+ }
+ Tcl_CreateHashEntry(&jumps, INT2PTR(offset), &isNew);
+ if (!isNew) {
+ offset = TclGetInt1AtPtr(currentInstPtr + 1);
+ break;
+ }
+ offset += delta;
+ switch (*(currentInstPtr + offset)) {
+ case INST_NOP:
+ delta = InstLength(INST_NOP);
+ continue;
+ case INST_JUMP1:
+ delta = TclGetInt1AtPtr(currentInstPtr + offset + 1);
+ continue;
+ case INST_JUMP4:
+ delta = TclGetInt4AtPtr(currentInstPtr + offset + 1);
+ continue;
+ }
+ break;
+ }
+ Tcl_DeleteHashTable(&jumps);
+ TclStoreInt1AtPtr(offset, currentInstPtr + 1);
+ continue;
+
+ case INST_JUMP4:
+ case INST_JUMP_TRUE4:
+ case INST_JUMP_FALSE4:
+ Tcl_InitHashTable(&jumps, TCL_ONE_WORD_KEYS);
+ Tcl_CreateHashEntry(&jumps, INT2PTR(0), &isNew);
+ for (offset = TclGetInt4AtPtr(currentInstPtr + 1); offset!=0 ;) {
+ Tcl_CreateHashEntry(&jumps, INT2PTR(offset), &isNew);
+ if (!isNew) {
+ offset = TclGetInt4AtPtr(currentInstPtr + 1);
+ break;
+ }
+ switch (*(currentInstPtr + offset)) {
+ case INST_NOP:
+ offset += InstLength(INST_NOP);
+ continue;
+ case INST_JUMP1:
+ offset += TclGetInt1AtPtr(currentInstPtr + offset + 1);
+ continue;
+ case INST_JUMP4:
+ offset += TclGetInt4AtPtr(currentInstPtr + offset + 1);
+ continue;
+ }
+ break;
+ }
+ Tcl_DeleteHashTable(&jumps);
+ TclStoreInt4AtPtr(offset, currentInstPtr + 1);
+ continue;
+ }
+ }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOptimizeBytecode --
+ *
+ * A very simple peephole optimizer for bytecode.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOptimizeBytecode(
+ void *envPtr)
+{
+ ConvertZeroEffectToNOP(envPtr);
+ AdvanceJumps(envPtr);
+ TrimUnreachable(envPtr);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * End:
+ */
diff --git a/generic/tclPanic.c b/generic/tclPanic.c
index 2cb8aff..2a453b9 100644
--- a/generic/tclPanic.c
+++ b/generic/tclPanic.c
@@ -14,7 +14,7 @@
*/
#include "tclInt.h"
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
MODULE_SCOPE void tclWinDebugPanic(const char *format, ...);
#endif
@@ -23,7 +23,11 @@
* procedure.
*/
+#if defined(__CYGWIN__)
+static Tcl_PanicProc *panicProc = tclWinDebugPanic;
+#else
static Tcl_PanicProc *panicProc = NULL;
+#endif
/*
*----------------------------------------------------------------------
@@ -45,9 +49,13 @@ void
Tcl_SetPanicProc(
Tcl_PanicProc *proc)
{
-#ifdef _WIN32
+#if defined(_WIN32)
/* tclWinDebugPanic only installs if there is no panicProc yet. */
if ((proc != tclWinDebugPanic) || (panicProc == NULL))
+#elif defined(__CYGWIN__)
+ if (proc == NULL)
+ panicProc = tclWinDebugPanic;
+ else
#endif
panicProc = proc;
}
@@ -98,22 +106,23 @@ Tcl_PanicVA(
arg8);
fprintf(stderr, "\n");
fflush(stderr);
- }
- /* In case the users panic proc does not abort, we do it here */
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
# if defined(__GNUC__)
- __builtin_trap();
+ __builtin_trap();
# elif defined(_WIN64)
- __debugbreak();
+ __debugbreak();
# elif defined(_MSC_VER)
- _asm {int 3}
+ _asm {int 3}
# else
- DebugBreak();
+ DebugBreak();
# endif
- ExitProcess(1);
+#endif
+#if defined(_WIN32)
+ ExitProcess(1);
#else
- abort();
+ abort();
#endif
+ }
}
/*
diff --git a/generic/tclParse.c b/generic/tclParse.c
index 2b0dab4..ee0d4c4 100644
--- a/generic/tclParse.c
+++ b/generic/tclParse.c
@@ -14,6 +14,8 @@
*/
#include "tclInt.h"
+#include "tclParse.h"
+#include <assert.h>
/*
* The following table provides parsing information about each possible 8-bit
@@ -41,18 +43,7 @@
* TYPE_BRACE - Character is a curly brace (either left or right).
*/
-#define TYPE_NORMAL 0
-#define TYPE_SPACE 0x1
-#define TYPE_COMMAND_END 0x2
-#define TYPE_SUBS 0x4
-#define TYPE_QUOTE 0x8
-#define TYPE_CLOSE_PAREN 0x10
-#define TYPE_CLOSE_BRACK 0x20
-#define TYPE_BRACE 0x40
-
-#define CHAR_TYPE(c) (charTypeTable+128)[(int)(c)]
-
-static const char charTypeTable[] = {
+const char tclCharTypeTable[] = {
/*
* Negative character values, from -128 to -1:
*/
@@ -268,7 +259,8 @@ Tcl_ParseCommand(
if ((start == NULL) && (numBytes != 0)) {
if (interp != NULL) {
- Tcl_SetResult(interp, "can't parse a NULL pointer", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "can't parse a NULL pointer", -1));
}
return TCL_ERROR;
}
@@ -578,14 +570,14 @@ Tcl_ParseCommand(
}
if (src[-1] == '"') {
if (interp != NULL) {
- Tcl_SetResult(interp, "extra characters after close-quote",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "extra characters after close-quote", -1));
}
parsePtr->errorType = TCL_PARSE_QUOTE_EXTRA;
} else {
if (interp != NULL) {
- Tcl_SetResult(interp, "extra characters after close-brace",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "extra characters after close-brace", -1));
}
parsePtr->errorType = TCL_PARSE_BRACE_EXTRA;
}
@@ -754,7 +746,7 @@ TclParseHex(
while (numBytes--) {
unsigned char digit = UCHAR(*p);
- if (!isxdigit(digit)) {
+ if (!isxdigit(digit) || (result > 0x10fff)) {
break;
}
@@ -866,7 +858,7 @@ TclParseBackslash(
result = 0xb;
break;
case 'x':
- count += TclParseHex(p+1, numBytes-2, &result);
+ count += TclParseHex(p+1, (numBytes > 3) ? 2 : numBytes-2, &result);
if (count == 2) {
/*
* No hexadigits -> This is just "x".
@@ -889,6 +881,15 @@ TclParseBackslash(
result = 'u';
}
break;
+ case 'U':
+ count += TclParseHex(p+1, (numBytes > 9) ? 8 : numBytes-2, &result);
+ if (count == 2) {
+ /*
+ * No hexadigits -> This is just "U".
+ */
+ result = 'U';
+ }
+ break;
case '\n':
count--;
do {
@@ -917,7 +918,7 @@ TclParseBackslash(
result = (result << 3) + (*p - '0');
p++;
if ((numBytes == 3) || !isdigit(UCHAR(*p)) /* INTL: digit */
- || (UCHAR(*p) >= '8')) {
+ || (UCHAR(*p) >= '8') || (result >= 0x20)) {
break;
}
count = 4;
@@ -1176,8 +1177,8 @@ ParseTokens(
}
if (numBytes == 0) {
if (parsePtr->interp != NULL) {
- Tcl_SetResult(parsePtr->interp,
- "missing close-bracket", TCL_STATIC);
+ Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj(
+ "missing close-bracket", -1));
}
parsePtr->errorType = TCL_PARSE_MISSING_BRACKET;
parsePtr->term = tokenPtr->start;
@@ -1412,8 +1413,8 @@ Tcl_ParseVarName(
}
if (numBytes == 0) {
if (parsePtr->interp != NULL) {
- Tcl_SetResult(parsePtr->interp,
- "missing close-brace for variable name", TCL_STATIC);
+ Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj(
+ "missing close-brace for variable name", -1));
}
parsePtr->errorType = TCL_PARSE_MISSING_VAR_BRACE;
parsePtr->term = tokenPtr->start-1;
@@ -1480,8 +1481,8 @@ Tcl_ParseVarName(
}
if ((parsePtr->term == src+numBytes) || (*parsePtr->term != ')')){
if (parsePtr->interp != NULL) {
- Tcl_SetResult(parsePtr->interp, "missing )",
- TCL_STATIC);
+ Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj(
+ "missing )", -1));
}
parsePtr->errorType = TCL_PARSE_MISSING_PAREN;
parsePtr->term = src;
@@ -1567,6 +1568,7 @@ Tcl_ParseVar(
code = TclSubstTokens(interp, parsePtr->tokenPtr, parsePtr->numTokens,
NULL, 1, NULL, NULL);
+ Tcl_FreeParse(parsePtr);
TclStackFree(interp, parsePtr);
if (code != TCL_OK) {
return NULL;
@@ -1577,16 +1579,13 @@ Tcl_ParseVar(
* At this point we should have an object containing the value of a
* variable. Just return the string from that object.
*
- * This should have returned the object for the user to manage, but
- * instead we have some weak reference to the string value in the object,
- * which is why we make sure the object exists after resetting the result.
- * This isn't ideal, but it's the best we can do with the current
- * documented interface. -- hobbs
+ * Since TclSubstTokens above returned TCL_OK, we know that objPtr
+ * is shared. It is in both the interp result and the value of the
+ * variable. Returning the string relies on that to be true.
*/
- if (!Tcl_IsShared(objPtr)) {
- Tcl_IncrRefCount(objPtr);
- }
+ assert( Tcl_IsShared(objPtr) );
+
Tcl_ResetResult(interp);
return TclGetString(objPtr);
}
@@ -1756,7 +1755,8 @@ Tcl_ParseBraces(
goto error;
}
- Tcl_SetResult(parsePtr->interp, "missing close-brace", TCL_STATIC);
+ Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj(
+ "missing close-brace", -1));
/*
* Guess if the problem is due to comments by searching the source string
@@ -1778,8 +1778,8 @@ Tcl_ParseBraces(
break;
case '#' :
if (openBrace && TclIsSpaceProc(src[-1])) {
- Tcl_AppendResult(parsePtr->interp,
- ": possible unbalanced brace in comment", NULL);
+ Tcl_AppendToObj(Tcl_GetObjResult(parsePtr->interp),
+ ": possible unbalanced brace in comment", -1);
goto error;
}
break;
@@ -1858,7 +1858,8 @@ Tcl_ParseQuotedString(
}
if (*parsePtr->term != '"') {
if (parsePtr->interp != NULL) {
- Tcl_SetResult(parsePtr->interp, "missing \"", TCL_STATIC);
+ Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj(
+ "missing \"", -1));
}
parsePtr->errorType = TCL_PARSE_MISSING_QUOTE;
parsePtr->term = start;
diff --git a/generic/tclParse.h b/generic/tclParse.h
new file mode 100644
index 0000000..20c609c
--- /dev/null
+++ b/generic/tclParse.h
@@ -0,0 +1,17 @@
+/*
+ * Minimal set of shared macro definitions and declarations so that multiple
+ * source files can make use of the parsing table in tclParse.c
+ */
+
+#define TYPE_NORMAL 0
+#define TYPE_SPACE 0x1
+#define TYPE_COMMAND_END 0x2
+#define TYPE_SUBS 0x4
+#define TYPE_QUOTE 0x8
+#define TYPE_CLOSE_PAREN 0x10
+#define TYPE_CLOSE_BRACK 0x20
+#define TYPE_BRACE 0x40
+
+#define CHAR_TYPE(c) (tclCharTypeTable+128)[(int)(c)]
+
+MODULE_SCOPE const char tclCharTypeTable[];
diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c
index 205c301..fe6063f 100644
--- a/generic/tclPathObj.c
+++ b/generic/tclPathObj.c
@@ -27,6 +27,8 @@ static int SetFsPathFromAny(Tcl_Interp *interp, Tcl_Obj *pathPtr);
static int FindSplitPos(const char *path, int separator);
static int IsSeparatorOrNull(int ch);
static Tcl_Obj * GetExtension(Tcl_Obj *pathPtr);
+static int MakePathFromNormalized(Tcl_Interp *interp,
+ Tcl_Obj *pathPtr);
/*
* Define the 'path' object type, which Tcl uses to represent file paths
@@ -92,9 +94,7 @@ typedef struct FsPath {
* generated during the correct filesystem
* epoch. The epoch changes when
* filesystem-mounts are changed. */
- struct FilesystemRecord *fsRecPtr;
- /* Pointer to the filesystem record entry to
- * use for this path. */
+ const Tcl_Filesystem *fsPtr;/* The Tcl_Filesystem that claims this path */
} FsPath;
/*
@@ -109,9 +109,9 @@ typedef struct FsPath {
* fields.
*/
-#define PATHOBJ(pathPtr) ((FsPath *) (pathPtr)->internalRep.otherValuePtr)
+#define PATHOBJ(pathPtr) ((FsPath *) (pathPtr)->internalRep.twoPtrValue.ptr1)
#define SETPATHOBJ(pathPtr,fsPathPtr) \
- ((pathPtr)->internalRep.otherValuePtr = (void *) (fsPathPtr))
+ ((pathPtr)->internalRep.twoPtrValue.ptr1 = (void *) (fsPathPtr))
#define PATHFLAGS(pathPtr) (PATHOBJ(pathPtr)->flags)
/*
@@ -152,14 +152,8 @@ typedef struct FsPath {
Tcl_Obj *
TclFSNormalizeAbsolutePath(
Tcl_Interp *interp, /* Interpreter to use */
- Tcl_Obj *pathPtr, /* Absolute path to normalize */
- ClientData *clientDataPtr) /* If non-NULL, then may be set to the
- * fs-specific clientData for this path. This
- * will happen when that extra information can
- * be calculated efficiently as a side-effect
- * of normalization. */
+ Tcl_Obj *pathPtr) /* Absolute path to normalize */
{
- ClientData clientData = NULL;
const char *dirSep, *oldDirSep;
int first = 1; /* Set to zero once we've passed the first
* directory separator - we can't use '..' to
@@ -269,6 +263,14 @@ TclFSNormalizeAbsolutePath(
}
if (!first || (tclPlatform == TCL_PLATFORM_UNIX)) {
linkObj = Tcl_FSLink(retVal, NULL, 0);
+
+ /* Safety check in case driver caused sharing */
+ if (Tcl_IsShared(retVal)) {
+ TclDecrRefCount(retVal);
+ retVal = Tcl_DuplicateObj(retVal);
+ Tcl_IncrRefCount(retVal);
+ }
+
if (linkObj != NULL) {
/*
* Got a link. Need to check if the link is relative
@@ -293,11 +295,6 @@ TclFSNormalizeAbsolutePath(
break;
}
}
- if (Tcl_IsShared(retVal)) {
- TclDecrRefCount(retVal);
- retVal = Tcl_DuplicateObj(retVal);
- Tcl_IncrRefCount(retVal);
- }
/*
* We want the trailing slash.
@@ -313,7 +310,12 @@ TclFSNormalizeAbsolutePath(
*/
TclDecrRefCount(retVal);
- retVal = linkObj;
+ if (Tcl_IsShared(linkObj)) {
+ retVal = Tcl_DuplicateObj(linkObj);
+ TclDecrRefCount(linkObj);
+ } else {
+ retVal = linkObj;
+ }
linkStr = Tcl_GetStringFromObj(retVal, &curLen);
/*
@@ -425,17 +427,14 @@ TclFSNormalizeAbsolutePath(
* for normalizing a path.
*/
- TclFSNormalizeToUniquePath(interp, retVal, 0, &clientData);
+ TclFSNormalizeToUniquePath(interp, retVal, 0);
/*
* Since we know it is a normalized path, we can actually convert this
* object into an FsPath for greater efficiency
*/
- TclFSMakePathFromNormalized(interp, retVal, clientData);
- if (clientDataPtr != NULL) {
- *clientDataPtr = clientData;
- }
+ MakePathFromNormalized(interp, retVal);
/*
* This has a refCount of 1 for the caller, unlike many Tcl_Obj APIs.
@@ -513,7 +512,7 @@ TclFSGetPathType(
if (PATHFLAGS(pathPtr) == 0) {
/* The path is not absolute... */
-#ifdef __WIN32__
+#ifdef _WIN32
/* ... on Windows we must make another call to determine whether
* it's relative or volumerelative [Bug 2571597]. */
return TclGetPathType(pathPtr, filesystemPtrPtr, driveNameLengthPtr,
@@ -567,8 +566,7 @@ TclPathPart(
if (pathPtr->typePtr == &tclFsPathType) {
FsPath *fsPathPtr = PATHOBJ(pathPtr);
- if (TclFSEpochOk(fsPathPtr->filesystemEpoch)
- && (PATHFLAGS(pathPtr) != 0)) {
+ if (PATHFLAGS(pathPtr) != 0) {
switch (portion) {
case TCL_PATH_DIRNAME: {
/*
@@ -830,44 +828,39 @@ Tcl_FSJoinPath(
* reference count. */
int elements) /* Number of elements to use (-1 = all) */
{
- Tcl_Obj *res;
- int i;
- const Tcl_Filesystem *fsPtr = NULL;
+ Tcl_Obj *copy, *res;
+ int objc;
+ Tcl_Obj **objv;
- if (elements < 0) {
- if (Tcl_ListObjLength(NULL, listObj, &elements) != TCL_OK) {
- return NULL;
- }
- } else {
- /*
- * Just make sure it is a valid list.
- */
-
- int listTest;
-
- if (Tcl_ListObjLength(NULL, listObj, &listTest) != TCL_OK) {
- return NULL;
- }
+ if (Tcl_ListObjLength(NULL, listObj, &objc) != TCL_OK) {
+ return NULL;
+ }
- /*
- * Correct this if it is too large, otherwise we will waste our time
- * joining null elements to the path.
- */
+ elements = ((elements >= 0) && (elements <= objc)) ? elements : objc;
+ copy = TclListObjCopy(NULL, listObj);
+ Tcl_ListObjGetElements(NULL, listObj, &objc, &objv);
+ res = TclJoinPath(elements, objv);
+ Tcl_DecrRefCount(copy);
+ return res;
+}
- if (elements > listTest) {
- elements = listTest;
- }
- }
+Tcl_Obj *
+TclJoinPath(
+ int elements,
+ Tcl_Obj * const objv[])
+{
+ Tcl_Obj *res;
+ int i;
+ const Tcl_Filesystem *fsPtr = NULL;
res = NULL;
for (i = 0; i < elements; i++) {
- Tcl_Obj *elt, *driveName = NULL;
int driveNameLength, strEltLen, length;
Tcl_PathType type;
char *strElt, *ptr;
-
- Tcl_ListObjIndex(NULL, listObj, i, &elt);
+ Tcl_Obj *driveName = NULL;
+ Tcl_Obj *elt = objv[i];
/*
* This is a special case where we can be much more efficient, where
@@ -881,9 +874,8 @@ Tcl_FSJoinPath(
if ((i == (elements-2)) && (i == 0)
&& (elt->typePtr == &tclFsPathType)
&& !((elt->bytes != NULL) && (elt->bytes[0] == '\0'))) {
- Tcl_Obj *tailObj;
+ Tcl_Obj *tailObj = objv[i+1];
- Tcl_ListObjIndex(NULL, listObj, i+1, &tailObj);
type = TclGetPathType(tailObj, NULL, NULL, NULL);
if (type == TCL_PATH_RELATIVE) {
const char *str;
@@ -1075,11 +1067,17 @@ Tcl_FSJoinPath(
if (sep != NULL) {
separator = TclGetString(sep)[0];
}
+ /* Safety check in case the VFS driver caused sharing */
+ if (Tcl_IsShared(res)) {
+ TclDecrRefCount(res);
+ res = Tcl_DuplicateObj(res);
+ Tcl_IncrRefCount(res);
+ }
}
if (length > 0 && ptr[length -1] != '/') {
Tcl_AppendToObj(res, &separator, 1);
- length++;
+ Tcl_GetStringFromObj(res, &length);
}
Tcl_SetObjLength(res, length + (int) strlen(strElt));
@@ -1158,7 +1156,7 @@ Tcl_FSConvertToPathType(
FreeFsPathInternalRep(pathPtr);
}
- return Tcl_ConvertToType(interp, pathPtr, &tclFsPathType);
+ return SetFsPathFromAny(interp, pathPtr);
/*
* We used to have more complex code here:
@@ -1266,7 +1264,6 @@ TclNewFSPathObj(
{
FsPath *fsPathPtr;
Tcl_Obj *pathPtr;
- ThreadSpecificData *tsdPtr;
const char *p;
int state = 0, count = 0;
@@ -1294,8 +1291,6 @@ TclNewFSPathObj(
return pathPtr;
}
- tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
-
pathPtr = Tcl_NewObj();
fsPathPtr = ckalloc(sizeof(FsPath));
@@ -1309,8 +1304,8 @@ TclNewFSPathObj(
fsPathPtr->cwdPtr = dirPtr;
Tcl_IncrRefCount(dirPtr);
fsPathPtr->nativePathPtr = NULL;
- fsPathPtr->fsRecPtr = NULL;
- fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch;
+ fsPathPtr->fsPtr = NULL;
+ fsPathPtr->filesystemEpoch = 0;
SETPATHOBJ(pathPtr, fsPathPtr);
PATHFLAGS(pathPtr) = TCLPATH_APPENDED;
@@ -1369,37 +1364,20 @@ AppendPath(
const char *bytes;
Tcl_Obj *copy = Tcl_DuplicateObj(head);
- bytes = Tcl_GetStringFromObj(copy, &numBytes);
-
/*
- * Should we perhaps use 'Tcl_FSPathSeparator'? But then what about the
- * Windows special case? Perhaps we should just check if cwd is a root
- * volume. We should never get numBytes == 0 in this code path.
+ * This is likely buggy when dealing with virtual filesystem drivers
+ * that use some character other than "/" as a path separator. I know
+ * of no evidence that such a foolish thing exists. This solution was
+ * chosen so that "JoinPath" operations that pass through either path
+ * intrep produce the same results; that is, bugward compatibility. If
+ * we need to fix that bug here, it needs fixing in TclJoinPath() too.
*/
-
- switch (tclPlatform) {
- case TCL_PLATFORM_UNIX:
- if (bytes[numBytes-1] != '/') {
- Tcl_AppendToObj(copy, "/", 1);
- }
- break;
-
- case TCL_PLATFORM_WINDOWS:
- /*
- * We need the extra 'numBytes != 2', and ':' checks because a volume
- * relative path doesn't get a '/'. For example 'glob C:*cat*.exe'
- * will return 'C:cat32.exe'
- */
-
- if (bytes[numBytes-1] != '/' && bytes[numBytes-1] != '\\') {
- if (numBytes!= 2 || bytes[1] != ':') {
- Tcl_AppendToObj(copy, "/", 1);
- }
- }
- break;
+ bytes = Tcl_GetStringFromObj(tail, &numBytes);
+ if (numBytes == 0) {
+ Tcl_AppendToObj(copy, "/", 1);
+ } else {
+ TclpNativeJoinPath(copy, bytes);
}
-
- Tcl_AppendObjToObj(copy, tail);
return copy;
}
@@ -1437,8 +1415,7 @@ TclFSMakePathRelative(
if (pathPtr->typePtr == &tclFsPathType) {
FsPath *fsPathPtr = PATHOBJ(pathPtr);
- if (PATHFLAGS(pathPtr) != 0
- && fsPathPtr->cwdPtr == cwdPtr) {
+ if (PATHFLAGS(pathPtr) != 0 && fsPathPtr->cwdPtr == cwdPtr) {
return fsPathPtr->normPathPtr;
}
}
@@ -1482,7 +1459,7 @@ TclFSMakePathRelative(
/*
*---------------------------------------------------------------------------
*
- * TclFSMakePathFromNormalized --
+ * MakePathFromNormalized --
*
* Like SetFsPathFromAny, but assumes the given object is an absolute
* normalized path. Only for internal use.
@@ -1496,15 +1473,12 @@ TclFSMakePathRelative(
*---------------------------------------------------------------------------
*/
-int
-TclFSMakePathFromNormalized(
+static int
+MakePathFromNormalized(
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
- Tcl_Obj *pathPtr, /* The object to convert. */
- ClientData nativeRep) /* The native rep for the object, if known
- * else NULL. */
+ Tcl_Obj *pathPtr) /* The object to convert. */
{
FsPath *fsPathPtr;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
if (pathPtr->typePtr == &tclFsPathType) {
return TCL_OK;
@@ -1518,9 +1492,8 @@ TclFSMakePathFromNormalized(
if (pathPtr->bytes == NULL) {
if (pathPtr->typePtr->updateStringProc == NULL) {
if (interp != NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "can't find object"
- "string representation", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "can't find object string representation", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "WTF",
NULL);
}
@@ -1545,9 +1518,10 @@ TclFSMakePathFromNormalized(
fsPathPtr->normPathPtr = pathPtr;
fsPathPtr->cwdPtr = NULL;
- fsPathPtr->nativePathPtr = nativeRep;
- fsPathPtr->fsRecPtr = NULL;
- fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch;
+ fsPathPtr->nativePathPtr = NULL;
+ fsPathPtr->fsPtr = NULL;
+ /* Remember the epoch under which we decided pathPtr was normalized */
+ fsPathPtr->filesystemEpoch = TclFSEpoch();
SETPATHOBJ(pathPtr, fsPathPtr);
PATHFLAGS(pathPtr) = 0;
@@ -1586,14 +1560,13 @@ Tcl_FSNewNativePath(
const Tcl_Filesystem *fromFilesystem,
ClientData clientData)
{
- Tcl_Obj *pathPtr;
+ Tcl_Obj *pathPtr = NULL;
FsPath *fsPathPtr;
- FilesystemRecord *fsFromPtr;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
- pathPtr = TclFSInternalToNormalized(fromFilesystem, clientData,
- &fsFromPtr);
+ if (fromFilesystem->internalToNormalizedProc != NULL) {
+ pathPtr = (*fromFilesystem->internalToNormalizedProc)(clientData);
+ }
if (pathPtr == NULL) {
return NULL;
}
@@ -1624,9 +1597,8 @@ Tcl_FSNewNativePath(
fsPathPtr->normPathPtr = pathPtr;
fsPathPtr->cwdPtr = NULL;
fsPathPtr->nativePathPtr = clientData;
- fsPathPtr->fsRecPtr = fsFromPtr;
- fsPathPtr->fsRecPtr->fileRefCount++;
- fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch;
+ fsPathPtr->fsPtr = fromFilesystem;
+ fsPathPtr->filesystemEpoch = TclFSEpoch();
SETPATHOBJ(pathPtr, fsPathPtr);
PATHFLAGS(pathPtr) = 0;
@@ -1684,6 +1656,12 @@ Tcl_FSGetTranslatedPath(
retObj = Tcl_FSJoinToPath(translatedCwdPtr, 1,
&srcFsPathPtr->normPathPtr);
srcFsPathPtr->translatedPathPtr = retObj;
+ if (translatedCwdPtr->typePtr == &tclFsPathType) {
+ srcFsPathPtr->filesystemEpoch
+ = PATHOBJ(translatedCwdPtr)->filesystemEpoch;
+ } else {
+ srcFsPathPtr->filesystemEpoch = 0;
+ }
Tcl_IncrRefCount(retObj);
Tcl_DecrRefCount(translatedCwdPtr);
} else {
@@ -1786,8 +1764,7 @@ Tcl_FSGetNormalizedPath(
*/
Tcl_Obj *dir, *copy;
- int cwdLen, pathType;
- ClientData clientData = NULL;
+ int tailLen, cwdLen, pathType;
pathType = Tcl_FSGetPathType(fsPathPtr->cwdPtr);
dir = Tcl_FSGetNormalizedPath(interp, fsPathPtr->cwdPtr);
@@ -1799,7 +1776,12 @@ Tcl_FSGetNormalizedPath(
UpdateStringOfFsPath(pathPtr);
}
- copy = AppendPath(dir, fsPathPtr->normPathPtr);
+ Tcl_GetStringFromObj(fsPathPtr->normPathPtr, &tailLen);
+ if (tailLen) {
+ copy = AppendPath(dir, fsPathPtr->normPathPtr);
+ } else {
+ copy = Tcl_DuplicateObj(dir);
+ }
Tcl_IncrRefCount(dir);
Tcl_IncrRefCount(copy);
@@ -1820,7 +1802,7 @@ Tcl_FSGetNormalizedPath(
* 2385549] ...
*/
- Tcl_Obj *newCopy = TclFSNormalizeAbsolutePath(interp, copy, NULL);
+ Tcl_Obj *newCopy = TclFSNormalizeAbsolutePath(interp, copy);
Tcl_DecrRefCount(copy);
copy = newCopy;
@@ -1835,8 +1817,7 @@ Tcl_FSGetNormalizedPath(
* will actually start off directly after that separator.
*/
- TclFSNormalizeToUniquePath(interp, copy, cwdLen-1,
- (fsPathPtr->nativePathPtr == NULL ? &clientData : NULL));
+ TclFSNormalizeToUniquePath(interp, copy, cwdLen-1);
}
/* Now we need to construct the new path object. */
@@ -1879,15 +1860,6 @@ Tcl_FSGetNormalizedPath(
TclDecrRefCount(dir);
}
- if (clientData != NULL) {
- /*
- * This may be unnecessary. It appears that the
- * TclFSNormalizeToUniquePath call above should have already set
- * this up. Not changing out of fear of the unknown.
- */
-
- fsPathPtr->nativePathPtr = clientData;
- }
PATHFLAGS(pathPtr) = 0;
}
@@ -1901,14 +1873,13 @@ Tcl_FSGetNormalizedPath(
UpdateStringOfFsPath(pathPtr);
}
FreeFsPathInternalRep(pathPtr);
- if (Tcl_ConvertToType(interp, pathPtr, &tclFsPathType) != TCL_OK) {
+ if (SetFsPathFromAny(interp, pathPtr) != TCL_OK) {
return NULL;
}
fsPathPtr = PATHOBJ(pathPtr);
} else if (fsPathPtr->normPathPtr == NULL) {
int cwdLen;
Tcl_Obj *copy;
- ClientData clientData = NULL;
copy = AppendPath(fsPathPtr->cwdPtr, pathPtr);
@@ -1920,17 +1891,12 @@ Tcl_FSGetNormalizedPath(
* of the previously normalized 'dir'. This should be much faster!
*/
- TclFSNormalizeToUniquePath(interp, copy, cwdLen-1,
- (fsPathPtr->nativePathPtr == NULL ? &clientData : NULL));
+ TclFSNormalizeToUniquePath(interp, copy, cwdLen-1);
fsPathPtr->normPathPtr = copy;
Tcl_IncrRefCount(fsPathPtr->normPathPtr);
- if (clientData != NULL) {
- fsPathPtr->nativePathPtr = clientData;
- }
}
}
if (fsPathPtr->normPathPtr == NULL) {
- ClientData clientData = NULL;
Tcl_Obj *useThisCwd = NULL;
int pureNormalized = 1;
@@ -1990,7 +1956,7 @@ Tcl_FSGetNormalizedPath(
/*
* We have a refCount on the cwd.
*/
-#ifdef __WIN32__
+#ifdef _WIN32
} else if (type == TCL_PATH_VOLUME_RELATIVE) {
/*
* Only Windows has volume-relative paths.
@@ -2003,7 +1969,7 @@ Tcl_FSGetNormalizedPath(
return NULL;
}
pureNormalized = 0;
-#endif /* __WIN32__ */
+#endif /* _WIN32 */
}
}
@@ -2012,12 +1978,7 @@ Tcl_FSGetNormalizedPath(
*/
fsPathPtr->normPathPtr = TclFSNormalizeAbsolutePath(interp,
- absolutePath,
- (fsPathPtr->nativePathPtr == NULL ? &clientData : NULL));
- if (0 && (clientData != NULL)) {
- fsPathPtr->nativePathPtr =
- fsPathPtr->fsRecPtr->fsPtr->dupInternalRepProc(clientData);
- }
+ absolutePath);
/*
* Check if path is pure normalized (this can only be the case if it
@@ -2108,7 +2069,7 @@ Tcl_FSGetInternalRep(
* not easily achievable with the current implementation.
*/
- if (srcFsPathPtr->fsRecPtr == NULL) {
+ if (srcFsPathPtr->fsPtr == NULL) {
/*
* This only usually happens in wrappers like TclpStat which create a
* string object and pass it to TclpObjStat. Code which calls the
@@ -2128,7 +2089,7 @@ Tcl_FSGetInternalRep(
*/
srcFsPathPtr = PATHOBJ(pathPtr);
- if (srcFsPathPtr->fsRecPtr == NULL) {
+ if (srcFsPathPtr->fsPtr == NULL) {
return NULL;
}
}
@@ -2140,7 +2101,7 @@ Tcl_FSGetInternalRep(
* for this is we ask what filesystem this path belongs to.
*/
- if (fsPtr != srcFsPathPtr->fsRecPtr->fsPtr) {
+ if (fsPtr != srcFsPathPtr->fsPtr) {
const Tcl_Filesystem *actualFs = Tcl_FSGetFileSystemForPath(pathPtr);
if (actualFs == fsPtr) {
@@ -2153,7 +2114,7 @@ Tcl_FSGetInternalRep(
Tcl_FSCreateInternalRepProc *proc;
char *nativePathPtr;
- proc = srcFsPathPtr->fsRecPtr->fsPtr->createInternalRepProc;
+ proc = srcFsPathPtr->fsPtr->createInternalRepProc;
if (proc == NULL) {
return NULL;
}
@@ -2221,8 +2182,8 @@ TclFSEnsureEpochOk(
* Check whether the object is already assigned to a fs.
*/
- if (srcFsPathPtr->fsRecPtr != NULL) {
- *fsPtrPtr = srcFsPathPtr->fsRecPtr->fsPtr;
+ if (srcFsPathPtr->fsPtr != NULL) {
+ *fsPtrPtr = srcFsPathPtr->fsPtr;
}
return TCL_OK;
}
@@ -2246,10 +2207,9 @@ TclFSEnsureEpochOk(
void
TclFSSetPathDetails(
Tcl_Obj *pathPtr,
- FilesystemRecord *fsRecPtr,
+ const Tcl_Filesystem *fsPtr,
ClientData clientData)
{
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
FsPath *srcFsPathPtr;
/*
@@ -2263,10 +2223,9 @@ TclFSSetPathDetails(
}
srcFsPathPtr = PATHOBJ(pathPtr);
- srcFsPathPtr->fsRecPtr = fsRecPtr;
+ srcFsPathPtr->fsPtr = fsPtr;
srcFsPathPtr->nativePathPtr = clientData;
- srcFsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch;
- fsRecPtr->fileRefCount++;
+ srcFsPathPtr->filesystemEpoch = TclFSEpoch();
}
/*
@@ -2355,10 +2314,6 @@ SetFsPathFromAny(
FsPath *fsPathPtr;
Tcl_Obj *transPtr;
char *name;
-#if defined(__CYGWIN__) && defined(__WIN32__)
- int copied = 0;
-#endif
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
if (pathPtr->typePtr == &tclFsPathType) {
return TCL_OK;
@@ -2385,7 +2340,6 @@ SetFsPathFromAny(
*/
if (name[0] == '~') {
- char *expandedUser;
Tcl_DString temp;
int split;
char separator = '/';
@@ -2418,9 +2372,9 @@ SetFsPathFromAny(
dir = TclGetEnv("HOME", &dirString);
if (dir == NULL) {
if (interp) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "couldn't find HOME environment "
- "variable to expand path", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "couldn't find HOME environment variable to"
+ " expand path", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH",
"HOMELESS", NULL);
}
@@ -2437,9 +2391,8 @@ SetFsPathFromAny(
Tcl_DStringInit(&temp);
if (TclpGetUserHome(name+1, &temp) == NULL) {
if (interp != NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "user \"", name+1,
- "\" doesn't exist", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "user \"%s\" doesn't exist", name+1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "NOUSER",
NULL);
}
@@ -2454,8 +2407,7 @@ SetFsPathFromAny(
}
}
- expandedUser = Tcl_DStringValue(&temp);
- transPtr = Tcl_NewStringObj(expandedUser, Tcl_DStringLength(&temp));
+ transPtr = TclDStringToObj(&temp);
if (split != len) {
/*
@@ -2500,34 +2452,9 @@ SetFsPathFromAny(
transPtr = joined;
}
}
- Tcl_DStringFree(&temp);
} else {
- transPtr = Tcl_FSJoinToPath(pathPtr, 0, NULL);
- }
-
-#if defined(__CYGWIN__) && defined(__WIN32__)
- {
- char winbuf[MAX_PATH+1];
-
- /*
- * In the Cygwin world, call conv_to_win32_path in order to use the
- * mount table to translate the file name into something Windows will
- * understand. Take care when converting empty strings!
- */
-
- name = Tcl_GetStringFromObj(transPtr, &len);
- if (len > 0) {
- cygwin_conv_to_win32_path(name, winbuf);
- TclWinNoBackslash(winbuf);
- if (Tcl_IsShared(transPtr)) {
- copied = 1;
- transPtr = Tcl_DuplicateObj(transPtr);
- Tcl_IncrRefCount(transPtr);
- }
- Tcl_SetStringObj(transPtr, winbuf, -1);
- }
+ transPtr = TclJoinPath(1, &pathPtr);
}
-#endif /* __CYGWIN__ && __WIN32__ */
/*
* Now we have a translated filename in 'transPtr'. This will have forward
@@ -2539,12 +2466,15 @@ SetFsPathFromAny(
fsPathPtr->translatedPathPtr = transPtr;
if (transPtr != pathPtr) {
Tcl_IncrRefCount(fsPathPtr->translatedPathPtr);
+ /* Redo translation when $env(HOME) changes */
+ fsPathPtr->filesystemEpoch = TclFSEpoch();
+ } else {
+ fsPathPtr->filesystemEpoch = 0;
}
fsPathPtr->normPathPtr = NULL;
fsPathPtr->cwdPtr = NULL;
fsPathPtr->nativePathPtr = NULL;
- fsPathPtr->fsRecPtr = NULL;
- fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch;
+ fsPathPtr->fsPtr = NULL;
/*
* Free old representation before installing our new one.
@@ -2554,12 +2484,6 @@ SetFsPathFromAny(
SETPATHOBJ(pathPtr, fsPathPtr);
PATHFLAGS(pathPtr) = 0;
pathPtr->typePtr = &tclFsPathType;
-#if defined(__CYGWIN__) && defined(__WIN32__)
- if (copied) {
- Tcl_DecrRefCount(transPtr);
- }
-#endif
-
return TCL_OK;
}
@@ -2583,25 +2507,15 @@ FreeFsPathInternalRep(
if (fsPathPtr->cwdPtr != NULL) {
TclDecrRefCount(fsPathPtr->cwdPtr);
}
- if (fsPathPtr->nativePathPtr != NULL && fsPathPtr->fsRecPtr != NULL) {
+ if (fsPathPtr->nativePathPtr != NULL && fsPathPtr->fsPtr != NULL) {
Tcl_FSFreeInternalRepProc *freeProc =
- fsPathPtr->fsRecPtr->fsPtr->freeInternalRepProc;
+ fsPathPtr->fsPtr->freeInternalRepProc;
if (freeProc != NULL) {
freeProc(fsPathPtr->nativePathPtr);
fsPathPtr->nativePathPtr = NULL;
}
}
- if (fsPathPtr->fsRecPtr != NULL) {
- fsPathPtr->fsRecPtr->fileRefCount--;
- if (fsPathPtr->fsRecPtr->fileRefCount <= 0) {
- /*
- * It has been unregistered already.
- */
-
- ckfree(fsPathPtr->fsRecPtr);
- }
- }
ckfree(fsPathPtr);
pathPtr->typePtr = NULL;
@@ -2644,10 +2558,10 @@ DupFsPathInternalRep(
copyFsPathPtr->flags = srcFsPathPtr->flags;
- if (srcFsPathPtr->fsRecPtr != NULL
+ if (srcFsPathPtr->fsPtr != NULL
&& srcFsPathPtr->nativePathPtr != NULL) {
Tcl_FSDupInternalRepProc *dupProc =
- srcFsPathPtr->fsRecPtr->fsPtr->dupInternalRepProc;
+ srcFsPathPtr->fsPtr->dupInternalRepProc;
if (dupProc != NULL) {
copyFsPathPtr->nativePathPtr =
@@ -2658,11 +2572,8 @@ DupFsPathInternalRep(
} else {
copyFsPathPtr->nativePathPtr = NULL;
}
- copyFsPathPtr->fsRecPtr = srcFsPathPtr->fsRecPtr;
+ copyFsPathPtr->fsPtr = srcFsPathPtr->fsPtr;
copyFsPathPtr->filesystemEpoch = srcFsPathPtr->filesystemEpoch;
- if (copyFsPathPtr->fsRecPtr != NULL) {
- copyFsPathPtr->fsRecPtr->fileRefCount++;
- }
copyPtr->typePtr = &tclFsPathType;
}
diff --git a/generic/tclPipe.c b/generic/tclPipe.c
index 5f59c38..83fb818 100644
--- a/generic/tclPipe.c
+++ b/generic/tclPipe.c
@@ -106,9 +106,10 @@ FileForRedirect(
if (msg) {
Tcl_SetObjResult(interp, msg);
} else {
- Tcl_AppendResult(interp, "channel \"",
- Tcl_GetChannelName(chan), "\" wasn't opened for ",
- ((writing) ? "writing" : "reading"), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "channel \"%s\" wasn't opened for %s",
+ Tcl_GetChannelName(chan),
+ ((writing) ? "writing" : "reading")));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
"BADCHAN", NULL);
}
@@ -141,9 +142,10 @@ FileForRedirect(
file = TclpOpenFile(name, flags);
Tcl_DStringFree(&nameString);
if (file == NULL) {
- Tcl_AppendResult(interp, "couldn't ",
- ((writing) ? "write" : "read"), " file \"", spec, "\": ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't %s file \"%s\": %s",
+ (writing ? "write" : "read"), spec,
+ Tcl_PosixError(interp)));
return NULL;
}
*closePtr = 1;
@@ -151,8 +153,8 @@ FileForRedirect(
return file;
badLastArg:
- Tcl_AppendResult(interp, "can't specify \"", arg,
- "\" as last word in command", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't specify \"%s\" as last word in command", arg));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "SYNTAX", NULL);
return NULL;
}
@@ -284,7 +286,7 @@ TclCleanupChildren(
for (i = 0; i < numPids; i++) {
/*
* We need to get the resolved pid before we wait on it as the windows
- * implimentation of Tcl_WaitPid deletes the information such that any
+ * implementation of Tcl_WaitPid deletes the information such that any
* following calls to TclpGetPid fail.
*/
@@ -304,8 +306,8 @@ TclCleanupChildren(
msg =
"child process lost (is SIGCHLD ignored or trapped?)";
}
- Tcl_AppendResult(interp, "error waiting for process to exit: ",
- msg, NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error waiting for process to exit: %s", msg));
}
continue;
}
@@ -335,16 +337,17 @@ TclCleanupChildren(
p = Tcl_SignalMsg(WTERMSIG(waitStatus));
Tcl_SetErrorCode(interp, "CHILDKILLED", msg1,
Tcl_SignalId(WTERMSIG(waitStatus)), p, NULL);
- Tcl_AppendResult(interp, "child killed: ", p, "\n", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "child killed: %s\n", p));
} else if (WIFSTOPPED(waitStatus)) {
p = Tcl_SignalMsg(WSTOPSIG(waitStatus));
Tcl_SetErrorCode(interp, "CHILDSUSP", msg1,
Tcl_SignalId(WSTOPSIG(waitStatus)), p, NULL);
- Tcl_AppendResult(interp, "child suspended: ", p, "\n",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "child suspended: %s\n", p));
} else {
- Tcl_AppendResult(interp,
- "child wait status didn't make sense\n", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "child wait status didn't make sense\n", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
"ODDWAITRESULT", msg1, NULL);
}
@@ -374,8 +377,9 @@ TclCleanupChildren(
result = TCL_ERROR;
Tcl_DecrRefCount(objPtr);
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "error reading stderr output file: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error reading stderr output file: %s",
+ Tcl_PosixError(interp)));
} else if (count > 0) {
anyErrorInfo = 1;
Tcl_SetObjResult(interp, objPtr);
@@ -393,7 +397,8 @@ TclCleanupChildren(
*/
if ((abnormalExit != 0) && (anyErrorInfo == 0) && (interp != NULL)) {
- Tcl_AppendResult(interp, "child process exited abnormally", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "child process exited abnormally", -1));
}
return result;
}
@@ -542,8 +547,8 @@ TclCreatePipeline(
}
if (*p == '\0') {
if ((i == (lastBar + 1)) || (i == (argc - 1))) {
- Tcl_SetResult(interp, "illegal use of | or |& in command",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "illegal use of | or |& in command", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
"PIPESYNTAX", NULL);
goto error;
@@ -570,8 +575,9 @@ TclCreatePipeline(
if (*inputLiteral == '\0') {
inputLiteral = ((i + 1) == argc) ? NULL : argv[i + 1];
if (inputLiteral == NULL) {
- Tcl_AppendResult(interp, "can't specify \"", argv[i],
- "\" as last word in command", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't specify \"%s\" as last word in command",
+ argv[i]));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
"PIPESYNTAX", NULL);
goto error;
@@ -680,8 +686,9 @@ TclCreatePipeline(
*/
if (i != argc-1) {
- Tcl_AppendResult(interp, "must specify \"", argv[i],
- "\" as last word in command", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "must specify \"%s\" as last word in command",
+ argv[i]));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
"PIPESYNTAX", NULL);
goto error;
@@ -722,8 +729,8 @@ TclCreatePipeline(
* We had a bar followed only by redirections.
*/
- Tcl_SetResult(interp, "illegal use of | or |& in command",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "illegal use of | or |& in command", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "PIPESYNTAX",
NULL);
goto error;
@@ -739,9 +746,9 @@ TclCreatePipeline(
inputFile = TclpCreateTempFile(inputLiteral);
if (inputFile == NULL) {
- Tcl_AppendResult(interp,
- "couldn't create input file for command: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't create input file for command: %s",
+ Tcl_PosixError(interp)));
goto error;
}
inputClose = 1;
@@ -752,9 +759,9 @@ TclCreatePipeline(
*/
if (TclpCreatePipe(&inputFile, inPipePtr) == 0) {
- Tcl_AppendResult(interp,
- "couldn't create input pipe for command: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't create input pipe for command: %s",
+ Tcl_PosixError(interp)));
goto error;
}
inputClose = 1;
@@ -781,9 +788,9 @@ TclCreatePipeline(
*/
if (TclpCreatePipe(outPipePtr, &outputFile) == 0) {
- Tcl_AppendResult(interp,
- "couldn't create output pipe for command: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't create output pipe for command: %s",
+ Tcl_PosixError(interp)));
goto error;
}
outputClose = 1;
@@ -821,9 +828,9 @@ TclCreatePipeline(
errorFile = TclpCreateTempFile(NULL);
if (errorFile == NULL) {
- Tcl_AppendResult(interp,
- "couldn't create error file for command: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't create error file for command: %s",
+ Tcl_PosixError(interp)));
goto error;
}
*errFilePtr = errorFile;
@@ -894,8 +901,8 @@ TclCreatePipeline(
} else {
argv[lastArg] = NULL;
if (TclpCreatePipe(&pipeIn, &curOutFile) == 0) {
- Tcl_AppendResult(interp, "couldn't create pipe: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't create pipe: %s", Tcl_PosixError(interp)));
goto error;
}
}
@@ -1074,15 +1081,17 @@ Tcl_OpenCommandChannel(
if (flags & TCL_ENFORCE_MODE) {
if ((flags & TCL_STDOUT) && (outPipe == NULL)) {
- Tcl_AppendResult(interp, "can't read output from command:"
- " standard output was redirected", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "can't read output from command:"
+ " standard output was redirected", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
"BADREDIRECT", NULL);
goto error;
}
if ((flags & TCL_STDIN) && (inPipe == NULL)) {
- Tcl_AppendResult(interp, "can't write input to command:"
- " standard input was redirected", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "can't write input to command:"
+ " standard input was redirected", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
"BADREDIRECT", NULL);
goto error;
@@ -1093,8 +1102,8 @@ Tcl_OpenCommandChannel(
numPids, pidPtr);
if (channel == NULL) {
- Tcl_AppendResult(interp, "pipe for command could not be created",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "pipe for command could not be created", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "NOPIPE", NULL);
goto error;
}
diff --git a/generic/tclPkg.c b/generic/tclPkg.c
index fdaea57..df90cea 100644
--- a/generic/tclPkg.c
+++ b/generic/tclPkg.c
@@ -106,6 +106,7 @@ static const char * PkgRequireCore(Tcl_Interp *interp, const char *name,
*----------------------------------------------------------------------
*/
+#undef Tcl_PkgProvide
int
Tcl_PkgProvide(
Tcl_Interp *interp, /* Interpreter in which package is now
@@ -154,8 +155,9 @@ Tcl_PkgProvideEx(
}
return TCL_OK;
}
- Tcl_AppendResult(interp, "conflicting versions provided for package \"",
- name, "\": ", pkgPtr->version, ", then ", version, NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "conflicting versions provided for package \"%s\": %s, then %s",
+ name, pkgPtr->version, version));
Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "VERSIONCONFLICT", NULL);
return TCL_ERROR;
}
@@ -187,6 +189,7 @@ Tcl_PkgProvideEx(
*----------------------------------------------------------------------
*/
+#undef Tcl_PkgRequire
const char *
Tcl_PkgRequire(
Tcl_Interp *interp, /* Interpreter in which package is now
@@ -284,9 +287,9 @@ Tcl_PkgRequireEx(
*/
tclEmptyStringRep = &tclEmptyString;
- Tcl_AppendResult(interp, "Cannot load package \"", name,
- "\" in standalone executable: This package is not "
- "compiled with stub support", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "Cannot load package \"%s\" in standalone executable:"
+ " This package is not compiled with stub support", name));
Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNSTUBBED", NULL);
return NULL;
}
@@ -355,6 +358,10 @@ PkgRequireCore(
char *script, *pkgVersionI;
Tcl_DString command;
+ if (TCL_OK != CheckAllRequirements(interp, reqc, reqv)) {
+ return NULL;
+ }
+
/*
* 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
@@ -374,9 +381,10 @@ PkgRequireCore(
*/
if (pkgPtr->clientData != NULL) {
- Tcl_AppendResult(interp, "circular package dependency: "
- "attempt to provide ", name, " ",
- (char *) pkgPtr->clientData, " requires ", name, 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 NULL;
@@ -494,10 +502,10 @@ PkgRequireCore(
Tcl_ResetResult(interp);
if (pkgPtr->version == NULL) {
code = TCL_ERROR;
- Tcl_AppendResult(interp, "attempt to provide package ",
- name, " ", versionToProvide,
- " failed: no version of package ", name,
- " provided", NULL);
+ 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 {
@@ -517,11 +525,11 @@ PkgRequireCore(
ckfree(vi);
if (res != 0) {
code = TCL_ERROR;
- Tcl_AppendResult(interp,
- "attempt to provide package ", name, " ",
- versionToProvide, " failed: package ",
- name, " ", pkgPtr->version,
- " provided instead", NULL);
+ 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);
}
@@ -530,10 +538,10 @@ PkgRequireCore(
} else if (code != TCL_ERROR) {
Tcl_Obj *codePtr = Tcl_NewIntObj(code);
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "attempt to provide package ", name,
- " ", versionToProvide, " failed: bad return code: ",
- TclGetString(codePtr), NULL);
+ 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;
@@ -591,13 +599,9 @@ PkgRequireCore(
Tcl_DStringFree(&command);
if ((code != TCL_OK) && (code != TCL_ERROR)) {
- Tcl_Obj *codePtr = Tcl_NewIntObj(code);
-
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad return code: ",
- TclGetString(codePtr), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad return code: %d", code));
Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
- Tcl_DecrRefCount(codePtr);
code = TCL_ERROR;
}
if (code == TCL_ERROR) {
@@ -610,7 +614,8 @@ PkgRequireCore(
}
if (pkgPtr->version == NULL) {
- Tcl_AppendResult(interp, "can't find package ", name, 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;
@@ -628,8 +633,9 @@ PkgRequireCore(
ckfree(pkgVersionI);
if (!satisfies) {
- Tcl_AppendResult(interp, "version conflict for package \"", name,
- "\": have ", pkgPtr->version, ", need", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "version conflict for package \"%s\": have %s, need",
+ name, pkgPtr->version));
Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "VERSIONCONFLICT",
NULL);
AddRequirementsToResult(interp, reqc, reqv);
@@ -666,6 +672,7 @@ PkgRequireCore(
*----------------------------------------------------------------------
*/
+#undef Tcl_PkgPresent
const char *
Tcl_PkgPresent(
Tcl_Interp *interp, /* Interpreter in which package is now
@@ -721,10 +728,11 @@ Tcl_PkgPresentEx(
}
if (version != NULL) {
- Tcl_AppendResult(interp, "package ", name, " ", version,
- " is not present", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "package %s %s is not present", name, version));
} else {
- Tcl_AppendResult(interp, "package ", name, " is not present", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "package %s is not present", name));
}
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PACKAGE", name, NULL);
return NULL;
@@ -850,7 +858,8 @@ Tcl_PackageObjCmd(
if (res == 0){
if (objc == 4) {
ckfree(argv3i);
- Tcl_SetResult(interp, availPtr->script, TCL_VOLATILE);
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj(availPtr->script, -1));
return TCL_OK;
}
Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC);
@@ -940,7 +949,7 @@ Tcl_PackageObjCmd(
version = TclGetString(objv[3]);
}
}
- Tcl_PkgPresent(interp, name, version, exact);
+ Tcl_PkgPresentEx(interp, name, version, exact, NULL);
return TCL_ERROR;
break;
}
@@ -955,7 +964,8 @@ Tcl_PackageObjCmd(
if (hPtr != NULL) {
pkgPtr = Tcl_GetHashValue(hPtr);
if (pkgPtr->version != NULL) {
- Tcl_SetResult(interp, pkgPtr->version, TCL_VOLATILE);
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj(pkgPtr->version, -1));
}
}
return TCL_OK;
@@ -964,7 +974,7 @@ Tcl_PackageObjCmd(
if (CheckVersionAndConvert(interp, argv3, NULL, NULL) != TCL_OK) {
return TCL_ERROR;
}
- return Tcl_PkgProvide(interp, argv2, argv3);
+ return Tcl_PkgProvideEx(interp, argv2, argv3, NULL);
case PKG_REQUIRE:
require:
if (objc < 3) {
@@ -1017,7 +1027,8 @@ Tcl_PackageObjCmd(
if (objc == 2) {
if (iPtr->packageUnknown != NULL) {
- Tcl_SetResult(interp, iPtr->packageUnknown, TCL_VOLATILE);
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj(iPtr->packageUnknown, -1));
}
} else if (objc == 3) {
if (iPtr->packageUnknown != NULL) {
@@ -1351,8 +1362,8 @@ CheckVersionAndConvert(
error:
ckfree(ibuf);
- Tcl_AppendResult(interp, "expected version number but got \"", string,
- "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "expected version number but got \"%s\"", string));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "VERSION", NULL);
return TCL_ERROR;
}
@@ -1614,8 +1625,8 @@ CheckRequirement(
* More dashes found after the first. This is wrong.
*/
- Tcl_AppendResult(interp, "expected versionMin-versionMax but got \"",
- string, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "expected versionMin-versionMax but got \"%s\"", string));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "VERSIONRANGE", NULL);
return TCL_ERROR;
}
@@ -1667,19 +1678,17 @@ AddRequirementsToResult(
Tcl_Obj *const reqv[]) /* 0 means to use the latest version
* available. */
{
- if (reqc > 0) {
- int i;
+ Tcl_Obj *result = Tcl_GetObjResult(interp);
+ int i, length;
- for (i = 0; i < reqc; i++) {
- int length;
- const char *v = Tcl_GetStringFromObj(reqv[i], &length);
+ for (i = 0; i < reqc; i++) {
+ const char *v = Tcl_GetStringFromObj(reqv[i], &length);
- if ((length & 0x1) && (v[length/2] == '-')
- && (strncmp(v, v+((length+1)/2), length/2) == 0)) {
- Tcl_AppendResult(interp, " exactly ", v+((length+1)/2), NULL);
- } else {
- Tcl_AppendResult(interp, " ", v, NULL);
- }
+ if ((length & 0x1) && (v[length/2] == '-')
+ && (strncmp(v, v+((length+1)/2), length/2) == 0)) {
+ Tcl_AppendPrintfToObj(result, " exactly %s", v+((length+1)/2));
+ } else {
+ Tcl_AppendPrintfToObj(result, " %s", v);
}
}
}
@@ -1708,15 +1717,15 @@ AddRequirementsToDString(
Tcl_Obj *const reqv[]) /* 0 means to use the latest version
* available. */
{
- if (reqc > 0) {
- int i;
+ int i;
+ if (reqc > 0) {
for (i = 0; i < reqc; i++) {
- Tcl_DStringAppend(dsPtr, " ", 1);
- Tcl_DStringAppend(dsPtr, TclGetString(reqv[i]), -1);
+ TclDStringAppendLiteral(dsPtr, " ");
+ TclDStringAppendObj(dsPtr, reqv[i]);
}
} else {
- Tcl_DStringAppend(dsPtr, " 0-", -1);
+ TclDStringAppendLiteral(dsPtr, " 0-");
}
}
diff --git a/generic/tclPkgConfig.c b/generic/tclPkgConfig.c
index 5907a03..466d535 100644
--- a/generic/tclPkgConfig.c
+++ b/generic/tclPkgConfig.c
@@ -22,7 +22,7 @@
* - TCL_COMPILE_STATS OSCMa bytecode compiler statistics.
*
* - TCL_CFG_DO64BIT NSCMdt tcl is compiled for a 64bit system.
- * - TCL_CFG_DEBUG NSCMdt tcl is compiled with symbol info on.
+ * - NDEBUG NSCMdt tcl is compiled with symbol info off.
* - TCL_CFG_OPTIMIZED NSCMdt tcl is compiled with cc optimizations on
* - TCL_CFG_PROFILED NSCMdt tcl is compiled with profiling info.
*
@@ -70,7 +70,7 @@
# define CFG_64 "0"
#endif
-#ifdef TCL_CFG_DEBUG
+#ifndef NDEBUG
# define CFG_DEBUG "1"
#else
# define CFG_DEBUG "0"
diff --git a/generic/tclPlatDecls.h b/generic/tclPlatDecls.h
index 77678be..abc8ee8 100644
--- a/generic/tclPlatDecls.h
+++ b/generic/tclPlatDecls.h
@@ -31,7 +31,7 @@
* TCHAR is needed here for win32, so if it is not defined yet do it here.
* This way, we don't need to include <tchar.h> just for one define.
*/
-#if defined(_WIN32) && !defined(_TCHAR_DEFINED)
+#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(_TCHAR_DEFINED)
# if defined(_UNICODE)
typedef wchar_t TCHAR;
# else
@@ -42,11 +42,15 @@
/* !BEGIN!: Do not edit below this line. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Exported function declarations:
*/
-#ifdef __WIN32__ /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
/* 0 */
EXTERN TCHAR * Tcl_WinUtfToTChar(const char *str, int len,
Tcl_DString *dsPtr);
@@ -69,9 +73,9 @@ EXTERN int Tcl_MacOSXOpenVersionedBundleResources(
typedef struct TclPlatStubs {
int magic;
- const struct TclPlatStubHooks *hooks;
+ void *hooks;
-#ifdef __WIN32__ /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
TCHAR * (*tcl_WinUtfToTChar) (const char *str, int len, Tcl_DString *dsPtr); /* 0 */
char * (*tcl_WinTCharToUtf) (const TCHAR *str, int len, Tcl_DString *dsPtr); /* 1 */
#endif /* WIN */
@@ -81,10 +85,8 @@ typedef struct TclPlatStubs {
#endif /* MACOSX */
} TclPlatStubs;
-#ifdef __cplusplus
-extern "C" {
-#endif
extern const TclPlatStubs *tclPlatStubsPtr;
+
#ifdef __cplusplus
}
#endif
@@ -95,7 +97,7 @@ extern const TclPlatStubs *tclPlatStubsPtr;
* Inline function declarations:
*/
-#ifdef __WIN32__ /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
#define Tcl_WinUtfToTChar \
(tclPlatStubsPtr->tcl_WinUtfToTChar) /* 0 */
#define Tcl_WinTCharToUtf \
diff --git a/generic/tclPort.h b/generic/tclPort.h
index 23c6191..12a60db 100644
--- a/generic/tclPort.h
+++ b/generic/tclPort.h
@@ -19,21 +19,10 @@
#endif
#if defined(_WIN32)
# include "tclWinPort.h"
-#endif
-#include "tcl.h"
-#if !defined(_WIN32)
+#else
# include "tclUnixPort.h"
#endif
-
-#if defined(__CYGWIN__)
-# define USE_PUTENV 1
-# define USE_PUTENV_FOR_UNSET 1
-/* On Cygwin, the environment is imported from the Cygwin DLL. */
- DLLIMPORT extern char **__cygwin_environ;
- DLLIMPORT extern int cygwin_conv_to_win32_path(const char *, char *);
-# define environ __cygwin_environ
-# define timezone _timezone
-#endif
+#include "tcl.h"
#if !defined(LLONG_MIN)
# ifdef TCL_WIDE_INT_IS_LONG
diff --git a/generic/tclProc.c b/generic/tclProc.c
index 50cf0f7..ce1c767 100644
--- a/generic/tclProc.c
+++ b/generic/tclProc.c
@@ -152,22 +152,24 @@ Tcl_ProcObjCmd(
&nsPtr, &altNsPtr, &cxtNsPtr, &procName);
if (nsPtr == NULL) {
- Tcl_AppendResult(interp, "can't create procedure \"", fullName,
- "\": unknown namespace", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't create procedure \"%s\": unknown namespace",
+ fullName));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL);
return TCL_ERROR;
}
if (procName == NULL) {
- Tcl_AppendResult(interp, "can't create procedure \"", fullName,
- "\": bad procedure name", 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_AppendResult(interp, "can't create procedure \"", procName,
- "\" in non-global namespace with name starting with \":\"",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't create procedure \"%s\" in non-global namespace with"
+ " name starting with \":\"", procName));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL);
return TCL_ERROR;
}
@@ -194,7 +196,7 @@ Tcl_ProcObjCmd(
Tcl_DStringInit(&ds);
if (nsPtr != iPtr->globalNsPtr) {
Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
- Tcl_DStringAppend(&ds, "::", 2);
+ TclDStringAppendLiteral(&ds, "::");
}
Tcl_DStringAppend(&ds, procName, -1);
@@ -269,8 +271,8 @@ Tcl_ProcObjCmd(
cfPtr->data.eval.path = contextPtr->data.eval.path;
Tcl_IncrRefCount(cfPtr->data.eval.path);
- cfPtr->cmd.str.cmd = NULL;
- cfPtr->cmd.str.len = 0;
+ cfPtr->cmd = NULL;
+ cfPtr->len = 0;
hePtr = Tcl_CreateHashEntry(iPtr->linePBodyPtr,
procPtr, &isNew);
@@ -419,7 +421,7 @@ TclCreateProc(
* will be holding a reference to it.
*/
- procPtr = bodyPtr->internalRep.otherValuePtr;
+ procPtr = bodyPtr->internalRep.twoPtrValue.ptr1;
procPtr->iPtr = iPtr;
procPtr->refCount++;
precompiled = 1;
@@ -518,16 +520,17 @@ TclCreateProc(
}
if (fieldCount > 2) {
ckfree(fieldValues);
- Tcl_AppendResult(interp,
- "too many fields in argument specifier \"",
- argArray[i], "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "too many fields in argument specifier \"%s\"",
+ argArray[i]));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
"FORMALARGUMENTFORMAT", NULL);
goto procError;
}
if ((fieldCount == 0) || (*fieldValues[0] == 0)) {
ckfree(fieldValues);
- Tcl_AppendResult(interp, "argument with no name", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "argument with no name", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
"FORMALARGUMENTFORMAT", NULL);
goto procError;
@@ -553,16 +556,18 @@ TclCreateProc(
} while (*q != '\0');
q--;
if (*q == ')') { /* We have an array element. */
- Tcl_AppendResult(interp, "formal parameter \"",
- fieldValues[0], "\" is an array element", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "formal parameter \"%s\" is an array element",
+ fieldValues[0]));
ckfree(fieldValues);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
"FORMALARGUMENTFORMAT", NULL);
goto procError;
}
} else if ((*p == ':') && (*(p+1) == ':')) {
- Tcl_AppendResult(interp, "formal parameter \"",
- fieldValues[0], "\" is not a simple name", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "formal parameter \"%s\" is not a simple name",
+ fieldValues[0]));
ckfree(fieldValues);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
"FORMALARGUMENTFORMAT", NULL);
@@ -767,8 +772,7 @@ TclGetFrame(
return result;
levelError:
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad level \"", name, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad level \"%s\"", name));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "STACKLEVEL", NULL);
return -1;
}
@@ -833,7 +837,7 @@ TclObjGetFrame(
}
/* TODO: Consider skipping the typePtr checks */
} else if (objPtr->typePtr == &tclIntType
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
|| objPtr->typePtr == &tclWideIntType
#endif
) {
@@ -900,8 +904,7 @@ TclObjGetFrame(
return result;
levelError:
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad level \"", name, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad level \"%s\"", name));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "STACKLEVEL", NULL);
return -1;
}
@@ -1120,6 +1123,8 @@ ProcWrongNumArgs(
if (framePtr->isProcCallFrame & FRAME_IS_LAMBDA) {
desiredObjs[0] = Tcl_NewStringObj("lambdaExpr", -1);
} else {
+ ((Interp *) interp)->ensembleRewrite.numInsertedObjs -= skip - 1;
+
#ifdef AVOID_HACKS_FOR_ITCL
desiredObjs[0] = framePtr->objv[skip-1];
#else
@@ -1192,7 +1197,7 @@ TclInitCompiledLocals(
if (bodyPtr->typePtr != &tclByteCodeType) {
Tcl_Panic("body object for proc attached to frame is not a byte code type");
}
- codePtr = bodyPtr->internalRep.otherValuePtr;
+ codePtr = bodyPtr->internalRep.twoPtrValue.ptr1;
if (framePtr->numCompiledLocals) {
if (!codePtr->localCachePtr) {
@@ -1342,17 +1347,9 @@ TclFreeLocalCache(
for (i = 0; i < localCachePtr->numVars; i++, namePtrPtr++) {
register Tcl_Obj *objPtr = *namePtrPtr;
- /*
- * Note that this can be called with interp==NULL, on interp deletion.
- * In that case, the literal table and objects go away on their own.
- */
-
if (objPtr) {
- if (interp) {
- TclReleaseLiteral(interp, objPtr);
- } else {
- Tcl_DecrRefCount(objPtr);
- }
+ /* TclReleaseLiteral calls Tcl_DecrRefCount for us */
+ TclReleaseLiteral(interp, objPtr);
}
}
ckfree(localCachePtr);
@@ -1363,7 +1360,7 @@ InitLocalCache(
Proc *procPtr)
{
Interp *iPtr = procPtr->iPtr;
- ByteCode *codePtr = procPtr->bodyPtr->internalRep.otherValuePtr;
+ ByteCode *codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1;
int localCt = procPtr->numCompiledLocals;
int numArgs = procPtr->numArgs, i = 0;
@@ -1440,7 +1437,7 @@ InitArgsAndLocals(
{
CallFrame *framePtr = ((Interp *)interp)->varFramePtr;
register Proc *procPtr = framePtr->procPtr;
- ByteCode *codePtr = procPtr->bodyPtr->internalRep.otherValuePtr;
+ ByteCode *codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1;
register Var *varPtr, *defPtr;
int localCt = procPtr->numCompiledLocals, numArgs, argCt, i, imax;
Tcl_Obj *const *argObjs;
@@ -1627,7 +1624,7 @@ PushProcCallFrame(
* commands and/or resolver changes are considered).
*/
- codePtr = procPtr->bodyPtr->internalRep.otherValuePtr;
+ codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1;
if (((Interp *) *codePtr->interpHandle != iPtr)
|| (codePtr->compileEpoch != iPtr->compileEpoch)
|| (codePtr->nsPtr != nsPtr)
@@ -1828,7 +1825,7 @@ TclNRInterpProcCore(
*/
procPtr->refCount++;
- codePtr = procPtr->bodyPtr->internalRep.otherValuePtr;
+ codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1;
TclNRAddCallback(interp, InterpProcNR2, procNameObj, errorProc,
NULL, NULL);
@@ -1858,9 +1855,39 @@ InterpProcNR2(
}
/*
- * Process the result code.
+ * Free the stack-allocated compiled locals and CallFrame. It is important
+ * to pop the call frame without freeing it first: the compiledLocals
+ * cannot be freed before the frame is popped, as the local variables must
+ * be deleted. But the compiledLocals must be freed first, as they were
+ * allocated later on the stack.
*/
+ if (result != TCL_OK) {
+ goto process;
+ }
+
+ done:
+ if (TCL_DTRACE_PROC_RESULT_ENABLED()) {
+ int l = iPtr->varFramePtr->isProcCallFrame & FRAME_IS_LAMBDA ? 1 : 0;
+ Tcl_Obj *r = Tcl_GetObjResult(interp);
+
+ TCL_DTRACE_PROC_RESULT(l < iPtr->varFramePtr->objc ?
+ TclGetString(iPtr->varFramePtr->objv[l]) : NULL, result,
+ TclGetString(r), r);
+ }
+
+ freePtr = iPtr->framePtr;
+ Tcl_PopCallFrame(interp); /* Pop but do not free. */
+ TclStackFree(interp, freePtr->compiledLocals);
+ /* Free compiledLocals. */
+ TclStackFree(interp, freePtr); /* Free CallFrame. */
+ return result;
+
+ /*
+ * Process any non-TCL_OK result code.
+ */
+
+ process:
switch (result) {
case TCL_RETURN:
/*
@@ -1877,10 +1904,9 @@ InterpProcNR2(
* transform to an error now.
*/
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "invoked \"",
- ((result == TCL_BREAK) ? "break" : "continue"),
- "\" outside of a loop", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invoked \"%s\" outside of a loop",
+ ((result == TCL_BREAK) ? "break" : "continue")));
Tcl_SetErrorCode(interp, "TCL", "RESULT", "UNEXPECTED", NULL);
result = TCL_ERROR;
@@ -1896,46 +1922,8 @@ InterpProcNR2(
*/
errorProc(interp, procNameObj);
-
- default:
- /*
- * Process other results (OK and non-standard) by doing nothing
- * special, skipping directly to the code afterwards that cleans up
- * associated memory.
- *
- * Non-standard results are processed by passing them through quickly.
- * This means they all work as exceptions, unwinding the stack quickly
- * and neatly. Who knows how well they are handled by third-party code
- * though...
- */
-
- (void) 0; /* do nothing */
- }
-
- if (TCL_DTRACE_PROC_RESULT_ENABLED()) {
- int l = iPtr->varFramePtr->isProcCallFrame & FRAME_IS_LAMBDA ? 1 : 0;
- Tcl_Obj *r = Tcl_GetObjResult(interp);
-
- TCL_DTRACE_PROC_RESULT(l < iPtr->varFramePtr->objc ?
- TclGetString(iPtr->varFramePtr->objv[l]) : NULL, result,
- TclGetString(r), r);
}
-
- /*
- * Free the stack-allocated compiled locals and CallFrame. It is important
- * to pop the call frame without freeing it first: the compiledLocals
- * cannot be freed before the frame is popped, as the local variables must
- * be deleted. But the compiledLocals must be freed first, as they were
- * allocated later on the stack.
- */
-
- freePtr = iPtr->framePtr;
- Tcl_PopCallFrame(interp); /* Pop but do not free. */
- TclStackFree(interp, freePtr->compiledLocals);
- /* Free compiledLocals. */
- TclStackFree(interp, freePtr); /* Free CallFrame. */
-
- return result;
+ goto done;
}
/*
@@ -1971,7 +1959,7 @@ TclProcCompileProc(
{
Interp *iPtr = (Interp *) interp;
Tcl_CallFrame *framePtr;
- ByteCode *codePtr = bodyPtr->internalRep.otherValuePtr;
+ ByteCode *codePtr = bodyPtr->internalRep.twoPtrValue.ptr1;
/*
* If necessary, compile the procedure's body. The compiler will allocate
@@ -1997,8 +1985,8 @@ TclProcCompileProc(
if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
if ((Interp *) *codePtr->interpHandle != iPtr) {
- Tcl_AppendResult(interp,
- "a precompiled script jumped interps", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "a precompiled script jumped interps", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
"CROSSINTERPBYTECODE", NULL);
return TCL_ERROR;
@@ -2091,7 +2079,7 @@ TclProcCompileProc(
iPtr->invokeWord = 0;
iPtr->invokeCmdFramePtr = (hePtr ? Tcl_GetHashValue(hePtr) : NULL);
- tclByteCodeType.setFromAnyProc(interp, bodyPtr);
+ TclSetByteCodeFromAny(interp, bodyPtr, NULL, NULL);
iPtr->invokeCmdFramePtr = NULL;
TclPopStackFrame(interp);
} else if (codePtr->nsEpoch != nsPtr->resolverEpoch) {
@@ -2232,7 +2220,7 @@ TclProcCleanupProc(
* procbody structures created by tbcload.
*/
- if (!iPtr) {
+ if (iPtr == NULL) {
return;
}
@@ -2243,13 +2231,15 @@ TclProcCleanupProc(
cfPtr = Tcl_GetHashValue(hePtr);
- if (cfPtr->type == TCL_LOCATION_SOURCE) {
- Tcl_DecrRefCount(cfPtr->data.eval.path);
- cfPtr->data.eval.path = NULL;
+ if (cfPtr) {
+ if (cfPtr->type == TCL_LOCATION_SOURCE) {
+ Tcl_DecrRefCount(cfPtr->data.eval.path);
+ cfPtr->data.eval.path = NULL;
+ }
+ ckfree(cfPtr->line);
+ cfPtr->line = NULL;
+ ckfree(cfPtr);
}
- ckfree(cfPtr->line);
- cfPtr->line = NULL;
- ckfree(cfPtr);
Tcl_DeleteHashEntry(hePtr);
}
@@ -2359,7 +2349,7 @@ TclNewProcBodyObj(
TclNewObj(objPtr);
if (objPtr) {
objPtr->typePtr = &tclProcBodyType;
- objPtr->internalRep.otherValuePtr = procPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = procPtr;
procPtr->refCount++;
}
@@ -2389,10 +2379,10 @@ ProcBodyDup(
Tcl_Obj *srcPtr, /* Object to copy. */
Tcl_Obj *dupPtr) /* Target object for the duplication. */
{
- Proc *procPtr = srcPtr->internalRep.otherValuePtr;
+ Proc *procPtr = srcPtr->internalRep.twoPtrValue.ptr1;
dupPtr->typePtr = &tclProcBodyType;
- dupPtr->internalRep.otherValuePtr = procPtr;
+ dupPtr->internalRep.twoPtrValue.ptr1 = procPtr;
procPtr->refCount++;
}
@@ -2419,10 +2409,9 @@ static void
ProcBodyFree(
Tcl_Obj *objPtr) /* The object to clean up. */
{
- Proc *procPtr = objPtr->internalRep.otherValuePtr;
+ Proc *procPtr = objPtr->internalRep.twoPtrValue.ptr1;
- procPtr->refCount--;
- if (procPtr->refCount <= 0) {
+ if (procPtr->refCount-- < 2) {
TclProcCleanupProc(procPtr);
}
}
@@ -2481,7 +2470,8 @@ SetLambdaFromAny(
Interp *iPtr = (Interp *) interp;
const char *name;
Tcl_Obj *argsPtr, *bodyPtr, *nsObjPtr, **objv;
- int objc, result;
+ int isNew, objc, result;
+ CmdFrame *cfPtr = NULL;
Proc *procPtr;
if (interp == NULL) {
@@ -2576,14 +2566,14 @@ SetLambdaFromAny(
if (contextPtr->line
&& (contextPtr->nline >= 2) && (contextPtr->line[1] >= 0)) {
- int isNew, buf[2];
- CmdFrame *cfPtr = ckalloc(sizeof(CmdFrame));
+ int buf[2];
/*
* Move from approximation (line of list cmd word) to actual
* location (line of 2nd list element).
*/
+ cfPtr = ckalloc(sizeof(CmdFrame));
TclListLines(objPtr, contextPtr->line[1], 2, buf, NULL);
cfPtr->level = -1;
@@ -2597,11 +2587,8 @@ SetLambdaFromAny(
cfPtr->data.eval.path = contextPtr->data.eval.path;
Tcl_IncrRefCount(cfPtr->data.eval.path);
- cfPtr->cmd.str.cmd = NULL;
- cfPtr->cmd.str.len = 0;
-
- Tcl_SetHashValue(Tcl_CreateHashEntry(iPtr->linePBodyPtr,
- procPtr, &isNew), cfPtr);
+ cfPtr->cmd = NULL;
+ cfPtr->len = 0;
}
/*
@@ -2613,6 +2600,8 @@ SetLambdaFromAny(
}
TclStackFree(interp, contextPtr);
}
+ Tcl_SetHashValue(Tcl_CreateHashEntry(iPtr->linePBodyPtr, procPtr,
+ &isNew), cfPtr);
/*
* Set the namespace for this lambda: given by objv[2] understood as a
@@ -2715,7 +2704,6 @@ TclNRApplyObjCmd(
else {
/*
* Joe English's suggestion to allow cmdNames to function as lambdas.
- * Also requires making tclCmdNameType non-static in tclObj.c
*/
Tcl_Obj *elemPtr;
@@ -2928,8 +2916,8 @@ Tcl_DisassembleObjCmd(
procPtr = TclFindProc((Interp *) interp, TclGetString(objv[2]));
if (procPtr == NULL) {
- Tcl_AppendResult(interp, "\"", TclGetString(objv[2]),
- "\" isn't a procedure", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" isn't a procedure", TclGetString(objv[2])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROC",
TclGetString(objv[2]), NULL);
return TCL_ERROR;
@@ -2955,10 +2943,9 @@ Tcl_DisassembleObjCmd(
Tcl_WrongNumArgs(interp, 2, objv, "script");
return TCL_ERROR;
}
- if (objv[2]->typePtr != &tclByteCodeType) {
- if (TclSetByteCodeFromAny(interp, objv[2], NULL, NULL) != TCL_OK){
- return TCL_ERROR;
- }
+ if ((objv[2]->typePtr != &tclByteCodeType)
+ && (TclSetByteCodeFromAny(interp, objv[2], NULL, NULL) != TCL_OK)) {
+ return TCL_ERROR;
}
codeObjPtr = objv[2];
break;
@@ -2978,8 +2965,8 @@ Tcl_DisassembleObjCmd(
return TCL_ERROR;
}
if (oPtr->classPtr == NULL) {
- Tcl_AppendResult(interp, "\"", TclGetString(objv[2]),
- "\" is not a class", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" is not a class", TclGetString(objv[2])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
TclGetString(objv[2]), NULL);
return TCL_ERROR;
@@ -3013,16 +3000,16 @@ Tcl_DisassembleObjCmd(
methodBody:
if (hPtr == NULL) {
unknownMethod:
- Tcl_AppendResult(interp, "unknown method \"",
- TclGetString(objv[3]), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown method \"%s\"", TclGetString(objv[3])));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(objv[3]), NULL);
return TCL_ERROR;
}
procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr));
if (procPtr == NULL) {
- Tcl_AppendResult(interp,
- "body not available for this kind of method", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "body not available for this kind of method", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
"METHODTYPE", NULL);
return TCL_ERROR;
@@ -3055,9 +3042,10 @@ Tcl_DisassembleObjCmd(
* Do the actual disassembly.
*/
- if (((ByteCode *) codeObjPtr->internalRep.otherValuePtr)->flags
+ if (((ByteCode *) codeObjPtr->internalRep.twoPtrValue.ptr1)->flags
& TCL_BYTECODE_PRECOMPILED) {
- Tcl_AppendResult(interp,"may not disassemble prebuilt bytecode",NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "may not disassemble prebuilt bytecode", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
"BYTECODE", NULL);
return TCL_ERROR;
diff --git a/generic/tclRegexp.c b/generic/tclRegexp.c
index 5c5af7b..6348e4a 100644
--- a/generic/tclRegexp.c
+++ b/generic/tclRegexp.c
@@ -578,7 +578,7 @@ Tcl_GetRegExpFromObj(
* TclRegexp* when the type is tclRegexpType.
*/
- regexpPtr = objPtr->internalRep.otherValuePtr;
+ regexpPtr = objPtr->internalRep.twoPtrValue.ptr1;
if ((objPtr->typePtr != &tclRegexpType) || (regexpPtr->flags != flags)) {
pattern = TclGetStringFromObj(objPtr, &length);
@@ -601,7 +601,7 @@ Tcl_GetRegExpFromObj(
*/
TclFreeIntRep(objPtr);
- objPtr->internalRep.otherValuePtr = regexpPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = regexpPtr;
objPtr->typePtr = &tclRegexpType;
}
return (Tcl_RegExp) regexpPtr;
@@ -714,14 +714,14 @@ TclRegError(
int status) /* Status code to report. */
{
char buf[100]; /* ample in practice */
- char cbuf[100]; /* lots in practice */
+ char cbuf[TCL_INTEGER_SPACE];
size_t n;
const char *p;
Tcl_ResetResult(interp);
n = TclReError(status, NULL, buf, sizeof(buf));
p = (n > sizeof(buf)) ? "..." : "";
- Tcl_AppendResult(interp, msg, buf, p, NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s%s%s", msg, buf, p));
sprintf(cbuf, "%d", status);
(void) TclReError(REG_ITOA, NULL, cbuf, sizeof(cbuf));
@@ -749,7 +749,7 @@ static void
FreeRegexpInternalRep(
Tcl_Obj *objPtr) /* Regexp object with internal rep to free. */
{
- TclRegexp *regexpRepPtr = objPtr->internalRep.otherValuePtr;
+ TclRegexp *regexpRepPtr = objPtr->internalRep.twoPtrValue.ptr1;
/*
* If this is the last reference to the regexp, free it.
@@ -783,10 +783,10 @@ DupRegexpInternalRep(
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
Tcl_Obj *copyPtr) /* Object with internal rep to set. */
{
- TclRegexp *regexpPtr = srcPtr->internalRep.otherValuePtr;
+ TclRegexp *regexpPtr = srcPtr->internalRep.twoPtrValue.ptr1;
regexpPtr->refCount++;
- copyPtr->internalRep.otherValuePtr = srcPtr->internalRep.otherValuePtr;
+ copyPtr->internalRep.twoPtrValue.ptr1 = srcPtr->internalRep.twoPtrValue.ptr1;
copyPtr->typePtr = &tclRegexpType;
}
@@ -947,10 +947,8 @@ CompileRegexp(
*/
if (TclReToGlob(NULL, string, length, &stringBuf, &exact) == TCL_OK) {
- regexpPtr->globObjPtr = Tcl_NewStringObj(Tcl_DStringValue(&stringBuf),
- Tcl_DStringLength(&stringBuf));
+ regexpPtr->globObjPtr = TclDStringToObj(&stringBuf);
Tcl_IncrRefCount(regexpPtr->globObjPtr);
- Tcl_DStringFree(&stringBuf);
} else {
regexpPtr->globObjPtr = NULL;
}
diff --git a/generic/tclResult.c b/generic/tclResult.c
index 4443cc1..2f2563a 100644
--- a/generic/tclResult.c
+++ b/generic/tclResult.c
@@ -230,6 +230,7 @@ Tcl_DiscardInterpState(
*----------------------------------------------------------------------
*/
+#undef Tcl_SaveResult
void
Tcl_SaveResult(
Tcl_Interp *interp, /* Interpreter to save. */
@@ -304,6 +305,7 @@ Tcl_SaveResult(
*----------------------------------------------------------------------
*/
+#undef Tcl_RestoreResult
void
Tcl_RestoreResult(
Tcl_Interp *interp, /* Interpreter being restored. */
@@ -372,6 +374,7 @@ Tcl_RestoreResult(
*----------------------------------------------------------------------
*/
+#undef Tcl_DiscardResult
void
Tcl_DiscardResult(
Tcl_SavedResult *statePtr) /* State returned by Tcl_SaveResult. */
@@ -380,12 +383,10 @@ Tcl_DiscardResult(
if (statePtr->result == statePtr->appendResult) {
ckfree(statePtr->appendResult);
+ } else if (statePtr->freeProc == TCL_DYNAMIC) {
+ ckfree(statePtr->result);
} else if (statePtr->freeProc) {
- if (statePtr->freeProc == TCL_DYNAMIC) {
- ckfree(statePtr->result);
- } else {
- statePtr->freeProc(statePtr->result);
- }
+ statePtr->freeProc(statePtr->result);
}
}
@@ -585,7 +586,7 @@ Tcl_GetObjResult(
* result, then reset the string result.
*/
- if (*(iPtr->result) != 0) {
+ if (iPtr->result[0] != 0) {
ResetObjResult(iPtr);
objResultPtr = iPtr->objResultPtr;
@@ -601,7 +602,7 @@ Tcl_GetObjResult(
iPtr->freeProc = 0;
}
iPtr->result = iPtr->resultSpace;
- iPtr->resultSpace[0] = 0;
+ iPtr->result[0] = 0;
}
return iPtr->objResultPtr;
}
@@ -1106,13 +1107,12 @@ Tcl_SetObjErrorCode(
*
* Tcl_GetErrorLine --
*
- * Results:
- *
- * Side effects:
+ * Returns the line number associated with the current error.
*
*----------------------------------------------------------------------
*/
+#undef Tcl_GetErrorLine
int
Tcl_GetErrorLine(
Tcl_Interp *interp)
@@ -1125,13 +1125,12 @@ Tcl_GetErrorLine(
*
* Tcl_SetErrorLine --
*
- * Results:
- *
- * Side effects:
+ * Sets the line number associated with the current error.
*
*----------------------------------------------------------------------
*/
+#undef Tcl_SetErrorLine
void
Tcl_SetErrorLine(
Tcl_Interp *interp,
@@ -1274,7 +1273,8 @@ TclProcessReturn(
Tcl_DecrRefCount(iPtr->errorInfo);
iPtr->errorInfo = NULL;
}
- Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORINFO], &valuePtr);
+ Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORINFO],
+ &valuePtr);
if (valuePtr != NULL) {
int infoLen;
@@ -1285,7 +1285,8 @@ TclProcessReturn(
iPtr->flags |= ERR_ALREADY_LOGGED;
}
}
- Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORSTACK], &valuePtr);
+ Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORSTACK],
+ &valuePtr);
if (valuePtr != NULL) {
int len, valueObjc;
Tcl_Obj **valueObjv;
@@ -1298,26 +1299,36 @@ TclProcessReturn(
Tcl_IncrRefCount(newObj);
iPtr->errorStack = newObj;
}
+
/*
* List extraction done after duplication to avoid moving the rug
* if someone does [return -errorstack [info errorstack]]
*/
- if (Tcl_ListObjGetElements(interp, valuePtr, &valueObjc, &valueObjv) == TCL_ERROR) {
+
+ if (Tcl_ListObjGetElements(interp, valuePtr, &valueObjc,
+ &valueObjv) == TCL_ERROR) {
return TCL_ERROR;
}
iPtr->resetErrorStack = 0;
Tcl_ListObjLength(interp, iPtr->errorStack, &len);
- /* reset while keeping the list intrep as much as possible */
- Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, valueObjc, valueObjv);
+
+ /*
+ * Reset while keeping the list intrep as much as possible.
+ */
+
+ Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, valueObjc,
+ valueObjv);
}
- Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORCODE], &valuePtr);
+ Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORCODE],
+ &valuePtr);
if (valuePtr != NULL) {
Tcl_SetObjErrorCode(interp, valuePtr);
} else {
Tcl_SetErrorCode(interp, "NONE", NULL);
}
- Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORLINE], &valuePtr);
+ Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORLINE],
+ &valuePtr);
if (valuePtr != NULL) {
TclGetIntFromObj(NULL, valuePtr, &iPtr->errorLine);
}
@@ -1390,10 +1401,9 @@ TclMergeReturnOptions(
* Value is not a legal dictionary.
*/
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad ", compare,
- " value: expected dictionary but got \"",
- TclGetString(objv[1]), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad %s value: expected dictionary but got \"%s\"",
+ compare, TclGetString(objv[1])));
Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_OPTIONS",
NULL);
goto error;
@@ -1422,7 +1432,8 @@ TclMergeReturnOptions(
Tcl_DictObjGet(NULL, returnOpts, keys[KEY_CODE], &valuePtr);
if (valuePtr != NULL) {
- if (TCL_ERROR == TclGetCompletionCodeFromObj(interp, valuePtr, &code)) {
+ if (TclGetCompletionCodeFromObj(interp, valuePtr,
+ &code) == TCL_ERROR) {
goto error;
}
Tcl_DictObjRemove(NULL, returnOpts, keys[KEY_CODE]);
@@ -1440,10 +1451,9 @@ TclMergeReturnOptions(
* Value is not a legal level.
*/
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad -level value: "
- "expected non-negative integer but got \"",
- TclGetString(valuePtr), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad -level value: expected non-negative integer but got"
+ " \"%s\"", TclGetString(valuePtr)));
Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_LEVEL", NULL);
goto error;
}
@@ -1462,10 +1472,10 @@ TclMergeReturnOptions(
/*
* Value is not a list, which is illegal for -errorcode.
*/
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad -errorcode value: "
- "expected a list but got \"",
- TclGetString(valuePtr), "\"", NULL);
+
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad -errorcode value: expected a list but got \"%s\"",
+ TclGetString(valuePtr)));
Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_ERRORCODE",
NULL);
goto error;
@@ -1484,10 +1494,10 @@ TclMergeReturnOptions(
/*
* Value is not a list, which is illegal for -errorstack.
*/
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad -errorstack value: "
- "expected a list but got \"", TclGetString(valuePtr),
- "\"", NULL);
+
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad -errorstack value: expected a list but got \"%s\"",
+ TclGetString(valuePtr)));
Tcl_SetErrorCode(interp, "TCL", "RESULT", "NONLIST_ERRORSTACK",
NULL);
goto error;
@@ -1496,10 +1506,10 @@ TclMergeReturnOptions(
/*
* Errorstack must always be an even-sized list
*/
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp,
- "forbidden odd-sized list for -errorstack: \"",
- TclGetString(valuePtr), "\"", NULL);
+
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "forbidden odd-sized list for -errorstack: \"%s\"",
+ TclGetString(valuePtr)));
Tcl_SetErrorCode(interp, "TCL", "RESULT",
"ODDSIZEDLIST_ERRORSTACK", NULL);
goto error;
@@ -1582,7 +1592,7 @@ Tcl_GetReturnOptions(
}
if (result == TCL_ERROR) {
- Tcl_AddObjErrorInfo(interp, "", -1);
+ Tcl_AddErrorInfo(interp, "");
Tcl_DictObjPut(NULL, options, keys[KEY_ERRORSTACK], iPtr->errorStack);
}
if (iPtr->errorCode) {
@@ -1601,7 +1611,8 @@ Tcl_GetReturnOptions(
*
* TclNoErrorStack --
*
- * Removes the -errorstack entry from an options dict to avoid reference cycles
+ * Removes the -errorstack entry from an options dict to avoid reference
+ * cycles.
*
* Results:
* The (unshared) argument options dict, modified in -place.
@@ -1610,12 +1621,13 @@ Tcl_GetReturnOptions(
*/
Tcl_Obj *
-TclNoErrorStack(Tcl_Interp *interp, Tcl_Obj *options)
+TclNoErrorStack(
+ Tcl_Interp *interp,
+ Tcl_Obj *options)
{
Tcl_Obj **keys = GetKeys();
Tcl_DictObjRemove(interp, options, keys[KEY_ERRORSTACK]);
-
return options;
}
@@ -1650,9 +1662,8 @@ Tcl_SetReturnOptions(
Tcl_IncrRefCount(options);
if (TCL_ERROR == TclListObjGetElements(interp, options, &objc, &objv)
|| (objc % 2)) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "expected dict but got \"",
- TclGetString(options), "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "expected dict but got \"%s\"", TclGetString(options)));
Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_OPTIONS", NULL);
code = TCL_ERROR;
} else if (TCL_ERROR == TclMergeReturnOptions(interp, objc, objv,
diff --git a/generic/tclScan.c b/generic/tclScan.c
index d21bfaf..4dfc2d6 100644
--- a/generic/tclScan.c
+++ b/generic/tclScan.c
@@ -261,6 +261,10 @@ ValidateFormat(
int objIndex, xpgSize, nspace = numVars;
int *nassign = TclStackAlloc(interp, nspace * sizeof(int));
char buf[TCL_UTF_MAX+1];
+ Tcl_Obj *errorMsg; /* Place to build an error messages. Note that
+ * these are messy operations because we do
+ * not want to use the formatting engine;
+ * we're inside there! */
/*
* Initialize an array that records the number of times a variable is
@@ -328,9 +332,9 @@ ValidateFormat(
gotSequential = 1;
if (gotXpg) {
mixedXPG:
- Tcl_SetResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"cannot mix \"%\" and \"%n$\" conversion specifiers",
- TCL_STATIC);
+ -1));
Tcl_SetErrorCode(interp, "TCL", "FORMAT", "MIXEDSPECTYPES", NULL);
goto error;
}
@@ -375,9 +379,9 @@ ValidateFormat(
switch (ch) {
case 'c':
if (flags & SCAN_WIDTH) {
- Tcl_SetResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"field width may not be specified in %c conversion",
- TCL_STATIC);
+ -1));
Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADWIDTH", NULL);
goto error;
}
@@ -389,9 +393,11 @@ ValidateFormat(
if (flags & (SCAN_LONGER|SCAN_BIG)) {
invalidFieldSize:
buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
- Tcl_AppendResult(interp,
- "field size modifier may not be specified in %", buf,
- " conversion", NULL);
+ errorMsg = Tcl_NewStringObj(
+ "field size modifier may not be specified in %", -1);
+ Tcl_AppendToObj(errorMsg, buf, -1);
+ Tcl_AppendToObj(errorMsg, " conversion", -1);
+ Tcl_SetObjResult(interp, errorMsg);
Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADSIZE", NULL);
goto error;
}
@@ -400,17 +406,20 @@ ValidateFormat(
*/
case 'd':
case 'e':
+ case 'E':
case 'f':
case 'g':
+ case 'G':
case 'i':
case 'o':
case 'x':
+ case 'X':
case 'b':
break;
case 'u':
if (flags & SCAN_BIG) {
- Tcl_SetResult(interp,
- "unsigned bignum scans are invalid", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "unsigned bignum scans are invalid", -1));
Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADUNSIGNED",NULL);
goto error;
}
@@ -446,15 +455,18 @@ ValidateFormat(
}
break;
badSet:
- Tcl_SetResult(interp, "unmatched [ in format string",
- TCL_STATIC);
- Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BRACKET", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "unmatched [ in format string", -1));
+ Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BRACKET", NULL);
goto error;
default:
buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
- Tcl_AppendResult(interp, "bad scan conversion character \"", buf,
- "\"", NULL);
- Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADTYPE", NULL);
+ errorMsg = Tcl_NewStringObj(
+ "bad scan conversion character \"", -1);
+ Tcl_AppendToObj(errorMsg, buf, -1);
+ Tcl_AppendToObj(errorMsg, "\"", -1);
+ Tcl_SetObjResult(interp, errorMsg);
+ Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADTYPE", NULL);
goto error;
}
if (!(flags & SCAN_SUPPRESS)) {
@@ -498,9 +510,9 @@ ValidateFormat(
}
for (i = 0; i < numVars; i++) {
if (nassign[i] > 1) {
- Tcl_SetResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"variable is assigned by multiple \"%n$\" conversion specifiers",
- TCL_STATIC);
+ -1));
Tcl_SetErrorCode(interp, "TCL", "FORMAT", "POLYASSIGNED", NULL);
goto error;
} else if (!xpgSize && (nassign[i] == 0)) {
@@ -509,9 +521,9 @@ ValidateFormat(
* and/or numVars != 0), then too many vars were given
*/
- Tcl_SetResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"variable is not assigned by any conversion specifiers",
- TCL_STATIC);
+ -1));
Tcl_SetErrorCode(interp, "TCL", "FORMAT", "UNASSIGNED", NULL);
goto error;
}
@@ -522,13 +534,13 @@ ValidateFormat(
badIndex:
if (gotXpg) {
- Tcl_SetResult(interp, "\"%n$\" argument index out of range",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "\"%n$\" argument index out of range", -1));
Tcl_SetErrorCode(interp, "TCL", "FORMAT", "INDEXRANGE", NULL);
} else {
- Tcl_SetResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"different numbers of variable names and field specifiers",
- TCL_STATIC);
+ -1));
Tcl_SetErrorCode(interp, "TCL", "FORMAT", "FIELDVARMISMATCH", NULL);
}
@@ -734,6 +746,7 @@ Tcl_ScanObjCmd(
parseFlag |= TCL_PARSE_OCTAL_ONLY | TCL_PARSE_SCAN_PREFIXES;
break;
case 'x':
+ case 'X':
op = 'i';
parseFlag |= TCL_PARSE_HEXADECIMAL_ONLY;
break;
@@ -749,7 +762,9 @@ Tcl_ScanObjCmd(
case 'f':
case 'e':
+ case 'E':
case 'g':
+ case 'G':
op = 'f';
break;
diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c
index a55ee83..883e2ea 100755..100644
--- a/generic/tclStrToD.c
+++ b/generic/tclStrToD.c
@@ -192,8 +192,6 @@ static int maxDigits; /* The maximum number of digits to the left of
* the decimal point of a double. */
static int minDigits; /* The maximum number of digits to the right
* of the decimal point in a double. */
-static int mantDIGIT; /* Number of mp_digit's needed to hold the
- * significand of a double. */
static const double pow_10_2_n[] = { /* Inexact higher powers of ten. */
1.0,
100.0,
@@ -249,15 +247,6 @@ static const int itens [] = {
100000000
};
-static const Tcl_WideUInt wtens[] = {
- 1, 10, 100, 1000, 10000, 100000, 1000000,
- (Tcl_WideUInt) 1000000*10, (Tcl_WideUInt) 1000000*100,
- (Tcl_WideUInt) 1000000*1000, (Tcl_WideUInt) 1000000*10000,
- (Tcl_WideUInt) 1000000*100000, (Tcl_WideUInt) 1000000*1000000,
- (Tcl_WideUInt) 1000000*1000000*10, (Tcl_WideUInt) 1000000*1000000*100,
- (Tcl_WideUInt) 1000000*1000000*1000,(Tcl_WideUInt) 1000000*1000000*10000
-};
-
static const double bigtens[] = {
1e016, 1e032, 1e064, 1e128, 1e256
};
@@ -1101,7 +1090,10 @@ TclParseNumber(
d = 10 + c - 'a';
} else if (c >= 'A' && c <= 'F') {
d = 10 + c - 'A';
+ } else {
+ goto endgame;
}
+ numSigDigs++;
significandWide = (significandWide << 4) + d;
state = sNANHEX;
break;
@@ -1247,7 +1239,7 @@ TclParseNumber(
if (!octalSignificandOverflow) {
if (octalSignificandWide >
(Tcl_WideUInt)(((~(unsigned long)0) >> 1) + signum)) {
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if (octalSignificandWide <= (MOST_BITS + signum)) {
objPtr->typePtr = &tclWideIntType;
if (signum) {
@@ -1294,7 +1286,7 @@ TclParseNumber(
if (!significandOverflow) {
if (significandWide >
(Tcl_WideUInt)(((~(unsigned long)0) >> 1) + signum)) {
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
if (significandWide <= MOST_BITS+signum) {
objPtr->typePtr = &tclWideIntType;
if (signum) {
@@ -4431,7 +4423,6 @@ TclInitDoubleConversion(void)
+ 0.5 * log(10.)) / log(10.));
minDigits = (int) floor((DBL_MIN_EXP - DBL_MANT_DIG)
* log((double) FLT_RADIX) / log(10.));
- mantDIGIT = (mantBits + DIGIT_BIT-1) / DIGIT_BIT;
log10_DIGIT_MAX = (int) floor(DIGIT_BIT * log(2.) / log(10.));
/*
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index ab62359..dffa38c 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -140,9 +140,9 @@ typedef struct String {
#define stringAttemptRealloc(ptr, numChars) \
(String *) attemptckrealloc((ptr), (unsigned) STRING_SIZE(numChars) )
#define GET_STRING(objPtr) \
- ((String *) (objPtr)->internalRep.otherValuePtr)
+ ((String *) (objPtr)->internalRep.twoPtrValue.ptr1)
#define SET_STRING(objPtr, stringPtr) \
- ((objPtr)->internalRep.otherValuePtr = (void *) (stringPtr))
+ ((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (stringPtr))
/*
* TCL STRING GROWTH ALGORITHM
@@ -1281,23 +1281,43 @@ Tcl_AppendObjToObj(
if ((TclIsPureByteArray(objPtr) || objPtr->bytes == tclEmptyStringRep)
&& TclIsPureByteArray(appendObjPtr)) {
- unsigned char *bytesSrc;
- int lengthSrc, lengthTotal;
/*
- * We do not assume that objPtr and appendObjPtr must be distinct!
- * This makes this code a bit more complex than it otherwise would be,
- * but in turn makes it much safer.
+ * You might expect the code here to be
+ *
+ * bytes = Tcl_GetByteArrayFromObj(appendObjPtr, &length);
+ * TclAppendBytesToByteArray(objPtr, bytes, length);
+ *
+ * and essentially all of the time that would be fine. However,
+ * it would run into trouble in the case where objPtr and
+ * appendObjPtr point to the same thing. That may never be a
+ * good idea. It seems to violate Copy On Write, and we don't
+ * have any tests for the situation, since making any Tcl commands
+ * that call Tcl_AppendObjToObj() do that appears impossible
+ * (They honor Copy On Write!). For the sake of extensions that
+ * go off into that realm, though, here's a more complex approach
+ * that can handle all the cases.
*/
+ /* Get lengths */
+ int lengthSrc;
+
(void) Tcl_GetByteArrayFromObj(objPtr, &length);
(void) Tcl_GetByteArrayFromObj(appendObjPtr, &lengthSrc);
- lengthTotal = length + lengthSrc;
- if (((length > lengthSrc) ? length : lengthSrc) > lengthTotal) {
- Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
- }
- bytesSrc = Tcl_GetByteArrayFromObj(appendObjPtr, NULL);
- TclAppendBytesToByteArray(objPtr, bytesSrc, lengthSrc);
+
+ /* Grow buffer enough for the append */
+ TclAppendBytesToByteArray(objPtr, NULL, lengthSrc);
+
+ /* Reset objPtr back to the original value */
+ Tcl_SetByteArrayLength(objPtr, length);
+
+ /*
+ * Now do the append knowing that buffer growth cannot cause
+ * any trouble.
+ */
+
+ TclAppendBytesToByteArray(objPtr,
+ Tcl_GetByteArrayFromObj(appendObjPtr, NULL), lengthSrc);
return;
}
@@ -1437,7 +1457,7 @@ AppendUnicodeToUnicodeRep(
* trailing null.
*/
- memcpy(stringPtr->unicode + stringPtr->numChars, unicode,
+ memmove(stringPtr->unicode + stringPtr->numChars, unicode,
appendNumChars * sizeof(Tcl_UniChar));
stringPtr->unicode[numChars] = 0;
stringPtr->numChars = numChars;
@@ -1605,7 +1625,7 @@ AppendUtfToUtfRep(
stringPtr->numChars = -1;
stringPtr->hasUnicode = 0;
- memcpy(objPtr->bytes + oldLength, bytes, numBytes);
+ memmove(objPtr->bytes + oldLength, bytes, numBytes);
objPtr->bytes[newLength] = 0;
objPtr->length = newLength;
}
@@ -2653,99 +2673,124 @@ Tcl_ObjPrintf(
*---------------------------------------------------------------------------
*/
+static void
+ReverseBytes(
+ unsigned char *to, /* Copy bytes into here... */
+ unsigned char *from, /* ...from here... */
+ int count) /* Until this many are copied, */
+ /* reversing as you go. */
+{
+ unsigned char *src = from + count;
+ if (to == from) {
+ /* Reversing in place */
+ while (--src > to) {
+ unsigned char c = *src;
+ *src = *to;
+ *to++ = c;
+ }
+ } else {
+ while (--src >= from) {
+ *to++ = *src;
+ }
+ }
+}
+
Tcl_Obj *
TclStringObjReverse(
Tcl_Obj *objPtr)
{
String *stringPtr;
- char *src = NULL, *dest = NULL;
- Tcl_UniChar *usrc = NULL, *udest = NULL;
- Tcl_Obj *resultPtr = NULL;
+ Tcl_UniChar ch;
+
+ if (TclIsPureByteArray(objPtr)) {
+ int numBytes;
+ unsigned char *from = Tcl_GetByteArrayFromObj(objPtr, &numBytes);
+
+ if (Tcl_IsShared(objPtr)) {
+ objPtr = Tcl_NewByteArrayObj(NULL, numBytes);
+ }
+ ReverseBytes(Tcl_GetByteArrayFromObj(objPtr, NULL), from, numBytes);
+ return objPtr;
+ }
SetStringFromAny(NULL, objPtr);
stringPtr = GET_STRING(objPtr);
- if (stringPtr->hasUnicode == 0) {
- if (stringPtr->numChars == -1) {
- TclNumUtfChars(stringPtr->numChars, objPtr->bytes, objPtr->length);
- }
- if (stringPtr->numChars <= 1) {
- return objPtr;
- }
- if (stringPtr->numChars == objPtr->length) {
- /*
- * All one-byte chars. Reverse in objPtr->bytes.
- */
+ if (stringPtr->hasUnicode) {
+ Tcl_UniChar *from = Tcl_GetUnicode(objPtr);
+ Tcl_UniChar *src = from + stringPtr->numChars;
- if (Tcl_IsShared(objPtr)) {
- resultPtr = Tcl_NewObj();
- Tcl_SetObjLength(resultPtr, objPtr->length);
- dest = TclGetString(resultPtr);
- src = objPtr->bytes + objPtr->length - 1;
- while (src >= objPtr->bytes) {
- *dest++ = *src--;
- }
- return resultPtr;
- }
+ if (Tcl_IsShared(objPtr)) {
+ Tcl_UniChar *to;
/*
- * Unshared. Reverse objPtr->bytes in place.
+ * Create a non-empty, pure unicode value, so we can coax
+ * Tcl_SetObjLength into growing the unicode rep buffer.
*/
- dest = objPtr->bytes;
- src = dest + objPtr->length - 1;
- while (dest < src) {
- char tmp = *src;
-
- *src-- = *dest;
- *dest++ = tmp;
+ ch = 0;
+ objPtr = Tcl_NewUnicodeObj(&ch, 1);
+ Tcl_SetObjLength(objPtr, stringPtr->numChars);
+ to = Tcl_GetUnicode(objPtr);
+ while (--src >= from) {
+ *to++ = *src;
+ }
+ } else {
+ /* Reversing in place */
+ while (--src > from) {
+ ch = *src;
+ *src = *from;
+ *from++ = ch;
}
- return objPtr;
}
- FillUnicodeRep(objPtr);
- stringPtr = GET_STRING(objPtr);
- }
- if (stringPtr->numChars <= 1) {
- return objPtr;
}
- /*
- * Reverse the Unicode rep.
- */
-
- if (Tcl_IsShared(objPtr)) {
- Tcl_UniChar ch = 0;
+ if (objPtr->bytes) {
+ int numChars = stringPtr->numChars;
+ int numBytes = objPtr->length;
+ char *to, *from = objPtr->bytes;
- /*
- * Create a non-empty, pure unicode value, so we can coax
- * Tcl_SetObjLength into growing the unicode rep buffer.
- */
-
- resultPtr = Tcl_NewUnicodeObj(&ch, 1);
- Tcl_SetObjLength(resultPtr, stringPtr->numChars);
- udest = Tcl_GetUnicode(resultPtr);
- usrc = stringPtr->unicode + stringPtr->numChars - 1;
- while (usrc >= stringPtr->unicode) {
- *udest++ = *usrc--;
+ if (Tcl_IsShared(objPtr)) {
+ objPtr = Tcl_NewObj();
+ Tcl_SetObjLength(objPtr, numBytes);
}
- return resultPtr;
- }
+ to = objPtr->bytes;
- /*
- * Unshared. Reverse objPtr->bytes in place.
- */
+ if (numChars < numBytes) {
+ /*
+ * Either numChars == -1 and we don't know how many chars are
+ * represented by objPtr->bytes and we need Pass 1 just in case,
+ * or numChars >= 0 and we know we have fewer chars than bytes,
+ * so we know there's a multibyte character needing Pass 1.
+ *
+ * Pass 1. Reverse the bytes of each multi-byte character.
+ */
+ int charCount = 0;
+ int bytesLeft = numBytes;
- udest = stringPtr->unicode;
- usrc = udest + stringPtr->numChars - 1;
- while (udest < usrc) {
- Tcl_UniChar tmp = *usrc;
+ while (bytesLeft) {
+ /*
+ * NOTE: We know that the from buffer is NUL-terminated.
+ * It's part of the contract for objPtr->bytes values.
+ * Thus, we can skip calling Tcl_UtfCharComplete() here.
+ */
+ int bytesInChar = Tcl_UtfToUniChar(from, &ch);
+
+ ReverseBytes((unsigned char *)to, (unsigned char *)from,
+ bytesInChar);
+ to += bytesInChar;
+ from += bytesInChar;
+ bytesLeft -= bytesInChar;
+ charCount++;
+ }
- *usrc-- = *udest;
- *udest++ = tmp;
+ from = to = objPtr->bytes;
+ stringPtr->numChars = charCount;
+ }
+ /* Pass 2. Reverse all the bytes. */
+ ReverseBytes((unsigned char *)to, (unsigned char *)from, numBytes);
}
- TclInvalidateStringRep(objPtr);
- stringPtr->allocated = 0;
return objPtr;
}
diff --git a/generic/tclStringTrim.h b/generic/tclStringTrim.h
new file mode 100644
index 0000000..030e4ec
--- /dev/null
+++ b/generic/tclStringTrim.h
@@ -0,0 +1,43 @@
+/*
+ * tclStringTrim.h --
+ *
+ * This file contains the definition of what characters are to be trimmed
+ * from a string by [string trim] by default. It's only needed by Tcl's
+ * implementation; it does not form a public or private API at all.
+ *
+ * Copyright (c) 1987-1993 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-2000 Scriptics Corporation.
+ * Copyright (c) 2002 ActiveState Corporation.
+ * Copyright (c) 2003-2013 Donal K. Fellows.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef TCL_STRING_TRIM_H
+#define TCL_STRING_TRIM_H
+
+/*
+ * Default set of characters to trim in [string trim] and friends. This is a
+ * UTF-8 literal string containing all Unicode space characters. [TIP #413]
+ */
+
+MODULE_SCOPE const char tclDefaultTrimSet[];
+
+/*
+ * The whitespace trimming set used when [concat]enating. This is a subset of
+ * the above, and deliberately so.
+ */
+
+#define CONCAT_TRIM_SET " \f\v\r\t\n"
+
+#endif /* TCL_STRING_TRIM_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
index 5b47e95..7a84cba 100644
--- a/generic/tclStubInit.c
+++ b/generic/tclStubInit.c
@@ -39,8 +39,260 @@
#undef Tcl_CreateHashEntry
#undef Tcl_Panic
#undef Tcl_FindExecutable
-#define TclpLocaltime_unix TclpLocaltime
-#define TclpGmtime_unix TclpGmtime
+#undef TclpGetPid
+#undef TclSockMinimumBuffers
+#define TclBackgroundException Tcl_BackgroundException
+#undef Tcl_SetIntObj
+#undef TclpInetNtoa
+#undef TclWinGetServByName
+#undef TclWinGetSockOpt
+#undef TclWinSetSockOpt
+
+/* See bug 510001: TclSockMinimumBuffers needs plat imp */
+#ifdef _WIN64
+# define TclSockMinimumBuffersOld 0
+#else
+#define TclSockMinimumBuffersOld sockMinimumBuffersOld
+static int TclSockMinimumBuffersOld(int sock, int size)
+{
+ return TclSockMinimumBuffers(INT2PTR(sock), size);
+}
+#endif
+
+#define TclSetStartupScriptPath setStartupScriptPath
+static void TclSetStartupScriptPath(Tcl_Obj *path)
+{
+ Tcl_SetStartupScript(path, NULL);
+}
+#define TclGetStartupScriptPath getStartupScriptPath
+static Tcl_Obj *TclGetStartupScriptPath(void)
+{
+ return Tcl_GetStartupScript(NULL);
+}
+#define TclSetStartupScriptFileName setStartupScriptFileName
+static void TclSetStartupScriptFileName(
+ const char *fileName)
+{
+ Tcl_SetStartupScript(Tcl_NewStringObj(fileName,-1), NULL);
+}
+#define TclGetStartupScriptFileName getStartupScriptFileName
+static const char *TclGetStartupScriptFileName(void)
+{
+ Tcl_Obj *path = Tcl_GetStartupScript(NULL);
+ if (path == NULL) {
+ return NULL;
+ }
+ return Tcl_GetStringFromObj(path, NULL);
+}
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+#undef TclWinNToHS
+#define TclWinNToHS winNToHS
+static unsigned short TclWinNToHS(unsigned short ns) {
+ return ntohs(ns);
+}
+#endif
+
+#ifdef _WIN32
+# define TclUnixWaitForFile 0
+# define TclUnixCopyFile 0
+# define TclUnixOpenTemporaryFile 0
+# define TclpReaddir 0
+# define TclpIsAtty 0
+#elif defined(__CYGWIN__)
+# define TclpIsAtty TclPlatIsAtty
+# define TclWinSetInterfaces (void (*) (int)) doNothing
+# define TclWinAddProcess (void (*) (void *, unsigned int)) doNothing
+# define TclWinFlushDirtyChannels doNothing
+# define TclWinResetInterfaces doNothing
+
+static Tcl_Encoding winTCharEncoding;
+
+static int
+TclpIsAtty(int fd)
+{
+ return isatty(fd);
+}
+
+#define TclWinGetPlatformId winGetPlatformId
+static int
+TclWinGetPlatformId()
+{
+ /* Don't bother to determine the real platform on cygwin,
+ * because VER_PLATFORM_WIN32_NT is the only supported platform */
+ return 2; /* VER_PLATFORM_WIN32_NT */;
+}
+
+void *TclWinGetTclInstance()
+{
+ void *hInstance = NULL;
+ GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ (const char *)&winTCharEncoding, &hInstance);
+ return hInstance;
+}
+
+#define TclWinSetSockOpt winSetSockOpt
+static int
+TclWinSetSockOpt(SOCKET s, int level, int optname,
+ const char *optval, int optlen)
+{
+ return setsockopt((int) s, level, optname, optval, optlen);
+}
+
+#define TclWinGetSockOpt winGetSockOpt
+static int
+TclWinGetSockOpt(SOCKET s, int level, int optname,
+ char *optval, int *optlen)
+{
+ return getsockopt((int) s, level, optname, optval, optlen);
+}
+
+#define TclWinGetServByName winGetServByName
+static struct servent *
+TclWinGetServByName(const char *name, const char *proto)
+{
+ return getservbyname(name, proto);
+}
+
+#define TclWinNoBackslash winNoBackslash
+static char *
+TclWinNoBackslash(char *path)
+{
+ char *p;
+
+ for (p = path; *p != '\0'; p++) {
+ if (*p == '\\') {
+ *p = '/';
+ }
+ }
+ return path;
+}
+
+int
+TclpGetPid(Tcl_Pid pid)
+{
+ return (int) (size_t) pid;
+}
+
+static void
+doNothing(void)
+{
+ /* dummy implementation, no need to do anything */
+}
+
+char *
+Tcl_WinUtfToTChar(
+ const char *string,
+ int len,
+ Tcl_DString *dsPtr)
+{
+ if (!winTCharEncoding) {
+ winTCharEncoding = Tcl_GetEncoding(0, "unicode");
+ }
+ return Tcl_UtfToExternalDString(winTCharEncoding,
+ string, len, dsPtr);
+}
+
+char *
+Tcl_WinTCharToUtf(
+ const char *string,
+ int len,
+ Tcl_DString *dsPtr)
+{
+ if (!winTCharEncoding) {
+ winTCharEncoding = Tcl_GetEncoding(0, "unicode");
+ }
+ return Tcl_ExternalToUtfDString(winTCharEncoding,
+ string, len, dsPtr);
+}
+
+#if defined(TCL_WIDE_INT_IS_LONG)
+/* On Cygwin64, long is 64-bit while on Win64 long is 32-bit. Therefore
+ * we have to make sure that all stub entries on Cygwin64 follow the Win64
+ * signature. Tcl 9 must find a better solution, but that cannot be done
+ * without introducing a binary incompatibility.
+ */
+#define Tcl_DbNewLongObj ((Tcl_Obj*(*)(long,const char*,int))dbNewLongObj)
+static Tcl_Obj *dbNewLongObj(
+ int intValue,
+ const char *file,
+ int line
+) {
+#ifdef TCL_MEM_DEBUG
+ register Tcl_Obj *objPtr;
+
+ TclDbNewObj(objPtr, file, line);
+ objPtr->bytes = NULL;
+
+ objPtr->internalRep.longValue = (long) intValue;
+ objPtr->typePtr = &tclIntType;
+ return objPtr;
+#else
+ return Tcl_NewIntObj(intValue);
+#endif
+}
+#define Tcl_GetLongFromObj (int(*)(Tcl_Interp*,Tcl_Obj*,long*))Tcl_GetIntFromObj
+#define Tcl_NewLongObj (Tcl_Obj*(*)(long))Tcl_NewIntObj
+#define Tcl_SetLongObj (void(*)(Tcl_Obj*,long))Tcl_SetIntObj
+static int exprInt(Tcl_Interp *interp, const char *expr, int *ptr){
+ long longValue;
+ int result = Tcl_ExprLong(interp, expr, &longValue);
+ if (result == TCL_OK) {
+ if ((longValue >= -(long)(UINT_MAX))
+ && (longValue <= (long)(UINT_MAX))) {
+ *ptr = (int)longValue;
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "integer value too large to represent as non-long integer", -1));
+ result = TCL_ERROR;
+ }
+ }
+ return result;
+}
+#define Tcl_ExprLong (int(*)(Tcl_Interp*,const char*,long*))exprInt
+static int exprIntObj(Tcl_Interp *interp, Tcl_Obj*expr, int *ptr){
+ long longValue;
+ int result = Tcl_ExprLongObj(interp, expr, &longValue);
+ if (result == TCL_OK) {
+ if ((longValue >= -(long)(UINT_MAX))
+ && (longValue <= (long)(UINT_MAX))) {
+ *ptr = (int)longValue;
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "integer value too large to represent as non-long integer", -1));
+ result = TCL_ERROR;
+ }
+ }
+ return result;
+}
+#define Tcl_ExprLongObj (int(*)(Tcl_Interp*,Tcl_Obj*,long*))exprIntObj
+static int uniCharNcmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct, unsigned int n){
+ return Tcl_UniCharNcmp(ucs, uct, (unsigned long)n);
+}
+#define Tcl_UniCharNcmp (int(*)(const Tcl_UniChar*,const Tcl_UniChar*,unsigned long))uniCharNcmp
+static int utfNcmp(const char *s1, const char *s2, unsigned int n){
+ return Tcl_UtfNcmp(s1, s2, (unsigned long)n);
+}
+#define Tcl_UtfNcmp (int(*)(const char*,const char*,unsigned long))utfNcmp
+static int utfNcasecmp(const char *s1, const char *s2, unsigned int n){
+ return Tcl_UtfNcasecmp(s1, s2, (unsigned long)n);
+}
+#define Tcl_UtfNcasecmp (int(*)(const char*,const char*,unsigned long))utfNcasecmp
+static int uniCharNcasecmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct, unsigned int n){
+ return Tcl_UniCharNcasecmp(ucs, uct, (unsigned long)n);
+}
+#define Tcl_UniCharNcasecmp (int(*)(const Tcl_UniChar*,const Tcl_UniChar*,unsigned long))uniCharNcasecmp
+static int formatInt(char *buffer, int n){
+ return TclFormatInt(buffer, (long)n);
+}
+#define TclFormatInt (int(*)(char *, long))formatInt
+
+#endif
+
+#else /* UNIX and MAC */
+# define TclpLocaltime_unix TclpLocaltime
+# define TclpGmtime_unix TclpGmtime
+#endif
/*
* WARNING: The contents of this file is automatically generated by the
@@ -134,7 +386,7 @@ static const TclIntStubs tclIntStubs = {
TclpGetClicks, /* 75 */
TclpGetSeconds, /* 76 */
TclpGetTime, /* 77 */
- TclpGetTimeZone, /* 78 */
+ 0, /* 78 */
0, /* 79 */
0, /* 80 */
TclpRealloc, /* 81 */
@@ -160,13 +412,13 @@ static const TclIntStubs tclIntStubs = {
TclSetPreInitScript, /* 101 */
TclSetupEnv, /* 102 */
TclSockGetPort, /* 103 */
- TclSockMinimumBuffers, /* 104 */
+ TclSockMinimumBuffersOld, /* 104 */
0, /* 105 */
0, /* 106 */
0, /* 107 */
TclTeardownNamespace, /* 108 */
TclUpdateReturnInfo, /* 109 */
- 0, /* 110 */
+ TclSockMinimumBuffers, /* 110 */
Tcl_AddInterpResolvers, /* 111 */
Tcl_AppendExportList, /* 112 */
Tcl_CreateNamespace, /* 113 */
@@ -214,8 +466,8 @@ static const TclIntStubs tclIntStubs = {
0, /* 155 */
TclRegError, /* 156 */
TclVarTraceExists, /* 157 */
- 0, /* 158 */
- 0, /* 159 */
+ TclSetStartupScriptFileName, /* 158 */
+ TclGetStartupScriptFileName, /* 159 */
0, /* 160 */
TclChannelTransform, /* 161 */
TclChannelEventScriptInvoker, /* 162 */
@@ -223,8 +475,8 @@ static const TclIntStubs tclIntStubs = {
TclExpandCodeArray, /* 164 */
TclpSetInitialEncodings, /* 165 */
TclListObjSetElement, /* 166 */
- 0, /* 167 */
- 0, /* 168 */
+ TclSetStartupScriptPath, /* 167 */
+ TclGetStartupScriptPath, /* 168 */
TclpUtfNcmp2, /* 169 */
TclCheckInterpTraces, /* 170 */
TclCheckExecutionTraces, /* 171 */
@@ -234,8 +486,8 @@ static const TclIntStubs tclIntStubs = {
TclCallVarTraces, /* 175 */
TclCleanupVar, /* 176 */
TclVarErrMsg, /* 177 */
- 0, /* 178 */
- 0, /* 179 */
+ Tcl_SetStartupScript, /* 178 */
+ Tcl_GetStartupScript, /* 179 */
0, /* 180 */
0, /* 181 */
TclpLocaltime, /* 182 */
@@ -292,7 +544,7 @@ static const TclIntStubs tclIntStubs = {
TclGetSrcInfoForPc, /* 233 */
TclVarHashCreateVar, /* 234 */
TclInitVarHashTable, /* 235 */
- 0, /* 236 */
+ TclBackgroundException, /* 236 */
TclResetCancellation, /* 237 */
TclNRInterpProc, /* 238 */
TclNRInterpProcCore, /* 239 */
@@ -307,12 +559,13 @@ static const TclIntStubs tclIntStubs = {
TclCopyChannel, /* 248 */
TclDoubleDigits, /* 249 */
TclSetSlaveCancelFlags, /* 250 */
+ TclRegisterLiteral, /* 251 */
};
static const TclIntPlatStubs tclIntPlatStubs = {
TCL_STUB_MAGIC,
0,
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
TclGetAndDetachPids, /* 0 */
TclpCloseFile, /* 1 */
TclpCreateCommandChannel, /* 2 */
@@ -328,38 +581,55 @@ static const TclIntPlatStubs tclIntPlatStubs = {
TclpGmtime_unix, /* 12 */
TclpInetNtoa, /* 13 */
TclUnixCopyFile, /* 14 */
+ 0, /* 15 */
+ 0, /* 16 */
+ 0, /* 17 */
+ 0, /* 18 */
+ 0, /* 19 */
+ 0, /* 20 */
+ 0, /* 21 */
+ 0, /* 22 */
+ 0, /* 23 */
+ 0, /* 24 */
+ 0, /* 25 */
+ 0, /* 26 */
+ 0, /* 27 */
+ 0, /* 28 */
+ TclWinCPUID, /* 29 */
+ TclUnixOpenTemporaryFile, /* 30 */
#endif /* UNIX */
-#ifdef __WIN32__ /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
TclWinConvertError, /* 0 */
TclWinConvertWSAError, /* 1 */
TclWinGetServByName, /* 2 */
TclWinGetSockOpt, /* 3 */
TclWinGetTclInstance, /* 4 */
- 0, /* 5 */
+ TclUnixWaitForFile, /* 5 */
TclWinNToHS, /* 6 */
TclWinSetSockOpt, /* 7 */
TclpGetPid, /* 8 */
TclWinGetPlatformId, /* 9 */
- 0, /* 10 */
+ TclpReaddir, /* 10 */
TclGetAndDetachPids, /* 11 */
TclpCloseFile, /* 12 */
TclpCreateCommandChannel, /* 13 */
TclpCreatePipe, /* 14 */
TclpCreateProcess, /* 15 */
- 0, /* 16 */
- 0, /* 17 */
+ TclpIsAtty, /* 16 */
+ TclUnixCopyFile, /* 17 */
TclpMakeFile, /* 18 */
TclpOpenFile, /* 19 */
TclWinAddProcess, /* 20 */
- 0, /* 21 */
+ TclpInetNtoa, /* 21 */
TclpCreateTempFile, /* 22 */
- TclpGetTZName, /* 23 */
+ 0, /* 23 */
TclWinNoBackslash, /* 24 */
0, /* 25 */
TclWinSetInterfaces, /* 26 */
TclWinFlushDirtyChannels, /* 27 */
TclWinResetInterfaces, /* 28 */
TclWinCPUID, /* 29 */
+ TclUnixOpenTemporaryFile, /* 30 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
TclGetAndDetachPids, /* 0 */
@@ -382,13 +652,24 @@ static const TclIntPlatStubs tclIntPlatStubs = {
TclMacOSXCopyFileAttributes, /* 17 */
TclMacOSXMatchType, /* 18 */
TclMacOSXNotifierAddRunLoopMode, /* 19 */
+ 0, /* 20 */
+ 0, /* 21 */
+ 0, /* 22 */
+ 0, /* 23 */
+ 0, /* 24 */
+ 0, /* 25 */
+ 0, /* 26 */
+ 0, /* 27 */
+ 0, /* 28 */
+ TclWinCPUID, /* 29 */
+ TclUnixOpenTemporaryFile, /* 30 */
#endif /* MACOSX */
};
static const TclPlatStubs tclPlatStubs = {
TCL_STUB_MAGIC,
0,
-#ifdef __WIN32__ /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
Tcl_WinUtfToTChar, /* 0 */
Tcl_WinTCharToUtf, /* 1 */
#endif /* WIN */
@@ -485,19 +766,19 @@ const TclStubs tclStubs = {
Tcl_DbCkalloc, /* 6 */
Tcl_DbCkfree, /* 7 */
Tcl_DbCkrealloc, /* 8 */
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
Tcl_CreateFileHandler, /* 9 */
#endif /* UNIX */
-#ifdef __WIN32__ /* WIN */
+#if defined(_WIN32) /* WIN */
0, /* 9 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
Tcl_CreateFileHandler, /* 9 */
#endif /* MACOSX */
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
Tcl_DeleteFileHandler, /* 10 */
#endif /* UNIX */
-#ifdef __WIN32__ /* WIN */
+#if defined(_WIN32) /* WIN */
0, /* 10 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
@@ -659,10 +940,10 @@ const TclStubs tclStubs = {
Tcl_GetMaster, /* 164 */
Tcl_GetNameOfExecutable, /* 165 */
Tcl_GetObjResult, /* 166 */
-#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
Tcl_GetOpenFile, /* 167 */
#endif /* UNIX */
-#ifdef __WIN32__ /* WIN */
+#if defined(_WIN32) /* WIN */
0, /* 167 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
@@ -1130,6 +1411,7 @@ const TclStubs tclStubs = {
Tcl_LoadFile, /* 627 */
Tcl_FindSymbol, /* 628 */
Tcl_FSUnloadFile, /* 629 */
+ Tcl_ZlibStreamSetCompressionDictionary, /* 630 */
};
/* !END!: Do not edit above this line. */
diff --git a/generic/tclStubLib.c b/generic/tclStubLib.c
index f569820..859cbf9 100644
--- a/generic/tclStubLib.c
+++ b/generic/tclStubLib.c
@@ -11,15 +11,6 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-/*
- * We need to ensure that we use the stub macros so that this file contains no
- * references to any of the stub functions. This will make it possible to
- * build an extension that references Tcl_InitStubs but doesn't end up
- * including the rest of the stub functions.
- */
-
-#define USE_TCL_STUBS
-
#include "tclInt.h"
MODULE_SCOPE const TclStubs *tclStubsPtr;
@@ -32,24 +23,8 @@ const TclPlatStubs *tclPlatStubsPtr = NULL;
const TclIntStubs *tclIntStubsPtr = NULL;
const TclIntPlatStubs *tclIntPlatStubsPtr = NULL;
-static const TclStubs *
-HasStubSupport(
- Tcl_Interp *interp)
-{
- Interp *iPtr = (Interp *) interp;
-
- if (iPtr->stubTable && (iPtr->stubTable->magic == TCL_STUB_MAGIC)) {
- return iPtr->stubTable;
- }
-
- iPtr->result =
- (char *)"This interpreter does not support stubs-enabled extensions.";
- iPtr->freeProc = TCL_STATIC;
- return NULL;
-}
-
/*
- * Use our own isdigit to avoid linking to libc on windows
+ * Use our own isDigit to avoid linking to libc on windows
*/
static int isDigit(const int c)
@@ -74,15 +49,17 @@ static int isDigit(const int c)
*
*----------------------------------------------------------------------
*/
-
+#undef Tcl_InitStubs
MODULE_SCOPE const char *
Tcl_InitStubs(
Tcl_Interp *interp,
const char *version,
int exact)
{
+ Interp *iPtr = (Interp *) interp;
const char *actualVersion = NULL;
ClientData pkgData = NULL;
+ const TclStubs *stubsPtr = iPtr->stubTable;
/*
* We can't optimize this check by caching tclStubsPtr because that
@@ -90,12 +67,13 @@ Tcl_InitStubs(
* times. [Bug 615304]
*/
- tclStubsPtr = HasStubSupport(interp);
- if (!tclStubsPtr) {
+ if (!stubsPtr || (stubsPtr->magic != TCL_STUB_MAGIC)) {
+ iPtr->result = "interpreter uses an incompatible stubs mechanism";
+ iPtr->freeProc = TCL_STATIC;
return NULL;
}
- actualVersion = Tcl_PkgRequireEx(interp, "Tcl", version, 0, &pkgData);
+ actualVersion = stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 0, &pkgData);
if (actualVersion == NULL) {
return NULL;
}
@@ -113,19 +91,19 @@ Tcl_InitStubs(
while (*p && (*p == *q)) {
p++; q++;
}
- if (*p) {
+ if (*p || isDigit(*q)) {
/* Construct error message */
- Tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL);
+ stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL);
return NULL;
}
} else {
- actualVersion = Tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL);
+ actualVersion = stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL);
if (actualVersion == NULL) {
return NULL;
}
}
}
- tclStubsPtr = (TclStubs *) pkgData;
+ tclStubsPtr = (TclStubs *)pkgData;
if (tclStubsPtr->hooks) {
tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs;
diff --git a/generic/tclStubLibTbl.c b/generic/tclStubLibTbl.c
new file mode 100644
index 0000000..0391502
--- /dev/null
+++ b/generic/tclStubLibTbl.c
@@ -0,0 +1,58 @@
+/*
+ * tclStubLibTbl.c --
+ *
+ * Stub object that will be statically linked into extensions that want
+ * to access Tcl.
+ *
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ * Copyright (c) 1998 Paul Duffin.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitStubTable --
+ *
+ * Initialize the stub table, using the structure pointed at
+ * by the "version" argument.
+ *
+ * Results:
+ * Outputs the value of the "version" argument.
+ *
+ * Side effects:
+ * Sets the stub table pointers.
+ *
+ *----------------------------------------------------------------------
+ */
+MODULE_SCOPE const char *
+TclInitStubTable(
+ const char *version) /* points to the version field of a
+ TclStubInfoType structure variable. */
+{
+ tclStubsPtr = ((const TclStubInfoType *) version)->stubs;
+
+ if (tclStubsPtr->hooks) {
+ tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs;
+ tclIntStubsPtr = tclStubsPtr->hooks->tclIntStubs;
+ tclIntPlatStubsPtr = tclStubsPtr->hooks->tclIntPlatStubs;
+ } else {
+ tclPlatStubsPtr = NULL;
+ tclIntStubsPtr = NULL;
+ tclIntPlatStubsPtr = NULL;
+ }
+
+ return version;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclTest.c b/generic/tclTest.c
index bac0c7f..a27c95a 100644
--- a/generic/tclTest.c
+++ b/generic/tclTest.c
@@ -15,14 +15,14 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include <math.h>
-
#undef STATIC_BUILD
#ifndef USE_TCL_STUBS
# define USE_TCL_STUBS
#endif
#include "tclInt.h"
#include "tclOO.h"
+#include <math.h>
+
/*
* Required for Testregexp*Cmd
*/
@@ -75,6 +75,8 @@ typedef struct TestAsyncHandler {
/* Next is list of handlers. */
} TestAsyncHandler;
+TCL_DECLARE_MUTEX(asyncTestMutex)
+
static TestAsyncHandler *firstHandler = NULL;
/*
@@ -306,9 +308,8 @@ static int TestexitmainloopCmd(ClientData dummy,
Tcl_Interp *interp, int argc, const char **argv);
static int TestpanicCmd(ClientData dummy,
Tcl_Interp *interp, int argc, const char **argv);
-static int TestfinexitObjCmd(ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *const objv[]);
+static int TestparseargsCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
static int TestparserObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
@@ -326,10 +327,12 @@ static int TestreturnObjCmd(ClientData dummy,
Tcl_Obj *const objv[]);
static void TestregexpXflags(const char *string,
int length, int *cflagsPtr, int *eflagsPtr);
+#ifndef TCL_NO_DEPRECATED
static int TestsaveresultCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
static void TestsaveresultFree(char *blockPtr);
+#endif /* TCL_NO_DEPRECATED */
static int TestsetassocdataCmd(ClientData dummy,
Tcl_Interp *interp, int argc, const char **argv);
static int TestsetCmd(ClientData dummy,
@@ -380,7 +383,8 @@ static Tcl_FSRenameFileProc TestReportRenameFile;
static Tcl_FSCreateDirectoryProc TestReportCreateDirectory;
static Tcl_FSCopyDirectoryProc TestReportCopyDirectory;
static Tcl_FSRemoveDirectoryProc TestReportRemoveDirectory;
-static Tcl_FSLoadFileProc TestReportLoadFile;
+static int TestReportLoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr,
+ Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr);
static Tcl_FSLinkProc TestReportLink;
static Tcl_FSFileAttrStringsProc TestReportFileAttrStrings;
static Tcl_FSFileAttrsGetProc TestReportFileAttrsGet;
@@ -407,6 +411,14 @@ static int TestHashSystemHashCmd(ClientData clientData,
static int TestNRELevels(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
+static int TestInterpResolverCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+#if defined(HAVE_CPUID) || defined(_WIN32)
+static int TestcpuidCmd(ClientData dummy,
+ Tcl_Interp* interp, int objc,
+ Tcl_Obj *const objv[]);
+#endif
static const Tcl_Filesystem testReportingFilesystem = {
"reporting",
@@ -437,7 +449,7 @@ static const Tcl_Filesystem testReportingFilesystem = {
TestReportRenameFile,
TestReportCopyDirectory,
TestReportLstat,
- TestReportLoadFile,
+ (Tcl_FSLoadFileProc *) TestReportLoadFile,
NULL /* cwd */,
TestReportChdir
};
@@ -513,7 +525,9 @@ int
Tcltest_Init(
Tcl_Interp *interp) /* Interpreter for application. */
{
+#ifndef TCL_NO_DEPRECATED
Tcl_ValueType t3ArgTypes[2];
+#endif /* TCL_NO_DEPRECATED */
Tcl_Obj *listPtr;
Tcl_Obj **objv;
@@ -621,7 +635,7 @@ Tcltest_Init(
Tcl_CreateObjCommand(interp, "testlocale", TestlocaleCmd, NULL,
NULL);
Tcl_CreateCommand(interp, "testpanic", TestpanicCmd, NULL, NULL);
- Tcl_CreateObjCommand(interp, "testfinexit", TestfinexitObjCmd, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "testparseargs", TestparseargsCmd,NULL,NULL);
Tcl_CreateObjCommand(interp, "testparser", TestparserObjCmd,
NULL, NULL);
Tcl_CreateObjCommand(interp, "testparsevar", TestparsevarObjCmd,
@@ -632,8 +646,10 @@ Tcltest_Init(
NULL, NULL);
Tcl_CreateObjCommand(interp, "testreturn", TestreturnObjCmd,
NULL, NULL);
+#ifndef TCL_NO_DEPRECATED
Tcl_CreateObjCommand(interp, "testsaveresult", TestsaveresultCmd,
NULL, NULL);
+#endif /* TCL_NO_DEPRECATED */
Tcl_CreateCommand(interp, "testsetassocdata", TestsetassocdataCmd,
NULL, NULL);
Tcl_CreateCommand(interp, "testsetnoerr", TestsetCmd,
@@ -655,21 +671,31 @@ Tcltest_Init(
Tcl_CreateCommand(interp, "testtranslatefilename",
TesttranslatefilenameCmd, NULL, NULL);
Tcl_CreateCommand(interp, "testupvar", TestupvarCmd, NULL, NULL);
+#ifndef TCL_NO_DEPRECATED
Tcl_CreateMathFunc(interp, "T1", 0, NULL, TestMathFunc, (ClientData) 123);
Tcl_CreateMathFunc(interp, "T2", 0, NULL, TestMathFunc, (ClientData) 345);
+#endif /* TCL_NO_DEPRECATED */
Tcl_CreateCommand(interp, "testmainthread", TestmainthreadCmd, NULL,
NULL);
Tcl_CreateCommand(interp, "testsetmainloop", TestsetmainloopCmd,
NULL, NULL);
Tcl_CreateCommand(interp, "testexitmainloop", TestexitmainloopCmd,
NULL, NULL);
+#if defined(HAVE_CPUID) || defined(_WIN32)
+ Tcl_CreateObjCommand(interp, "testcpuid", TestcpuidCmd,
+ (ClientData) 0, NULL);
+#endif
+#ifndef TCL_NO_DEPRECATED
t3ArgTypes[0] = TCL_EITHER;
t3ArgTypes[1] = TCL_EITHER;
Tcl_CreateMathFunc(interp, "T3", 2, t3ArgTypes, TestMathFunc2,
NULL);
+#endif /* TCL_NO_DEPRECATED */
Tcl_CreateObjCommand(interp, "testnrelevels", TestNRELevels,
NULL, NULL);
+ Tcl_CreateObjCommand(interp, "testinterpresolver", TestInterpResolverCmd,
+ NULL, NULL);
if (TclObjTest_Init(interp) != TCL_OK) {
return TCL_ERROR;
@@ -791,17 +817,20 @@ TestasyncCmd(
goto wrongNumArgs;
}
asyncPtr = ckalloc(sizeof(TestAsyncHandler));
+ asyncPtr->command = ckalloc(strlen(argv[2]) + 1);
+ strcpy(asyncPtr->command, argv[2]);
+ Tcl_MutexLock(&asyncTestMutex);
asyncPtr->id = nextId;
nextId++;
asyncPtr->handler = Tcl_AsyncCreate(AsyncHandlerProc,
- (ClientData) asyncPtr);
- asyncPtr->command = ckalloc(strlen(argv[2]) + 1);
- strcpy(asyncPtr->command, argv[2]);
+ INT2PTR(asyncPtr->id));
asyncPtr->nextPtr = firstHandler;
firstHandler = asyncPtr;
+ Tcl_MutexUnlock(&asyncTestMutex);
Tcl_SetObjResult(interp, Tcl_NewIntObj(asyncPtr->id));
} else if (strcmp(argv[1], "delete") == 0) {
if (argc == 2) {
+ Tcl_MutexLock(&asyncTestMutex);
while (firstHandler != NULL) {
asyncPtr = firstHandler;
firstHandler = asyncPtr->nextPtr;
@@ -809,6 +838,7 @@ TestasyncCmd(
ckfree(asyncPtr->command);
ckfree(asyncPtr);
}
+ Tcl_MutexUnlock(&asyncTestMutex);
return TCL_OK;
}
if (argc != 3) {
@@ -817,6 +847,7 @@ TestasyncCmd(
if (Tcl_GetInt(interp, argv[2], &id) != TCL_OK) {
return TCL_ERROR;
}
+ Tcl_MutexLock(&asyncTestMutex);
for (prevPtr = NULL, asyncPtr = firstHandler; asyncPtr != NULL;
prevPtr = asyncPtr, asyncPtr = asyncPtr->nextPtr) {
if (asyncPtr->id != id) {
@@ -832,6 +863,7 @@ TestasyncCmd(
ckfree(asyncPtr);
break;
}
+ Tcl_MutexUnlock(&asyncTestMutex);
} else if (strcmp(argv[1], "mark") == 0) {
if (argc != 5) {
goto wrongNumArgs;
@@ -840,6 +872,7 @@ TestasyncCmd(
|| (Tcl_GetInt(interp, argv[4], &code) != TCL_OK)) {
return TCL_ERROR;
}
+ Tcl_MutexLock(&asyncTestMutex);
for (asyncPtr = firstHandler; asyncPtr != NULL;
asyncPtr = asyncPtr->nextPtr) {
if (asyncPtr->id == id) {
@@ -848,6 +881,7 @@ TestasyncCmd(
}
}
Tcl_SetObjResult(interp, Tcl_NewStringObj(argv[3], -1));
+ Tcl_MutexUnlock(&asyncTestMutex);
return code;
#ifdef TCL_THREADS
} else if (strcmp(argv[1], "marklater") == 0) {
@@ -857,19 +891,22 @@ TestasyncCmd(
if (Tcl_GetInt(interp, argv[2], &id) != TCL_OK) {
return TCL_ERROR;
}
+ Tcl_MutexLock(&asyncTestMutex);
for (asyncPtr = firstHandler; asyncPtr != NULL;
asyncPtr = asyncPtr->nextPtr) {
if (asyncPtr->id == id) {
Tcl_ThreadId threadID;
if (Tcl_CreateThread(&threadID, AsyncThreadProc,
- (ClientData) asyncPtr, TCL_THREAD_STACK_DEFAULT,
+ INT2PTR(id), TCL_THREAD_STACK_DEFAULT,
TCL_THREAD_NOFLAGS) != TCL_OK) {
Tcl_SetResult(interp, "can't create thread", TCL_STATIC);
+ Tcl_MutexUnlock(&asyncTestMutex);
return TCL_ERROR;
}
break;
}
}
+ Tcl_MutexUnlock(&asyncTestMutex);
} else {
Tcl_AppendResult(interp, "bad option \"", argv[1],
"\": must be create, delete, int, mark, or marklater", NULL);
@@ -886,15 +923,29 @@ TestasyncCmd(
static int
AsyncHandlerProc(
- ClientData clientData, /* Pointer to TestAsyncHandler structure. */
+ ClientData clientData, /* If of TestAsyncHandler structure.
+ * in global list. */
Tcl_Interp *interp, /* Interpreter in which command was
* executed, or NULL. */
int code) /* Current return code from command. */
{
- TestAsyncHandler *asyncPtr = (TestAsyncHandler *) clientData;
+ TestAsyncHandler *asyncPtr;
+ int id = PTR2INT(clientData);
const char *listArgv[4], *cmd;
char string[TCL_INTEGER_SPACE];
+ Tcl_MutexLock(&asyncTestMutex);
+ for (asyncPtr = firstHandler; asyncPtr != NULL;
+ asyncPtr = asyncPtr->nextPtr) {
+ if (asyncPtr->id == id) break;
+ }
+ Tcl_MutexUnlock(&asyncTestMutex);
+
+ if (!asyncPtr) {
+ /* Woops - this one was deleted between the AsyncMark and now */
+ return TCL_OK;
+ }
+
TclFormatInt(string, code);
listArgv[0] = asyncPtr->command;
listArgv[1] = Tcl_GetString(Tcl_GetObjResult(interp));
@@ -932,12 +983,22 @@ AsyncHandlerProc(
#ifdef TCL_THREADS
static Tcl_ThreadCreateType
AsyncThreadProc(
- ClientData clientData) /* Parameter is a pointer to a
+ ClientData clientData) /* Parameter is the id of a
* TestAsyncHandler, defined above. */
{
- TestAsyncHandler *asyncPtr = clientData;
+ TestAsyncHandler *asyncPtr;
+ int id = PTR2INT(clientData);
+
Tcl_Sleep(1);
- Tcl_AsyncMark(asyncPtr->handler);
+ Tcl_MutexLock(&asyncTestMutex);
+ for (asyncPtr = firstHandler; asyncPtr != NULL;
+ asyncPtr = asyncPtr->nextPtr) {
+ if (asyncPtr->id == id) {
+ Tcl_AsyncMark(asyncPtr->handler);
+ break;
+ }
+ }
+ Tcl_MutexUnlock(&asyncTestMutex);
Tcl_ExitThread(TCL_OK);
TCL_THREAD_CREATE_RETURN;
}
@@ -1494,14 +1555,14 @@ DelCallbackProc(
*
* TestdelCmd --
*
- * This procedure implements the "testdcall" command. It is used
- * to test Tcl_CallWhenDeleted.
+ * This procedure implements the "testdel" command. It is used
+ * to test calling of command deletion callbacks.
*
* Results:
* A standard Tcl result.
*
* Side effects:
- * Creates and deletes interpreters.
+ * Creates a command.
*
*----------------------------------------------------------------------
*/
@@ -1795,7 +1856,7 @@ TestdstringCmd(
if (Tcl_GetInt(interp, argv[2], &count) != TCL_OK) {
return TCL_ERROR;
}
- Tcl_DStringTrunc(&dstring, count);
+ Tcl_DStringSetLength(&dstring, count);
} else if (strcmp(argv[1], "start") == 0) {
if (argc != 2) {
goto wrongNumArgs;
@@ -3217,7 +3278,7 @@ TestlocaleCmd(
"ctype", "numeric", "time", "collate", "monetary",
"all", NULL
};
- static int lcTypes[] = {
+ static const int lcTypes[] = {
LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY,
LC_ALL
};
@@ -4347,8 +4408,26 @@ TestseterrorcodeCmd(
Tcl_SetResult(interp, "too many args", TCL_STATIC);
return TCL_ERROR;
}
- Tcl_SetErrorCode(interp, argv[1], argv[2], argv[3], argv[4],
- argv[5], NULL);
+ switch (argc) {
+ case 1:
+ Tcl_SetErrorCode(interp, "NONE", NULL);
+ break;
+ case 2:
+ Tcl_SetErrorCode(interp, argv[1], NULL);
+ break;
+ case 3:
+ Tcl_SetErrorCode(interp, argv[1], argv[2], NULL);
+ break;
+ case 4:
+ Tcl_SetErrorCode(interp, argv[1], argv[2], argv[3], NULL);
+ break;
+ case 5:
+ Tcl_SetErrorCode(interp, argv[1], argv[2], argv[3], argv[4], NULL);
+ break;
+ case 6:
+ Tcl_SetErrorCode(interp, argv[1], argv[2], argv[3], argv[4],
+ argv[5], NULL);
+ }
return TCL_ERROR;
}
@@ -4493,47 +4572,6 @@ TestpanicCmd(
return TCL_OK;
}
-/*
- *----------------------------------------------------------------------
- *
- * TestfinexitObjCmd --
- *
- * Calls a variant of [exit] including the full finalization path.
- *
- * Results:
- * Error, or doesn't return.
- *
- * Side effects:
- * Exits application.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-TestfinexitObjCmd(
- ClientData dummy, /* Not used. */
- Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
- Tcl_Obj *const objv[]) /* Argument objects. */
-{
- int value;
-
- if ((objc != 1) && (objc != 2)) {
- Tcl_WrongNumArgs(interp, 1, objv, "?returnCode?");
- return TCL_ERROR;
- }
-
- if (objc == 1) {
- value = 0;
- } else if (Tcl_GetIntFromObj(interp, objv[1], &value) != TCL_OK) {
- return TCL_ERROR;
- }
- Tcl_Finalize();
- TclpExit(value);
- /*NOTREACHED*/
- return TCL_ERROR; /* Better not ever reach this! */
-}
-
static int
TestfileCmd(
ClientData dummy, /* Not used. */
@@ -4993,6 +5031,7 @@ Testset2Cmd(
}
}
+#ifndef TCL_NO_DEPRECATED
/*
*----------------------------------------------------------------------
*
@@ -5126,6 +5165,7 @@ TestsaveresultFree(
{
freeCount++;
}
+#endif /* TCL_NO_DEPRECATED */
/*
*----------------------------------------------------------------------
@@ -6160,7 +6200,7 @@ TestReport(
* API, but there you go. We should convert it to objects.
*/
- Tcl_SavedResult savedResult;
+ Tcl_Obj *savedResult;
Tcl_DString ds;
Tcl_DStringInit(&ds);
@@ -6174,11 +6214,15 @@ TestReport(
Tcl_DStringAppendElement(&ds, Tcl_GetString(arg2));
}
Tcl_DStringEndSublist(&ds);
- Tcl_SaveResult(interp, &savedResult);
+ savedResult = Tcl_GetObjResult(interp);
+ Tcl_IncrRefCount(savedResult);
+ Tcl_SetObjResult(interp, Tcl_NewObj());
Tcl_Eval(interp, Tcl_DStringValue(&ds));
Tcl_DStringFree(&ds);
- Tcl_RestoreResult(interp, &savedResult);
- }
+ Tcl_ResetResult(interp);
+ Tcl_SetObjResult(interp, savedResult);
+ Tcl_DecrRefCount(savedResult);
+ }
}
static int
@@ -6603,6 +6647,62 @@ TestNumUtfCharsCmd(
}
return TCL_OK;
}
+
+#if defined(HAVE_CPUID) || defined(_WIN32)
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestcpuidCmd --
+ *
+ * Retrieves CPU ID information.
+ *
+ * Usage:
+ * testwincpuid <eax>
+ *
+ * Parameters:
+ * eax - The value to pass in the EAX register to a CPUID instruction.
+ *
+ * Results:
+ * Returns a four-element list containing the values from the EAX, EBX,
+ * ECX and EDX registers returned from the CPUID instruction.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestcpuidCmd(
+ ClientData dummy,
+ Tcl_Interp* interp, /* Tcl interpreter */
+ int objc, /* Parameter count */
+ Tcl_Obj *const * objv) /* Parameter vector */
+{
+ int status, index, i;
+ unsigned int regs[4];
+ Tcl_Obj *regsObjs[4];
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "eax");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIntFromObj(interp, objv[1], &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ status = TclWinCPUID((unsigned) index, regs);
+ if (status != TCL_OK) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj("operation not available", -1));
+ return status;
+ }
+ for (i=0 ; i<4 ; ++i) {
+ regsObjs[i] = Tcl_NewIntObj((int) regs[i]);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewListObj(4, regsObjs));
+ return TCL_OK;
+}
+#endif
/*
* Used to do basic checks of the TCL_HASH_KEY_SYSTEM_HASH flag
@@ -7050,9 +7150,245 @@ TestconcatobjCmd(
}
/*
+ *----------------------------------------------------------------------
+ *
+ * TestparseargsCmd --
+ *
+ * This procedure implements the "testparseargs" command. It is used to
+ * test that Tcl_ParseArgsObjv does indeed return the right number of
+ * arguments. In other words, that [Bug 3413857] was fixed properly.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestparseargsCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Arguments. */
+{
+ static int foo = 0;
+ int count = objc;
+ Tcl_Obj **remObjv, *result[3];
+ Tcl_ArgvInfo argTable[] = {
+ {TCL_ARGV_CONSTANT, "-bool", INT2PTR(1), &foo, "booltest", NULL},
+ TCL_ARGV_AUTO_REST, TCL_ARGV_AUTO_HELP, TCL_ARGV_TABLE_END
+ };
+
+ foo = 0;
+ if (Tcl_ParseArgsObjv(interp, argTable, &count, objv, &remObjv)!=TCL_OK) {
+ return TCL_ERROR;
+ }
+ result[0] = Tcl_NewIntObj(foo);
+ result[1] = Tcl_NewIntObj(count);
+ result[2] = Tcl_NewListObj(count, remObjv);
+ Tcl_SetObjResult(interp, Tcl_NewListObj(3, result));
+ ckfree(remObjv);
+ return TCL_OK;
+}
+
+/**
+ * Test harness for command and variable resolvers.
+ */
+
+static int
+InterpCmdResolver(
+ Tcl_Interp *interp,
+ const char *name,
+ Tcl_Namespace *context,
+ int flags,
+ Tcl_Command *rPtr)
+{
+ Interp *iPtr = (Interp *) interp;
+ CallFrame *varFramePtr = iPtr->varFramePtr;
+ Proc *procPtr = (varFramePtr->isProcCallFrame & FRAME_IS_PROC) ?
+ varFramePtr->procPtr : NULL;
+ Namespace *ns2NsPtr = (Namespace *)
+ Tcl_FindNamespace(interp, "::ns2", NULL, 0);
+
+ if (procPtr && (procPtr->cmdPtr->nsPtr == iPtr->globalNsPtr
+ || (ns2NsPtr && procPtr->cmdPtr->nsPtr == ns2NsPtr))) {
+ const char *callingCmdName =
+ Tcl_GetCommandName(interp, (Tcl_Command) procPtr->cmdPtr);
+
+ if ((callingCmdName[0] == 'x') && (callingCmdName[1] == '\0')
+ && (name[0] == 'z') && (name[1] == '\0')) {
+ Tcl_Command sourceCmdPtr = Tcl_FindCommand(interp, "y", NULL,
+ TCL_GLOBAL_ONLY);
+
+ if (sourceCmdPtr != NULL) {
+ *rPtr = sourceCmdPtr;
+ return TCL_OK;
+ }
+ }
+ }
+ return TCL_CONTINUE;
+}
+
+static int
+InterpVarResolver(
+ Tcl_Interp *interp,
+ const char *name,
+ Tcl_Namespace *context,
+ int flags,
+ Tcl_Var *rPtr)
+{
+ /*
+ * Don't resolve the variable; use standard rules.
+ */
+
+ return TCL_CONTINUE;
+}
+
+typedef struct MyResolvedVarInfo {
+ Tcl_ResolvedVarInfo vInfo; /* This must be the first element. */
+ Tcl_Var var;
+ Tcl_Obj *nameObj;
+} MyResolvedVarInfo;
+
+static inline void
+HashVarFree(
+ Tcl_Var var)
+{
+ if (VarHashRefCount(var) < 2) {
+ ckfree(var);
+ } else {
+ VarHashRefCount(var)--;
+ }
+}
+
+static void
+MyCompiledVarFree(
+ Tcl_ResolvedVarInfo *vInfoPtr)
+{
+ MyResolvedVarInfo *resVarInfo = (MyResolvedVarInfo *) vInfoPtr;
+
+ Tcl_DecrRefCount(resVarInfo->nameObj);
+ if (resVarInfo->var) {
+ HashVarFree(resVarInfo->var);
+ }
+ ckfree(vInfoPtr);
+}
+
+#define TclVarHashGetValue(hPtr) \
+ ((Var *) ((char *)hPtr - TclOffset(VarInHash, entry)))
+
+static Tcl_Var
+MyCompiledVarFetch(
+ Tcl_Interp *interp,
+ Tcl_ResolvedVarInfo *vinfoPtr)
+{
+ MyResolvedVarInfo *resVarInfo = (MyResolvedVarInfo *) vinfoPtr;
+ Tcl_Var var = resVarInfo->var;
+ int isNewVar;
+ Interp *iPtr = (Interp *) interp;
+ Tcl_HashEntry *hPtr;
+
+ if (var != NULL) {
+ if (!(((Var *) var)->flags & VAR_DEAD_HASH)) {
+ /*
+ * The cached variable is valid, return it.
+ */
+
+ return var;
+ }
+
+ /*
+ * The variable is not valid anymore. Clean it up.
+ */
+
+ HashVarFree(var);
+ }
+
+ hPtr = Tcl_CreateHashEntry((Tcl_HashTable *) &iPtr->globalNsPtr->varTable,
+ (char *) resVarInfo->nameObj, &isNewVar);
+ if (hPtr) {
+ var = (Tcl_Var) TclVarHashGetValue(hPtr);
+ } else {
+ var = NULL;
+ }
+ resVarInfo->var = var;
+
+ /*
+ * Increment the reference counter to avoid ckfree() of the variable in
+ * Tcl's FreeVarEntry(); for cleanup, we provide our own HashVarFree();
+ */
+
+ VarHashRefCount(var)++;
+ return var;
+}
+
+static int
+InterpCompiledVarResolver(
+ Tcl_Interp *interp,
+ const char *name,
+ int length,
+ Tcl_Namespace *context,
+ Tcl_ResolvedVarInfo **rPtr)
+{
+ if (*name == 'T') {
+ MyResolvedVarInfo *resVarInfo = ckalloc(sizeof(MyResolvedVarInfo));
+
+ resVarInfo->vInfo.fetchProc = MyCompiledVarFetch;
+ resVarInfo->vInfo.deleteProc = MyCompiledVarFree;
+ resVarInfo->var = NULL;
+ resVarInfo->nameObj = Tcl_NewStringObj(name, -1);
+ Tcl_IncrRefCount(resVarInfo->nameObj);
+ *rPtr = &resVarInfo->vInfo;
+ return TCL_OK;
+ }
+ return TCL_CONTINUE;
+}
+
+static int
+TestInterpResolverCmd(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ static const char *const table[] = {
+ "down", "up", NULL
+ };
+ int idx;
+#define RESOLVER_KEY "testInterpResolver"
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "up|down");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[1], table, "operation", TCL_EXACT,
+ &idx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch (idx) {
+ case 1: /* up */
+ Tcl_AddInterpResolvers(interp, RESOLVER_KEY, InterpCmdResolver,
+ InterpVarResolver, InterpCompiledVarResolver);
+ break;
+ case 0: /*down*/
+ if (!Tcl_RemoveInterpResolvers(interp, RESOLVER_KEY)) {
+ Tcl_AppendResult(interp, "could not remove the resolver scheme",
+ NULL);
+ return TCL_ERROR;
+ }
+ }
+ return TCL_OK;
+}
+
+/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
+ * tab-width: 8
+ * indent-tabs-mode: nil
* End:
*/
diff --git a/generic/tclTestObj.c b/generic/tclTestObj.c
index 7494beb..f36b07f 100644
--- a/generic/tclTestObj.c
+++ b/generic/tclTestObj.c
@@ -555,7 +555,7 @@ TestindexobjCmd(
}
Tcl_GetIndexFromObj(NULL, objv[1], tablePtr, "token", 0, &index);
- indexRep = objv[1]->internalRep.otherValuePtr;
+ indexRep = objv[1]->internalRep.twoPtrValue.ptr1;
indexRep->index = index2;
result = Tcl_GetIndexFromObj(NULL, objv[1],
tablePtr, "token", 0, &index);
@@ -592,7 +592,7 @@ TestindexobjCmd(
if (objv[3]->typePtr != NULL
&& !strcmp("index", objv[3]->typePtr->name)) {
- indexRep = objv[3]->internalRep.otherValuePtr;
+ indexRep = objv[3]->internalRep.twoPtrValue.ptr1;
if (indexRep->tablePtr == (void *) argv) {
TclFreeIntRep(objv[3]);
}
@@ -963,6 +963,17 @@ TestobjCmd(
}
SetVarToObj(varPtr, destIndex, varPtr[varIndex]);
Tcl_SetObjResult(interp, varPtr[destIndex]);
+ } else if (strcmp(subCmd, "bug3598580") == 0) {
+ Tcl_Obj *listObjPtr, *elemObjPtr;
+ if (objc != 2) {
+ goto wrongNumArgs;
+ }
+ elemObjPtr = Tcl_NewIntObj(123);
+ listObjPtr = Tcl_NewListObj(1, &elemObjPtr);
+ /* Replace the single list element through itself, nonsense but legal. */
+ Tcl_ListObjReplace(interp, listObjPtr, 0, 1, 1, &elemObjPtr);
+ Tcl_SetObjResult(interp, listObjPtr);
+ return TCL_OK;
} else if (strcmp(subCmd, "convert") == 0) {
const char *typeName;
@@ -1239,7 +1250,7 @@ TeststringobjCmd(
if (varPtr[varIndex] != NULL) {
Tcl_ConvertToType(NULL, varPtr[varIndex],
Tcl_GetObjType("string"));
- strPtr = varPtr[varIndex]->internalRep.otherValuePtr;
+ strPtr = varPtr[varIndex]->internalRep.twoPtrValue.ptr1;
length = (int) strPtr->allocated;
} else {
length = -1;
@@ -1293,7 +1304,7 @@ TeststringobjCmd(
if (varPtr[varIndex] != NULL) {
Tcl_ConvertToType(NULL, varPtr[varIndex],
Tcl_GetObjType("string"));
- strPtr = varPtr[varIndex]->internalRep.otherValuePtr;
+ strPtr = varPtr[varIndex]->internalRep.twoPtrValue.ptr1;
length = strPtr->maxChars;
} else {
length = -1;
diff --git a/generic/tclThread.c b/generic/tclThread.c
index d1f2691..8c972a8 100644
--- a/generic/tclThread.c
+++ b/generic/tclThread.c
@@ -339,8 +339,9 @@ Tcl_ConditionFinalize(
*
* TclFinalizeThreadData --
*
- * This function cleans up the thread-local storage. This is called once
- * for each thread.
+ * This function cleans up the thread-local storage. Secondary, it cleans
+ * thread alloc cache.
+ * This is called once for each thread before thread exits.
*
* Results:
* None.
@@ -355,6 +356,9 @@ void
TclFinalizeThreadData(void)
{
TclFinalizeThreadDataThread();
+#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
+ TclFinalizeThreadAllocThread();
+#endif
}
/*
diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c
index ad1d510..ddf888a 100644
--- a/generic/tclThreadAlloc.c
+++ b/generic/tclThreadAlloc.c
@@ -573,7 +573,7 @@ TclThreadAllocObj(void)
}
while (--numMove >= 0) {
objPtr = &newObjsPtr[numMove];
- objPtr->internalRep.otherValuePtr = cachePtr->firstObjPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr;
cachePtr->firstObjPtr = objPtr;
}
}
@@ -584,7 +584,7 @@ TclThreadAllocObj(void)
*/
objPtr = cachePtr->firstObjPtr;
- cachePtr->firstObjPtr = objPtr->internalRep.otherValuePtr;
+ cachePtr->firstObjPtr = objPtr->internalRep.twoPtrValue.ptr1;
cachePtr->numObjects--;
return objPtr;
}
@@ -621,7 +621,7 @@ TclThreadFreeObj(
* Get this thread's list and push on the free Tcl_Obj.
*/
- objPtr->internalRep.otherValuePtr = cachePtr->firstObjPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr;
cachePtr->firstObjPtr = objPtr;
cachePtr->numObjects++;
@@ -722,16 +722,16 @@ MoveObjs(
*/
while (--numMove) {
- objPtr = objPtr->internalRep.otherValuePtr;
+ objPtr = objPtr->internalRep.twoPtrValue.ptr1;
}
- fromPtr->firstObjPtr = objPtr->internalRep.otherValuePtr;
+ fromPtr->firstObjPtr = objPtr->internalRep.twoPtrValue.ptr1;
/*
* Move all objects as a block - they are already linked to each other, we
* just have to update the first and last.
*/
- objPtr->internalRep.otherValuePtr = toPtr->firstObjPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = toPtr->firstObjPtr;
toPtr->firstObjPtr = fromFirstObjPtr;
}
@@ -812,15 +812,7 @@ LockBucket(
Cache *cachePtr,
int bucket)
{
-#if 0
- if (Tcl_MutexTryLock(bucketInfo[bucket].lockPtr) != TCL_OK) {
- Tcl_MutexLock(bucketInfo[bucket].lockPtr);
- cachePtr->buckets[bucket].numWaits++;
- sharedPtr->buckets[bucket].numWaits++;
- }
-#else
Tcl_MutexLock(bucketInfo[bucket].lockPtr);
-#endif
cachePtr->buckets[bucket].numLocks++;
sharedPtr->buckets[bucket].numLocks++;
}
@@ -1031,6 +1023,33 @@ TclFinalizeThreadAlloc(void)
TclpFreeAllocCache(NULL);
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeThreadAllocThread --
+ *
+ * This procedure is used to destroy single thread private resources used
+ * in this file.
+ * Called in TclpFinalizeThreadData when a thread exits (Tcl_FinalizeThread).
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeThreadAllocThread(void)
+{
+ Cache *cachePtr = TclpGetAllocCache();
+ if (cachePtr != NULL) {
+ TclpFreeAllocCache(cachePtr);
+ }
+}
+
#else /* !(TCL_THREADS && USE_THREAD_ALLOC) */
/*
*----------------------------------------------------------------------
diff --git a/generic/tclThreadJoin.c b/generic/tclThreadJoin.c
index 4b09e1c..5c70a62 100644
--- a/generic/tclThreadJoin.c
+++ b/generic/tclThreadJoin.c
@@ -14,7 +14,7 @@
#include "tclInt.h"
-#ifdef WIN32
+#ifdef _WIN32
/*
* The information about each joinable thread is remembered in a structure as
@@ -305,7 +305,7 @@ TclSignalExitThread(
Tcl_MutexUnlock(&threadPtr->threadMutex);
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
/*
* Local Variables:
diff --git a/generic/tclThreadTest.c b/generic/tclThreadTest.c
index 71d5a66..02ee038 100644
--- a/generic/tclThreadTest.c
+++ b/generic/tclThreadTest.c
@@ -46,7 +46,7 @@ static Tcl_ThreadDataKey dataKey;
* protected by threadMutex.
*/
-static ThreadSpecificData *threadList;
+static ThreadSpecificData *threadList = NULL;
/*
* The following bit-values are legal for the "flags" field of the
@@ -337,7 +337,7 @@ ThreadObjCmd(
*/
if (objc == 2) {
- idObj = Tcl_NewLongObj((long)(size_t)Tcl_GetCurrentThread());
+ idObj = Tcl_NewWideIntObj((Tcl_WideInt)(size_t)Tcl_GetCurrentThread());
} else if (objc == 3
&& strcmp("-main", Tcl_GetString(objv[2])) == 0) {
Tcl_MutexLock(&threadMutex);
@@ -355,14 +355,14 @@ ThreadObjCmd(
return TCL_ERROR;
}
case THREAD_JOIN: {
- long id;
+ Tcl_WideInt id;
int result, status;
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "id");
return TCL_ERROR;
}
- if (Tcl_GetLongFromObj(interp, objv[2], &id) != TCL_OK) {
+ if (Tcl_GetWideIntFromObj(interp, objv[2], &id) != TCL_OK) {
return TCL_ERROR;
}
@@ -372,7 +372,7 @@ ThreadObjCmd(
} else {
char buf[20];
- TclFormatInt(buf, id);
+ sprintf(buf, "%" TCL_LL_MODIFIER "d", id);
Tcl_AppendResult(interp, "cannot join thread ", buf, NULL);
}
return result;
@@ -384,7 +384,7 @@ ThreadObjCmd(
}
return ThreadList(interp);
case THREAD_SEND: {
- long id;
+ Tcl_WideInt id;
const char *script;
int wait, arg;
@@ -403,7 +403,7 @@ ThreadObjCmd(
wait = 1;
arg = 2;
}
- if (Tcl_GetLongFromObj(interp, objv[arg], &id) != TCL_OK) {
+ if (Tcl_GetWideIntFromObj(interp, objv[arg], &id) != TCL_OK) {
return TCL_ERROR;
}
arg++;
@@ -513,7 +513,6 @@ ThreadCreate(
TCL_THREAD_STACK_DEFAULT, joinable) != TCL_OK) {
Tcl_MutexUnlock(&threadMutex);
Tcl_AppendResult(interp, "can't create a new thread", NULL);
- ckfree(ctrl.script);
return TCL_ERROR;
}
@@ -524,7 +523,7 @@ ThreadCreate(
Tcl_ConditionWait(&ctrl.condWait, &threadMutex, NULL);
Tcl_MutexUnlock(&threadMutex);
Tcl_ConditionFinalize(&ctrl.condWait);
- Tcl_SetObjResult(interp, Tcl_NewLongObj((long)(size_t)id));
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)(size_t)id));
return TCL_OK;
}
@@ -623,9 +622,9 @@ NewTestThread(
* Clean up.
*/
- ListRemove(tsdPtr);
- Tcl_Release(tsdPtr->interp);
Tcl_DeleteInterp(tsdPtr->interp);
+ Tcl_Release(tsdPtr->interp);
+ ListRemove(tsdPtr);
Tcl_ExitThread(result);
TCL_THREAD_CREATE_RETURN;
@@ -656,7 +655,7 @@ ThreadErrorProc(
char *script;
char buf[TCL_DOUBLE_SPACE+1];
- TclFormatInt(buf, (size_t) Tcl_GetCurrentThread());
+ sprintf(buf, "%" TCL_LL_MODIFIER "d", (Tcl_WideInt)(size_t)Tcl_GetCurrentThread());
errorInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
if (errorProcString == NULL) {
@@ -744,6 +743,7 @@ ListRemove(
tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr;
}
tsdPtr->nextPtr = tsdPtr->prevPtr = 0;
+ tsdPtr->interp = NULL;
Tcl_MutexUnlock(&threadMutex);
}
@@ -773,7 +773,7 @@ ThreadList(
Tcl_MutexLock(&threadMutex);
for (tsdPtr = threadList ; tsdPtr ; tsdPtr = tsdPtr->nextPtr) {
Tcl_ListObjAppendElement(interp, listPtr,
- Tcl_NewLongObj((long)(size_t)tsdPtr->threadId));
+ Tcl_NewWideIntObj((Tcl_WideInt)(size_t)tsdPtr->threadId));
}
Tcl_MutexUnlock(&threadMutex);
Tcl_SetObjResult(interp, listPtr);
@@ -926,10 +926,11 @@ ThreadSend(
ckfree(resultPtr->errorInfo);
}
}
- Tcl_SetResult(interp, resultPtr->result, TCL_DYNAMIC);
+ Tcl_AppendResult(interp, resultPtr->result, NULL);
Tcl_ConditionFinalize(&resultPtr->done);
code = resultPtr->code;
+ ckfree(resultPtr->result);
ckfree(resultPtr);
return code;
@@ -987,7 +988,8 @@ ThreadCancel(
Tcl_MutexUnlock(&threadMutex);
Tcl_ResetResult(interp);
- return Tcl_CancelEval(tsdPtr->interp, Tcl_NewStringObj(result, -1), 0, flags);
+ return Tcl_CancelEval(tsdPtr->interp,
+ (result != NULL) ? Tcl_NewStringObj(result, -1) : NULL, 0, flags);
}
/*
@@ -1148,6 +1150,11 @@ ThreadExitProc(
char *threadEvalScript = clientData;
ThreadEventResult *resultPtr, *nextPtr;
Tcl_ThreadId self = Tcl_GetCurrentThread();
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+ if (tsdPtr->interp != NULL) {
+ ListRemove(tsdPtr);
+ }
Tcl_MutexLock(&threadMutex);
diff --git a/generic/tclTimer.c b/generic/tclTimer.c
index cf91dca..c10986a 100644
--- a/generic/tclTimer.c
+++ b/generic/tclTimer.c
@@ -182,8 +182,7 @@ static void TimerSetupProc(ClientData clientData, int flags);
static ThreadSpecificData *
InitTimer(void)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- TclThreadDataKeyGet(&dataKey);
+ ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey);
if (tsdPtr == NULL) {
tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -214,8 +213,7 @@ static void
TimerExitProc(
ClientData clientData) /* Not used. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- TclThreadDataKeyGet(&dataKey);
+ ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey);
Tcl_DeleteEventSource(TimerSetupProc, TimerCheckProc, NULL);
if (tsdPtr != NULL) {
@@ -297,9 +295,8 @@ TclCreateAbsoluteTimerHandler(
ClientData clientData)
{
register TimerHandler *timerHandlerPtr, *tPtr2, *prevPtr;
- ThreadSpecificData *tsdPtr;
+ ThreadSpecificData *tsdPtr = InitTimer();
- tsdPtr = InitTimer();
timerHandlerPtr = ckalloc(sizeof(TimerHandler));
/*
@@ -822,7 +819,7 @@ Tcl_AfterObjCmd(
*/
if (objv[1]->typePtr == &tclIntType
-#ifndef NO_WIDE_TYPE
+#ifndef TCL_WIDE_INT_IS_LONG
|| objv[1]->typePtr == &tclWideIntType
#endif
|| objv[1]->typePtr == &tclBignumType
@@ -832,8 +829,9 @@ Tcl_AfterObjCmd(
if (Tcl_GetWideIntFromObj(NULL, objv[1], &ms) != TCL_OK) {
const char *arg = Tcl_GetString(objv[1]);
- Tcl_AppendResult(interp, "bad argument \"", arg,
- "\": must be cancel, idle, info, or an integer", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad argument \"%s\": must be"
+ " cancel, idle, info, or an integer", arg));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "argument",
arg, NULL);
return TCL_ERROR;
@@ -971,8 +969,8 @@ Tcl_AfterObjCmd(
if (afterPtr == NULL) {
const char *eventStr = TclGetString(objv[2]);
- Tcl_AppendResult(interp, "event \"", eventStr, "\" doesn't exist",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "event \"%s\" doesn't exist", eventStr));
Tcl_SetErrorCode(interp, "TCL","LOOKUP","EVENT", eventStr, NULL);
return TCL_ERROR;
} else {
diff --git a/generic/tclTomMath.decls b/generic/tclTomMath.decls
index 29a6a03..ea3abb1 100644
--- a/generic/tclTomMath.decls
+++ b/generic/tclTomMath.decls
@@ -213,11 +213,11 @@ declare 60 {
int TclBN_s_mp_sub(mp_int *a, mp_int *b, mp_int *c)
}
declare 61 {
- int TclBN_mp_init_set_int(mp_int* a, unsigned long i)
+ int TclBN_mp_init_set_int(mp_int *a, unsigned long i)
}
declare 62 {
- int TclBN_mp_set_int(mp_int* a, unsigned long i)
+ int TclBN_mp_set_int(mp_int *a, unsigned long i)
}
declare 63 {
- int TclBN_mp_cnt_lsb(const mp_int* a)
+ int TclBN_mp_cnt_lsb(const mp_int *a)
}
diff --git a/generic/tclTomMath.h b/generic/tclTomMath.h
index eca435f..dd9edaf 100644
--- a/generic/tclTomMath.h
+++ b/generic/tclTomMath.h
@@ -15,7 +15,6 @@
#ifndef BN_H_
#define BN_H_
-#include "tclInt.h"
#include "tclTomMathDecls.h"
#ifndef MODULE_SCOPE
#define MODULE_SCOPE extern
diff --git a/generic/tclTomMathDecls.h b/generic/tclTomMathDecls.h
index feaefb3..69b095c 100644
--- a/generic/tclTomMathDecls.h
+++ b/generic/tclTomMathDecls.h
@@ -134,6 +134,10 @@
/* !BEGIN!: Do not edit below this line. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Exported function declarations:
*/
@@ -270,15 +274,15 @@ EXTERN int TclBN_s_mp_sqr(mp_int *a, mp_int *b);
/* 60 */
EXTERN int TclBN_s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
/* 61 */
-EXTERN int TclBN_mp_init_set_int(mp_int*a, unsigned long i);
+EXTERN int TclBN_mp_init_set_int(mp_int *a, unsigned long i);
/* 62 */
-EXTERN int TclBN_mp_set_int(mp_int*a, unsigned long i);
+EXTERN int TclBN_mp_set_int(mp_int *a, unsigned long i);
/* 63 */
-EXTERN int TclBN_mp_cnt_lsb(const mp_int*a);
+EXTERN int TclBN_mp_cnt_lsb(const mp_int *a);
typedef struct TclTomMathStubs {
int magic;
- const struct TclTomMathStubHooks *hooks;
+ void *hooks;
int (*tclBN_epoch) (void); /* 0 */
int (*tclBN_revision) (void); /* 1 */
@@ -341,15 +345,13 @@ typedef struct TclTomMathStubs {
int (*tclBN_s_mp_mul_digs) (mp_int *a, mp_int *b, mp_int *c, int digs); /* 58 */
int (*tclBN_s_mp_sqr) (mp_int *a, mp_int *b); /* 59 */
int (*tclBN_s_mp_sub) (mp_int *a, mp_int *b, mp_int *c); /* 60 */
- int (*tclBN_mp_init_set_int) (mp_int*a, unsigned long i); /* 61 */
- int (*tclBN_mp_set_int) (mp_int*a, unsigned long i); /* 62 */
- int (*tclBN_mp_cnt_lsb) (const mp_int*a); /* 63 */
+ int (*tclBN_mp_init_set_int) (mp_int *a, unsigned long i); /* 61 */
+ int (*tclBN_mp_set_int) (mp_int *a, unsigned long i); /* 62 */
+ int (*tclBN_mp_cnt_lsb) (const mp_int *a); /* 63 */
} TclTomMathStubs;
-#ifdef __cplusplus
-extern "C" {
-#endif
extern const TclTomMathStubs *tclTomMathStubsPtr;
+
#ifdef __cplusplus
}
#endif
diff --git a/generic/tclTomMathInt.h b/generic/tclTomMathInt.h
index 1b9eb64..831f13f 100644
--- a/generic/tclTomMathInt.h
+++ b/generic/tclTomMathInt.h
@@ -1,2 +1,3 @@
+#include "tclInt.h"
#include "tclTomMath.h"
#include "tommath_class.h"
diff --git a/generic/tclTomMathInterface.c b/generic/tclTomMathInterface.c
index 775e86b..48db8c3 100644
--- a/generic/tclTomMathInterface.c
+++ b/generic/tclTomMathInterface.c
@@ -111,7 +111,7 @@ extern void *
TclBNAlloc(
size_t x)
{
- return (void *) Tcl_Alloc((unsigned int) x);
+ return (void *) ckalloc((unsigned int) x);
}
/*
@@ -135,7 +135,7 @@ TclBNRealloc(
void *p,
size_t s)
{
- return (void *) Tcl_Realloc((char *) p, (unsigned int) s);
+ return (void *) ckrealloc((char *) p, (unsigned int) s);
}
/*
@@ -161,7 +161,7 @@ extern void
TclBNFree(
void *p)
{
- Tcl_Free((char *) p);
+ ckree((char *) p);
}
#endif
diff --git a/generic/tclTomMathStubLib.c b/generic/tclTomMathStubLib.c
index e7e4aea..324f2a3 100644
--- a/generic/tclTomMathStubLib.c
+++ b/generic/tclTomMathStubLib.c
@@ -11,15 +11,6 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-/*
- * We need to ensure that we use the stub macros so that this file contains no
- * references to any of the stub functions. This will make it possible to
- * build an extension that references Tcl_InitStubs but doesn't end up
- * including the rest of the stub functions.
- */
-
-#define USE_TCL_STUBS
-
#include "tclInt.h"
MODULE_SCOPE const TclTomMathStubs *tclTomMathStubsPtr;
@@ -55,31 +46,30 @@ TclTomMathInitializeStubs(
int exact = 0;
const char *packageName = "tcl::tommath";
const char *errMsg = NULL;
- ClientData pkgClientData = NULL;
- const char *actualVersion =
- Tcl_PkgRequireEx(interp, packageName, version, exact, &pkgClientData);
- const TclTomMathStubs *stubsPtr = pkgClientData;
+ TclTomMathStubs *stubsPtr = NULL;
+ const char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
+ packageName, version, exact, &stubsPtr);
if (actualVersion == NULL) {
return NULL;
}
- if (pkgClientData == NULL) {
+ if (stubsPtr == NULL) {
errMsg = "missing stub table pointer";
- } else if ((stubsPtr->tclBN_epoch)() != epoch) {
+ } else if(stubsPtr->tclBN_epoch() != epoch) {
errMsg = "epoch number mismatch";
- } else if ((stubsPtr->tclBN_revision)() != revision) {
+ } else if(stubsPtr->tclBN_revision() != revision) {
errMsg = "requires a later revision";
} else {
tclTomMathStubsPtr = stubsPtr;
return actualVersion;
}
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "error loading ", packageName,
+ tclStubsPtr->tcl_ResetResult(interp);
+ tclStubsPtr->tcl_AppendResult(interp, "Error loading ", packageName,
" (requested version ", version, ", actual version ",
actualVersion, "): ", errMsg, NULL);
return NULL;
}
-
+
/*
* Local Variables:
* mode: c
diff --git a/generic/tclTrace.c b/generic/tclTrace.c
index 13359ee..c0cde49 100644
--- a/generic/tclTrace.c
+++ b/generic/tclTrace.c
@@ -113,7 +113,7 @@ static const char *const traceTypeOptions[] = {
static Tcl_TraceTypeObjCmd *const traceSubCmds[] = {
TraceExecutionObjCmd,
TraceCommandObjCmd,
- TraceVariableObjCmd,
+ TraceVariableObjCmd
};
/*
@@ -155,8 +155,8 @@ typedef struct StringTraceData {
#define FOREACH_VAR_TRACE(interp, name, clientData) \
(clientData) = NULL; \
- while (((clientData) = Tcl_VarTraceInfo((interp), (name), 0, \
- TraceVarProc, (clientData))) != NULL)
+ while (((clientData) = Tcl_VarTraceInfo2((interp), (name), NULL, \
+ 0, TraceVarProc, (clientData))) != NULL)
#define FOREACH_COMMAND_TRACE(interp, name, clientData) \
(clientData) = NULL; \
@@ -366,8 +366,9 @@ Tcl_TraceObjCmd(
return TCL_OK;
badVarOps:
- Tcl_AppendResult(interp, "bad operations \"", flagOps,
- "\": should be one or more of rwua", NULL);
+ 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;
}
@@ -434,9 +435,9 @@ TraceExecutionObjCmd(
return result;
}
if (listLen == 0) {
- Tcl_SetResult(interp, "bad operation list \"\": must be "
- "one or more of enter, leave, enterstep, or leavestep",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "bad operation list \"\": must be one or more of"
+ " enter, leave, enterstep, or leavestep", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRACE", "NOOPS",
NULL);
return TCL_ERROR;
@@ -677,8 +678,9 @@ TraceCommandObjCmd(
return result;
}
if (listLen == 0) {
- Tcl_SetResult(interp, "bad operation list \"\": must be "
- "one or more of delete or rename", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "bad operation list \"\": must be one or more of"
+ " delete or rename", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRACE", "NOOPS",
NULL);
return TCL_ERROR;
@@ -875,8 +877,9 @@ TraceVariableObjCmd(
return result;
}
if (listLen == 0) {
- Tcl_SetResult(interp, "bad operation list \"\": must be "
- "one or more of array, read, unset, or write", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "bad operation list \"\": must be one or more of"
+ " array, read, unset, or write", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRACE", "NOOPS",
NULL);
return TCL_ERROR;
@@ -1124,8 +1127,18 @@ Tcl_TraceCommand(
tracePtr->refCount = 1;
cmdPtr->tracePtr = tracePtr;
if (tracePtr->flags & TCL_TRACE_ANY_EXEC) {
+ /*
+ * Bug 3484621: up the interp's epoch if this is a BC'ed command
+ */
+
+ if ((cmdPtr->compileProc != NULL) && !(cmdPtr->flags & CMD_HAS_EXEC_TRACES)){
+ Interp *iPtr = (Interp *) interp;
+ iPtr->compileEpoch++;
+ }
cmdPtr->flags |= CMD_HAS_EXEC_TRACES;
}
+
+
return TCL_OK;
}
@@ -1228,6 +1241,15 @@ Tcl_UntraceCommand(
*/
cmdPtr->flags &= ~CMD_HAS_EXEC_TRACES;
+
+ /*
+ * Bug 3484621: up the interp's epoch if this is a BC'ed command
+ */
+
+ if (cmdPtr->compileProc != NULL) {
+ Interp *iPtr = (Interp *) interp;
+ iPtr->compileEpoch++;
+ }
}
}
@@ -1279,9 +1301,9 @@ TraceCommandProc(
Tcl_DStringAppendElement(&cmd, oldName);
Tcl_DStringAppendElement(&cmd, (newName ? newName : ""));
if (flags & TCL_TRACE_RENAME) {
- Tcl_DStringAppend(&cmd, " rename", 7);
+ TclDStringAppendLiteral(&cmd, " rename");
} else if (flags & TCL_TRACE_DELETE) {
- Tcl_DStringAppend(&cmd, " delete", 7);
+ TclDStringAppendLiteral(&cmd, " delete");
}
/*
@@ -1300,7 +1322,7 @@ TraceCommandProc(
Tcl_DStringLength(&cmd), 0);
if (code != TCL_OK) {
/* We ignore errors in these traced commands */
- /*** QUESTION: Use Tcl_BackgroundError(interp); instead? ***/
+ /*** QUESTION: Use Tcl_BackgroundException(interp, code); instead? ***/
}
Tcl_DStringFree(&cmd);
}
@@ -1463,7 +1485,11 @@ TclCheckExecutionTraces(
}
iPtr->activeCmdTracePtr = active.nextPtr;
if (state) {
- Tcl_RestoreInterpState(interp, state);
+ if (traceCode == TCL_OK) {
+ (void) Tcl_RestoreInterpState(interp, state);
+ } else {
+ Tcl_DiscardInterpState(state);
+ }
}
return traceCode;
@@ -1975,24 +2001,24 @@ TraceVarProc(
#ifndef TCL_REMOVE_OBSOLETE_TRACES
if (tvarPtr->flags & TCL_TRACE_OLD_STYLE) {
if (flags & TCL_TRACE_ARRAY) {
- Tcl_DStringAppend(&cmd, " a", 2);
+ TclDStringAppendLiteral(&cmd, " a");
} else if (flags & TCL_TRACE_READS) {
- Tcl_DStringAppend(&cmd, " r", 2);
+ TclDStringAppendLiteral(&cmd, " r");
} else if (flags & TCL_TRACE_WRITES) {
- Tcl_DStringAppend(&cmd, " w", 2);
+ TclDStringAppendLiteral(&cmd, " w");
} else if (flags & TCL_TRACE_UNSETS) {
- Tcl_DStringAppend(&cmd, " u", 2);
+ TclDStringAppendLiteral(&cmd, " u");
}
} else {
#endif
if (flags & TCL_TRACE_ARRAY) {
- Tcl_DStringAppend(&cmd, " array", 6);
+ TclDStringAppendLiteral(&cmd, " array");
} else if (flags & TCL_TRACE_READS) {
- Tcl_DStringAppend(&cmd, " read", 5);
+ TclDStringAppendLiteral(&cmd, " read");
} else if (flags & TCL_TRACE_WRITES) {
- Tcl_DStringAppend(&cmd, " write", 6);
+ TclDStringAppendLiteral(&cmd, " write");
} else if (flags & TCL_TRACE_UNSETS) {
- Tcl_DStringAppend(&cmd, " unset", 6);
+ TclDStringAppendLiteral(&cmd, " unset");
}
#ifndef TCL_REMOVE_OBSOLETE_TRACES
}
@@ -2558,7 +2584,7 @@ TclCallVarTraces(
char *newPart1;
Tcl_DStringInit(&nameCopy);
- Tcl_DStringAppend(&nameCopy, part1, (p-part1));
+ Tcl_DStringAppend(&nameCopy, part1, p-part1);
newPart1 = Tcl_DStringValue(&nameCopy);
newPart1[offset] = 0;
part1 = newPart1;
@@ -2696,7 +2722,8 @@ TclCallVarTraces(
if (disposeFlags & TCL_TRACE_RESULT_OBJECT) {
Tcl_SetObjResult((Tcl_Interp *)iPtr, (Tcl_Obj *) result);
} else {
- Tcl_SetResult((Tcl_Interp *)iPtr, result, TCL_STATIC);
+ Tcl_SetObjResult((Tcl_Interp *)iPtr,
+ Tcl_NewStringObj(result, -1));
}
Tcl_AddErrorInfo((Tcl_Interp *)iPtr, "");
@@ -2788,6 +2815,7 @@ DisposeTraceResult(
*----------------------------------------------------------------------
*/
+#undef Tcl_UntraceVar
void
Tcl_UntraceVar(
Tcl_Interp *interp, /* Interpreter containing variable. */
@@ -2956,6 +2984,7 @@ Tcl_UntraceVar2(
*----------------------------------------------------------------------
*/
+#undef Tcl_VarTraceInfo
ClientData
Tcl_VarTraceInfo(
Tcl_Interp *interp, /* Interpreter containing variable. */
@@ -3064,6 +3093,7 @@ Tcl_VarTraceInfo2(
*----------------------------------------------------------------------
*/
+#undef Tcl_TraceVar
int
Tcl_TraceVar(
Tcl_Interp *interp, /* Interpreter in which variable is to be
diff --git a/generic/tclUniData.c b/generic/tclUniData.c
index 83b3058..a0d4ccc 100644
--- a/generic/tclUniData.c
+++ b/generic/tclUniData.c
@@ -24,134 +24,520 @@
*/
static const unsigned short pageMap[] = {
- 0, 1, 2, 3, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 7, 15, 16, 17,
- 18, 19, 20, 21, 22, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 7, 32,
- 7, 33, 7, 7, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 42, 42, 45,
- 46, 47, 48, 49, 42, 42, 50, 51, 52, 53, 54, 55, 56, 56, 56, 56, 56,
- 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 61,
- 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 84, 88,
- 89, 90, 91, 92, 93, 94, 95, 96, 97, 56, 98, 99, 100, 56, 101, 102,
- 103, 104, 105, 106, 107, 56, 42, 108, 109, 110, 111, 112, 113, 114,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 115, 42, 116, 117, 118, 42,
- 119, 42, 120, 121, 122, 42, 42, 123, 124, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 125, 126, 42, 42, 127,
- 128, 129, 130, 131, 42, 132, 133, 134, 135, 42, 136, 137, 42, 138,
- 42, 139, 140, 141, 142, 143, 42, 144, 145, 146, 147, 42, 148, 149,
- 150, 151, 56, 56, 152, 153, 154, 155, 156, 157, 42, 158, 42, 159, 160,
- 161, 56, 56, 162, 163, 164, 165, 166, 167, 168, 166, 22, 169, 7, 7,
- 7, 7, 170, 7, 7, 7, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
- 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
- 195, 195, 195, 195, 195, 195, 195, 195, 196, 197, 146, 198, 199, 200,
- 201, 202, 146, 203, 204, 205, 206, 207, 208, 209, 146, 146, 146, 146,
- 146, 210, 211, 212, 146, 146, 146, 213, 146, 146, 146, 146, 214, 146,
- 146, 215, 216, 146, 217, 218, 146, 146, 146, 146, 146, 146, 146, 146,
- 195, 195, 195, 195, 219, 195, 220, 221, 195, 195, 195, 195, 195, 195,
- 195, 195, 146, 222, 223, 56, 56, 56, 56, 56, 224, 225, 226, 227, 7,
- 7, 7, 228, 229, 230, 42, 231, 232, 233, 233, 22, 234, 235, 56, 56,
- 236, 146, 146, 237, 146, 146, 146, 146, 146, 146, 238, 239, 240, 241,
- 95, 42, 242, 124, 42, 243, 244, 245, 42, 42, 246, 247, 146, 248, 249,
- 250, 251, 146, 250, 251, 146, 249, 146, 146, 146, 146, 146, 146, 146,
- 146, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 139, 146, 146, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 252, 56, 253,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 254, 146, 255, 161, 42, 42, 42, 42, 42, 42, 42, 42, 256, 257, 7,
- 258, 259, 42, 42, 260, 261, 262, 7, 263, 264, 265, 56, 266, 267, 268,
- 42, 269, 270, 271, 272, 273, 51, 274, 275, 140, 57, 276, 277, 56, 42,
- 278, 279, 280, 42, 281, 282, 56, 283, 284, 56, 56, 56, 56, 42, 285,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 286, 287, 288, 289, 289, 289, 289,
- 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289,
- 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289,
- 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289,
- 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289,
- 289, 289, 289, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 291, 42, 291, 42, 42, 292, 56, 293, 294, 295, 42, 42, 296,
- 297, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 298, 299, 42, 300, 42,
- 301, 302, 303, 304, 305, 306, 42, 42, 42, 307, 308, 2, 309, 310, 311,
- 312, 313, 314
+ 0, 32, 64, 96, 0, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416,
+ 448, 224, 480, 512, 544, 576, 608, 640, 672, 704, 704, 736, 768, 800,
+ 832, 864, 896, 928, 960, 992, 224, 1024, 224, 1056, 224, 224, 1088,
+ 1120, 1152, 1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1344, 1344,
+ 1440, 1472, 1504, 1536, 1568, 1344, 1344, 1600, 1632, 1664, 1696, 1728,
+ 1760, 1792, 1792, 1824, 1792, 1856, 1888, 1920, 1952, 1984, 2016, 2048,
+ 2080, 2112, 2144, 2176, 2208, 2240, 2272, 2304, 2336, 2368, 2016, 2400,
+ 2432, 2464, 2496, 2528, 2560, 2592, 2624, 2656, 2688, 2720, 2752, 2784,
+ 2816, 2848, 2752, 2880, 2912, 2944, 2976, 3008, 3040, 3072, 3104, 3136,
+ 3168, 1792, 3200, 3232, 3264, 1792, 3296, 3328, 3360, 3392, 3424, 3456,
+ 3488, 1792, 1344, 3520, 3552, 3584, 3616, 3648, 3680, 3712, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 3744, 1344, 3776, 3808,
+ 3840, 1344, 3872, 1344, 3904, 3936, 3968, 1344, 1344, 4000, 4032, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 4064, 4096, 1344, 1344, 4128, 4160, 4192,
+ 4224, 4256, 1344, 4288, 4320, 4352, 4384, 1344, 4416, 4448, 1344, 4480,
+ 1344, 4512, 4544, 4576, 4608, 4640, 1344, 4672, 4704, 4736, 4768, 1344,
+ 4800, 4832, 4864, 4896, 1792, 1792, 4928, 4960, 4992, 5024, 5056, 5088,
+ 1344, 5120, 1344, 5152, 5184, 5216, 1792, 1792, 5248, 5280, 5312, 5344,
+ 5376, 5408, 5440, 5376, 704, 5472, 224, 224, 224, 224, 5504, 224, 224,
+ 224, 5536, 5568, 5600, 5632, 5664, 5696, 5728, 5760, 5792, 5824, 5856,
+ 5888, 5920, 5952, 5984, 6016, 6048, 6080, 6112, 6144, 6176, 6208, 6240,
+ 6272, 6304, 6304, 6304, 6304, 6304, 6304, 6304, 6304, 6336, 6368, 4736,
+ 6400, 6432, 6464, 6496, 6528, 4736, 6560, 6592, 6624, 6656, 6688, 6720,
+ 6752, 4736, 4736, 4736, 4736, 4736, 6784, 6816, 6848, 4736, 4736, 4736,
+ 6880, 4736, 4736, 4736, 4736, 6912, 4736, 4736, 6944, 6976, 4736, 7008,
+ 7040, 4736, 4736, 4736, 4736, 4736, 4736, 4736, 4736, 6304, 6304, 6304,
+ 6304, 7072, 6304, 7104, 7136, 6304, 6304, 6304, 6304, 6304, 6304, 6304,
+ 6304, 4736, 7168, 7200, 1792, 1792, 1792, 1792, 1792, 7232, 7264, 7296,
+ 7328, 224, 224, 224, 7360, 7392, 7424, 1344, 7456, 7488, 7520, 7520,
+ 704, 7552, 7584, 1792, 1792, 7616, 4736, 4736, 7648, 4736, 4736, 4736,
+ 4736, 4736, 4736, 7680, 7712, 7744, 7776, 3104, 1344, 7808, 4032, 1344,
+ 7840, 7872, 7904, 1344, 1344, 7936, 7968, 4736, 8000, 8032, 8064, 8096,
+ 4736, 8064, 8128, 4736, 8032, 4736, 4736, 4736, 4736, 4736, 4736, 4736,
+ 4736, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 4512, 4736, 4736, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 8160,
+ 1792, 8192, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 8224, 4736, 8256, 5216, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 8288, 8320, 224, 8352, 8384, 1344, 1344, 8416, 8448, 8480, 224,
+ 8512, 8544, 8576, 1792, 8608, 8640, 8672, 1344, 8704, 8736, 8768, 8800,
+ 8832, 1632, 8864, 8896, 4544, 1888, 8928, 8960, 1792, 1344, 8992, 9024,
+ 9056, 1344, 9088, 9120, 9152, 9184, 9216, 1792, 1792, 1792, 1792, 1344,
+ 9248, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 9280, 9312, 9344, 9376, 9376, 9376, 9376, 9376, 9376, 9376,
+ 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376,
+ 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376,
+ 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376,
+ 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376,
+ 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408,
+ 9408, 9408, 9408, 9408, 9408, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 9440, 1344, 1344, 9472, 1792, 9504, 9536, 9568,
+ 1344, 1344, 9600, 9632, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 9664, 9696, 1344, 9728, 1344, 9760, 9792, 9824, 9856, 9888,
+ 9920, 1344, 1344, 1344, 9952, 9984, 64, 10016, 10048, 10080, 10112,
+ 10144, 10176
+#if TCL_UTF_MAX > 3
+ ,10208, 10240, 10272, 1792, 1344, 1344, 1344, 7968, 10304, 10336, 10368,
+ 10400, 10432, 1792, 10464, 10496, 1792, 1792, 1792, 1792, 4544, 1344,
+ 10528, 1792, 10112, 10560, 10592, 1792, 10624, 1344, 10656, 1792, 10688,
+ 10720, 10752, 1344, 10784, 10816, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 10848, 10880, 10912,
+ 1792, 1792, 1792, 1792, 1792, 10944, 10976, 1792, 1792, 1344, 11008,
+ 1792, 1792, 11040, 11072, 11104, 11136, 1792, 1792, 1792, 1792, 1344,
+ 11168, 11200, 11232, 1792, 1792, 1792, 1792, 1344, 1344, 11264, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 11296, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 11328, 11360, 11392, 11424, 5056, 11456,
+ 11488, 11520, 11552, 11584, 11616, 1792, 5056, 11648, 11680, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1344, 11712, 10816, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 11744, 1792, 1792,
+ 1792, 1792, 10368, 10368, 10368, 11776, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 11744, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 11808, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1344, 1344, 11840, 11872, 11904, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 11936,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 4736, 4736, 4736, 4736, 4736, 4736, 4736, 7680, 4736,
+ 11968, 4736, 12000, 12032, 12064, 12096, 1792, 4736, 4736, 12128, 1792,
+ 1792, 1792, 1792, 1792, 4736, 4736, 12160, 12192, 1792, 1792, 1792,
+ 1792, 12224, 12256, 12288, 12320, 12352, 12384, 12416, 12448, 12480,
+ 12512, 12544, 12576, 12608, 12224, 12256, 12640, 12320, 12672, 12704,
+ 12736, 12448, 12768, 12800, 12832, 12864, 12896, 12928, 12960, 12992,
+ 13024, 13056, 13088, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 13120, 13152, 13184, 13216, 13248, 13280, 1792, 13312, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 4736, 13344, 4736, 4736, 7648,
+ 13376, 13408, 1792, 13440, 13472, 4736, 13344, 13504, 1792, 1792, 13536,
+ 13568, 13504, 13600, 1792, 1792, 1792, 1792, 1792, 4736, 13632, 4736,
+ 13664, 7648, 4736, 13696, 13728, 4736, 8032, 13760, 4736, 4736, 4736,
+ 4736, 13792, 4736, 12096, 13824, 13856, 1792, 1792, 1792, 13888, 4736,
+ 4736, 13920, 1792, 4736, 4736, 13952, 1792, 4736, 4736, 4736, 7648,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 7488, 1792,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 4000, 1344, 1344,
+ 1344, 1344, 1344, 1344, 10784, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 10784
+#endif /* TCL_UTF_MAX > 3 */
};
/*
@@ -167,563 +553,788 @@ static const unsigned char groupMap[] = {
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 5, 3, 6, 11, 12, 11, 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, 5, 7, 6, 7, 1, 2, 3, 4, 4, 4, 4, 14, 14, 11, 14, 15, 16,
- 7, 17, 14, 11, 14, 7, 18, 18, 11, 19, 14, 3, 11, 18, 15, 20, 18, 18,
+ 13, 13, 13, 5, 7, 6, 7, 1, 2, 3, 4, 4, 4, 4, 14, 3, 11, 14, 15, 16,
+ 7, 17, 14, 11, 14, 7, 18, 18, 11, 19, 3, 3, 11, 18, 15, 20, 18, 18,
18, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 7, 10, 10, 10, 10, 10, 10, 10, 15,
+ 10, 10, 10, 10, 10, 10, 10, 10, 7, 10, 10, 10, 10, 10, 10, 10, 21,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 7, 13, 13, 13, 13, 13, 13, 13, 21, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 24, 25, 22, 23, 22,
- 23, 22, 23, 15, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 15, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 26,
- 22, 23, 22, 23, 22, 23, 27, 28, 29, 22, 23, 22, 23, 30, 22, 23, 31,
- 31, 22, 23, 15, 32, 33, 34, 22, 23, 31, 35, 36, 37, 38, 22, 23, 39,
- 15, 37, 40, 41, 42, 22, 23, 22, 23, 22, 23, 43, 22, 23, 43, 15, 15,
- 22, 23, 43, 22, 23, 44, 44, 22, 23, 22, 23, 45, 22, 23, 15, 46, 22,
- 23, 15, 47, 46, 46, 46, 46, 48, 49, 50, 48, 49, 50, 48, 49, 50, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 51, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 15, 48, 49, 50, 22, 23, 52, 53, 22, 23, 22, 23, 22, 23, 22, 23, 54,
- 15, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 15, 15, 15, 15, 15, 15, 55, 22, 23, 56, 57, 58, 58, 22, 23,
- 59, 60, 61, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 62, 63, 64, 65,
- 66, 15, 67, 67, 15, 68, 15, 69, 15, 15, 15, 15, 67, 15, 15, 70, 15,
- 71, 15, 15, 72, 73, 15, 74, 15, 15, 15, 73, 15, 75, 76, 15, 15, 77,
- 15, 15, 15, 15, 15, 15, 15, 78, 15, 15, 79, 15, 15, 79, 15, 15, 15,
- 15, 79, 80, 81, 81, 82, 15, 15, 15, 15, 15, 83, 15, 46, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 11, 11, 11, 11, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 84, 84, 84, 84, 84, 11, 11, 11, 11, 11, 11, 11, 84,
- 11, 84, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 85, 85, 85, 85, 85, 86, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 22, 23, 22,
- 23, 84, 11, 22, 23, 0, 0, 84, 41, 41, 41, 3, 0, 0, 0, 0, 0, 11, 11,
- 87, 3, 88, 88, 88, 0, 89, 0, 90, 90, 15, 10, 10, 10, 10, 10, 10, 10,
+ 13, 13, 13, 13, 13, 13, 7, 13, 13, 13, 13, 13, 13, 13, 22, 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, 23, 24, 23, 24, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 25, 26, 23, 24, 23,
+ 24, 23, 24, 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 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,
+ 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 27,
+ 23, 24, 23, 24, 23, 24, 28, 29, 30, 23, 24, 23, 24, 31, 23, 24, 32,
+ 32, 23, 24, 21, 33, 34, 35, 23, 24, 32, 36, 37, 38, 39, 23, 24, 40,
+ 21, 38, 41, 42, 43, 23, 24, 23, 24, 23, 24, 44, 23, 24, 44, 21, 21,
+ 23, 24, 44, 23, 24, 45, 45, 23, 24, 23, 24, 46, 23, 24, 21, 15, 23,
+ 24, 21, 47, 15, 15, 15, 15, 48, 49, 50, 48, 49, 50, 48, 49, 50, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 51, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+ 21, 48, 49, 50, 23, 24, 52, 53, 23, 24, 23, 24, 23, 24, 23, 24, 54,
+ 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+ 23, 24, 21, 21, 21, 21, 21, 21, 55, 23, 24, 56, 57, 58, 58, 23, 24,
+ 59, 60, 61, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 62, 63, 64, 65,
+ 66, 21, 67, 67, 21, 68, 21, 69, 21, 21, 21, 21, 67, 21, 21, 70, 21,
+ 71, 72, 21, 73, 74, 21, 75, 21, 21, 21, 74, 21, 76, 77, 21, 21, 78,
+ 21, 21, 21, 21, 21, 21, 21, 79, 21, 21, 80, 21, 21, 80, 21, 21, 21,
+ 21, 80, 81, 82, 82, 83, 21, 21, 21, 21, 21, 84, 21, 15, 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, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 11, 11, 11, 11, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 85, 85, 85, 85, 85, 11, 11, 11, 11, 11, 11, 11, 85,
+ 11, 85, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 87, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 23, 24, 23,
+ 24, 85, 11, 23, 24, 0, 0, 85, 42, 42, 42, 3, 0, 0, 0, 0, 0, 11, 11,
+ 88, 3, 89, 89, 89, 0, 90, 0, 91, 91, 21, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 91, 92, 92, 92, 15, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 93, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 94, 95, 95, 96, 97, 98, 99, 99, 99, 100, 101, 102, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 103, 104, 105, 15, 106, 107, 7, 22, 23, 108, 22, 23,
- 15, 54, 54, 54, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109,
- 109, 109, 109, 109, 109, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 92, 93, 93, 93, 21, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 94, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 95, 96, 96, 97, 98, 99, 100, 100, 100, 101, 102, 103, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+ 23, 24, 23, 24, 104, 105, 106, 21, 107, 108, 7, 23, 24, 109, 23, 24,
+ 21, 54, 54, 54, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 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, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
- 104, 104, 104, 104, 22, 23, 14, 85, 85, 85, 85, 85, 110, 110, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 111, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 112, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113,
- 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
- 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
- 113, 113, 113, 113, 113, 113, 113, 113, 113, 0, 0, 84, 3, 3, 3, 3,
- 3, 3, 0, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114,
+ 13, 13, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 23, 24, 14, 86, 86, 86, 86, 86, 111, 111, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 112, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 113, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114,
114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114,
- 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 15, 0,
- 3, 8, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 8, 85, 3, 85, 85, 3, 85, 85, 3, 85, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 46, 46, 46, 3, 3, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 0, 0, 7, 7, 7, 3, 3,
- 4, 3, 3, 14, 14, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 3, 0,
- 0, 3, 3, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 84, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 85, 85, 85, 85, 85, 85,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 46, 46, 85, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 3, 46, 85, 85, 85,
- 85, 85, 85, 85, 17, 14, 85, 85, 85, 85, 85, 85, 84, 84, 85, 85, 14,
- 85, 85, 85, 85, 46, 46, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 46, 46, 46, 14,
- 14, 46, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 17, 46, 85, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 85, 85, 85, 85, 85,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 85, 85, 85, 85, 85, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 85, 85, 85,
- 85, 85, 85, 85, 85, 85, 85, 85, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 85, 85, 85, 85, 85, 85, 85, 85,
- 85, 84, 84, 14, 3, 3, 3, 84, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 85,
- 85, 85, 85, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 84, 85, 85, 85,
- 84, 85, 85, 85, 85, 85, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 85, 85, 85, 0, 0, 3, 0, 0,
+ 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114,
+ 114, 114, 114, 114, 114, 114, 114, 114, 114, 0, 0, 85, 3, 3, 3, 3,
+ 3, 3, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 21, 0,
+ 3, 8, 0, 0, 0, 0, 4, 0, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 8, 86, 3, 86, 86, 3, 86, 86, 3, 86, 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, 0, 7, 7, 7, 3, 3,
+ 4, 3, 3, 14, 14, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 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,
+ 85, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 15, 15, 86, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 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, 86, 86, 86,
+ 86, 86, 86, 86, 17, 14, 86, 86, 86, 86, 86, 86, 85, 85, 86, 86, 14,
+ 86, 86, 86, 86, 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, 86, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 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, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 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, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 85, 85, 14, 3, 3, 3, 85, 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, 86,
+ 86, 86, 86, 85, 86, 86, 86, 86, 86, 86, 86, 86, 86, 85, 86, 86, 86,
+ 85, 86, 86, 86, 86, 86, 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, 86, 86, 86, 0, 0, 3, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 115, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 85, 115, 85, 46,
- 115, 115, 115, 85, 85, 85, 85, 85, 85, 85, 85, 115, 115, 115, 115,
- 85, 115, 115, 46, 85, 85, 85, 85, 85, 85, 85, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 85, 85, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 84,
- 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 85, 115,
- 115, 0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 0, 0, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 0, 0, 46, 46,
- 46, 46, 0, 0, 85, 46, 115, 115, 115, 85, 85, 85, 85, 0, 0, 115, 115,
- 0, 0, 115, 115, 85, 46, 0, 0, 0, 0, 0, 0, 0, 0, 115, 0, 0, 0, 0, 46,
- 46, 0, 46, 46, 46, 85, 85, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 46,
- 46, 4, 4, 18, 18, 18, 18, 18, 18, 14, 4, 0, 0, 0, 0, 0, 85, 85, 115,
- 0, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 46, 46, 0, 0, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 0, 46, 46, 0, 46, 46,
- 0, 0, 85, 0, 115, 115, 115, 85, 85, 0, 0, 0, 0, 85, 85, 0, 0, 85, 85,
- 85, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 0, 46, 0, 0,
- 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 85, 85, 46, 46, 46, 85,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 115, 0, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46,
- 46, 46, 46, 46, 0, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 85, 46, 115,
- 115, 115, 85, 85, 85, 85, 85, 0, 85, 85, 115, 0, 115, 115, 85, 0, 0,
- 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 85, 85, 0,
- 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46,
- 46, 46, 46, 0, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 85, 46, 115, 85,
- 115, 85, 85, 85, 85, 0, 0, 115, 115, 0, 0, 115, 115, 85, 0, 0, 0, 0,
- 0, 0, 0, 0, 85, 115, 0, 0, 0, 0, 46, 46, 0, 46, 46, 46, 85, 85, 0,
- 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 46, 18, 18, 18, 18, 18, 18, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 46, 0, 46, 46, 46, 46, 46, 46, 0, 0,
- 0, 46, 46, 46, 0, 46, 46, 46, 46, 0, 0, 0, 46, 46, 0, 46, 0, 46, 46,
- 0, 0, 0, 46, 46, 0, 0, 0, 46, 46, 46, 0, 0, 0, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 115, 115, 85, 115, 115, 0,
- 0, 0, 115, 115, 115, 0, 115, 115, 115, 85, 0, 0, 46, 0, 0, 0, 0, 0,
- 0, 115, 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, 0, 115, 115, 115, 0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46,
- 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 0, 46, 85, 85, 85, 115, 115, 115,
- 115, 0, 85, 85, 85, 0, 85, 85, 85, 85, 0, 0, 0, 0, 0, 0, 0, 85, 85,
- 0, 46, 46, 0, 0, 0, 0, 0, 0, 46, 46, 85, 85, 0, 0, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 14,
- 0, 0, 115, 115, 0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 0, 46, 46, 46, 46, 46, 0, 0, 85, 46, 115, 85, 115, 115, 115, 115, 115,
- 0, 85, 115, 115, 0, 115, 115, 85, 85, 0, 0, 0, 0, 0, 0, 0, 115, 115,
- 0, 0, 0, 0, 0, 0, 0, 46, 0, 46, 46, 85, 85, 0, 0, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 0, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 115, 115, 115, 85, 85, 85,
- 85, 0, 115, 115, 115, 0, 115, 115, 115, 85, 46, 0, 0, 0, 0, 0, 0, 0,
- 0, 115, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 85, 85, 0, 0, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 0, 0, 0, 14, 46, 46, 46, 46,
- 46, 46, 0, 0, 115, 115, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 0, 46, 46, 46, 46,
- 46, 46, 46, 0, 0, 0, 85, 0, 0, 0, 0, 115, 115, 115, 85, 85, 85, 0,
- 85, 0, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 115, 3, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 85, 46, 46, 85, 85, 85, 85, 85, 85, 85, 0, 0, 0, 0, 4, 46, 46,
- 46, 46, 46, 46, 84, 85, 85, 85, 85, 85, 85, 85, 85, 3, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 3, 3, 0, 0, 0, 0, 0, 46, 46, 0, 46, 0, 0, 46, 46,
- 0, 46, 0, 0, 46, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 0, 46, 46, 46, 46,
- 46, 46, 46, 0, 46, 46, 46, 0, 46, 0, 46, 0, 0, 46, 46, 0, 46, 46, 46,
- 46, 85, 46, 46, 85, 85, 85, 85, 85, 85, 0, 85, 85, 46, 0, 0, 46, 46,
- 46, 46, 46, 0, 84, 0, 85, 85, 85, 85, 85, 85, 0, 0, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 0, 0, 46, 46, 0, 0, 46, 14, 14, 14, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 14, 14, 14, 14, 85, 85, 14, 14, 14,
- 14, 14, 14, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, 14, 85, 14, 85, 14, 85, 5, 6, 5, 6, 115, 115, 46, 46, 46,
- 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 85, 85, 85, 85, 85, 85,
- 85, 85, 85, 85, 85, 85, 85, 85, 115, 85, 85, 85, 85, 85, 3, 85, 85,
- 46, 46, 46, 46, 46, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 85, 85, 0, 14, 14, 14, 14, 14, 14, 14, 14, 85, 14, 14, 14, 14, 14,
- 14, 0, 14, 14, 3, 3, 3, 3, 3, 14, 14, 14, 14, 3, 3, 0, 0, 0, 0, 0,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 115, 115, 85, 85, 85, 85,
- 115, 85, 85, 85, 85, 85, 85, 115, 85, 85, 115, 115, 85, 85, 46, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 46, 46, 46, 46, 46, 46,
- 115, 115, 85, 85, 46, 46, 46, 46, 85, 85, 85, 46, 115, 115, 115, 46,
- 46, 115, 115, 115, 115, 115, 115, 115, 46, 46, 46, 85, 85, 85, 85,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 85, 115, 115, 85,
- 85, 115, 115, 115, 115, 115, 115, 85, 46, 115, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 115, 115, 115, 85, 14, 14, 116, 116, 116, 116, 116, 116, 116,
- 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+ 0, 0, 0, 0, 0, 0, 0, 0, 15, 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, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 0, 86, 86, 86, 116,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 86, 116, 86, 15, 116, 116, 116, 86, 86, 86, 86, 86, 86,
+ 86, 86, 116, 116, 116, 116, 86, 116, 116, 15, 86, 86, 86, 86, 86, 86,
+ 86, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86, 86, 3, 3, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 3, 85, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15,
+ 15, 15, 15, 15, 0, 86, 116, 116, 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, 86, 15, 116, 116, 116, 86,
+ 86, 86, 86, 0, 0, 116, 116, 0, 0, 116, 116, 86, 15, 0, 0, 0, 0, 0,
+ 0, 0, 0, 116, 0, 0, 0, 0, 15, 15, 0, 15, 15, 15, 86, 86, 0, 0, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 4, 4, 18, 18, 18, 18, 18, 18, 14, 4,
+ 0, 0, 0, 0, 0, 86, 86, 116, 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, 86, 0, 116, 116, 116, 86, 86, 0, 0,
+ 0, 0, 86, 86, 0, 0, 86, 86, 86, 0, 0, 0, 86, 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, 86, 86, 15, 15, 15, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 86,
+ 116, 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, 86, 15, 116, 116, 116, 86, 86, 86, 86, 86, 0, 86, 86,
+ 116, 0, 116, 116, 86, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 15, 15, 86, 86, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 4,
+ 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, 0, 15, 15, 0, 15, 15, 15, 15,
+ 15, 0, 0, 86, 15, 116, 86, 116, 86, 86, 86, 86, 0, 0, 116, 116, 0,
+ 0, 116, 116, 86, 0, 0, 0, 0, 0, 0, 0, 0, 86, 116, 0, 0, 0, 0, 15, 15,
+ 0, 15, 15, 15, 86, 86, 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, 86, 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, 116,
+ 116, 86, 116, 116, 0, 0, 0, 116, 116, 116, 0, 116, 116, 116, 86, 0,
+ 0, 15, 0, 0, 0, 0, 0, 0, 116, 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, 0, 116, 116, 116, 0, 15, 15, 15, 15, 15, 15,
+ 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, 0, 15, 86, 86,
+ 86, 116, 116, 116, 116, 0, 86, 86, 86, 0, 86, 86, 86, 86, 0, 0, 0,
+ 0, 0, 0, 0, 86, 86, 0, 15, 15, 0, 0, 0, 0, 0, 0, 15, 15, 86, 86, 0,
+ 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18,
+ 18, 18, 18, 18, 14, 0, 0, 116, 116, 0, 15, 15, 15, 15, 15, 15, 15,
+ 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, 86, 15, 116, 86, 116,
+ 116, 116, 116, 116, 0, 86, 116, 116, 0, 116, 116, 86, 86, 0, 0, 0,
+ 0, 0, 0, 0, 116, 116, 0, 0, 0, 0, 0, 0, 0, 15, 0, 15, 15, 86, 86, 0,
+ 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 116,
+ 116, 116, 86, 86, 86, 86, 0, 116, 116, 116, 0, 116, 116, 116, 86, 15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 86, 86,
+ 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 0, 0, 0,
+ 14, 15, 15, 15, 15, 15, 15, 0, 0, 116, 116, 0, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0,
+ 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 86, 0, 0, 0, 0, 116, 116, 116,
+ 86, 86, 86, 0, 86, 0, 116, 116, 116, 116, 116, 116, 116, 116, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 116, 3, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 86, 15, 15, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0,
+ 4, 15, 15, 15, 15, 15, 15, 85, 86, 86, 86, 86, 86, 86, 86, 86, 3, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 0, 0, 0, 0, 0, 15, 15, 0, 15, 0, 0,
+ 15, 15, 0, 15, 0, 0, 15, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 15, 15,
+ 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 0, 15, 0, 0, 15, 15, 0, 15,
+ 15, 15, 15, 86, 15, 15, 86, 86, 86, 86, 86, 86, 0, 86, 86, 15, 0, 0,
+ 15, 15, 15, 15, 15, 0, 85, 0, 86, 86, 86, 86, 86, 86, 0, 0, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 0, 0, 15, 15, 15, 15, 15, 14, 14, 14, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 3, 14, 14, 14, 86, 86, 14,
+ 14, 14, 14, 14, 14, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 14, 86, 14, 86, 14, 86, 5, 6, 5, 6, 116, 116, 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, 0, 0, 0, 0, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 116, 86, 86, 86, 86, 86, 3,
+ 86, 86, 15, 15, 15, 15, 15, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 0, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 0, 14, 14, 14, 14, 14, 14, 14, 14, 86, 14, 14, 14,
+ 14, 14, 14, 0, 14, 14, 3, 3, 3, 3, 3, 14, 14, 14, 14, 3, 3, 0, 0, 0,
+ 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 116, 116, 86, 86,
+ 86, 86, 116, 86, 86, 86, 86, 86, 86, 116, 86, 86, 116, 116, 86, 86,
+ 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15,
+ 15, 15, 116, 116, 86, 86, 15, 15, 15, 15, 86, 86, 86, 15, 116, 116,
+ 116, 15, 15, 116, 116, 116, 116, 116, 116, 116, 15, 15, 15, 86, 86,
+ 86, 86, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86, 116,
+ 116, 86, 86, 116, 116, 116, 116, 116, 116, 86, 15, 116, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 116, 116, 116, 86, 14, 14, 117, 117, 117, 117, 117,
+ 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117,
+ 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117,
+ 117, 117, 117, 117, 117, 0, 117, 0, 0, 0, 0, 0, 117, 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, 85, 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, 86, 86, 86, 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, 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, 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, 118, 118, 118, 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, 15, 15, 15, 15,
+ 86, 86, 86, 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, 86, 86, 86, 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, 86, 86, 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, 86, 86, 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, 86, 86,
+ 116, 86, 86, 86, 86, 86, 86, 86, 116, 116, 116, 116, 116, 116, 116,
+ 116, 86, 116, 116, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 3, 3,
+ 3, 85, 3, 3, 3, 4, 15, 86, 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, 86, 86, 86, 17, 0, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 85, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0,
+ 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86, 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, 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, 0, 0, 0, 86, 86, 86, 116, 116, 116, 116,
+ 86, 86, 116, 116, 116, 0, 0, 0, 0, 116, 116, 86, 116, 116, 116, 116,
+ 116, 116, 86, 86, 86, 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, 116, 116, 116,
116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
- 116, 116, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 3, 84, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0,
- 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 46, 46,
- 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46,
- 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 0, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 46,
- 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 0, 0,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 0, 0, 85, 85, 85, 14, 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,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 3, 3, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 5, 6, 0, 0, 0,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 3, 3, 3, 117, 117, 117,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 85, 85, 85, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 85, 85, 85, 3, 3, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 85, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 85, 85, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 17, 17, 115, 85, 85, 85, 85,
- 85, 85, 85, 115, 115, 115, 115, 115, 115, 115, 115, 85, 115, 115, 85,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 3, 3, 3, 84, 3, 3, 3, 4, 46,
- 85, 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, 85, 85, 85, 2, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0,
- 0, 0, 0, 46, 46, 46, 84, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 85, 46, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 0, 0, 0, 85, 85, 85, 115, 115, 115, 115, 85, 85, 115, 115, 115, 0,
- 0, 0, 0, 115, 115, 85, 115, 115, 115, 115, 115, 115, 85, 85, 85, 0,
- 0, 0, 0, 14, 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 0, 0, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115,
- 115, 115, 115, 115, 115, 115, 115, 46, 46, 46, 46, 46, 46, 46, 115,
- 115, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 0, 0, 0, 14,
+ 15, 15, 15, 15, 15, 15, 15, 116, 116, 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, 14, 14, 14, 14, 14, 14, 14, 14, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 85, 85, 115, 115, 115, 0, 0, 3, 3, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 115, 85, 115, 85, 85, 85, 85, 85, 85, 85, 0, 85, 115, 85, 115,
- 115, 85, 85, 85, 85, 85, 85, 85, 85, 115, 115, 115, 115, 115, 115,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, 0, 85, 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, 84, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, 115, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 85, 115, 85, 85, 85, 85,
- 85, 115, 85, 115, 115, 115, 115, 115, 85, 115, 115, 46, 46, 46, 46,
- 46, 46, 46, 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, 85, 85, 85, 85, 85, 85,
- 85, 85, 85, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 85, 85, 115,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 115, 85, 85, 85,
- 85, 115, 115, 85, 85, 115, 0, 0, 0, 46, 46, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 85, 115, 85, 85, 115,
- 115, 115, 85, 115, 85, 85, 85, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 3,
- 3, 3, 3, 46, 46, 46, 46, 115, 115, 115, 115, 115, 115, 115, 115, 85,
- 85, 85, 85, 85, 85, 85, 85, 115, 115, 85, 85, 0, 0, 0, 3, 3, 3, 3,
- 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 46, 46, 46, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 84, 84, 84, 84, 84, 84, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 85, 85, 85, 3, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 85, 85, 115, 85, 85, 85, 85, 85, 85, 85, 46, 46, 46, 46, 85, 46, 46,
- 46, 46, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 84, 118, 15,
- 15, 15, 119, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 84, 84,
- 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 15, 15, 15, 15, 15, 120, 15, 15, 121, 15, 122, 122, 122, 122, 122,
- 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 122, 122, 122,
- 122, 122, 122, 0, 0, 123, 123, 123, 123, 123, 123, 0, 0, 122, 122,
- 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123,
- 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123,
- 123, 123, 122, 122, 122, 122, 122, 122, 0, 0, 123, 123, 123, 123, 123,
- 123, 0, 0, 15, 122, 15, 122, 15, 122, 15, 122, 0, 123, 0, 123, 0, 123,
- 0, 123, 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123,
- 123, 123, 123, 123, 124, 124, 125, 125, 125, 125, 126, 126, 127, 127,
- 128, 128, 129, 129, 0, 0, 122, 122, 122, 122, 122, 122, 122, 122, 130,
- 130, 130, 130, 130, 130, 130, 130, 122, 122, 122, 122, 122, 122, 122,
- 122, 130, 130, 130, 130, 130, 130, 130, 130, 122, 122, 122, 122, 122,
- 122, 122, 122, 130, 130, 130, 130, 130, 130, 130, 130, 122, 122, 15,
- 131, 15, 0, 15, 15, 123, 123, 132, 132, 133, 11, 134, 11, 11, 11, 15,
- 131, 15, 0, 15, 15, 135, 135, 135, 135, 133, 11, 11, 11, 122, 122,
- 15, 15, 0, 0, 15, 15, 123, 123, 136, 136, 0, 11, 11, 11, 122, 122,
- 15, 15, 15, 105, 15, 15, 123, 123, 137, 137, 108, 11, 11, 11, 0, 0,
- 15, 131, 15, 0, 15, 15, 138, 138, 139, 139, 133, 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, 140, 141, 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, 0, 0, 0, 0, 17,
- 17, 17, 17, 17, 17, 18, 84, 0, 0, 18, 18, 18, 18, 18, 18, 7, 7, 7,
- 5, 6, 84, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 0,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 110, 110, 110,
- 110, 85, 110, 110, 110, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 99, 14, 14,
- 14, 14, 99, 14, 14, 15, 99, 99, 99, 15, 15, 99, 99, 99, 15, 14, 99,
- 14, 14, 7, 99, 99, 99, 99, 99, 14, 14, 14, 14, 14, 14, 99, 14, 142,
- 14, 99, 14, 143, 144, 99, 99, 14, 15, 99, 99, 145, 99, 15, 46, 46,
- 46, 46, 15, 14, 14, 15, 15, 99, 99, 7, 7, 7, 7, 7, 99, 15, 15, 15,
- 15, 14, 7, 14, 14, 146, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 148, 148, 148, 148, 148, 148, 148,
- 148, 148, 148, 148, 148, 148, 148, 148, 148, 117, 117, 117, 22, 23,
- 117, 117, 117, 117, 18, 0, 0, 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, 7, 7, 14, 14, 7, 14, 7, 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, 86, 86, 116,
+ 116, 86, 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, 116, 86, 116, 86, 86, 86, 86, 86,
+ 86, 86, 0, 86, 116, 86, 116, 116, 86, 86, 86, 86, 86, 86, 86, 86, 116,
+ 116, 116, 116, 116, 116, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 0,
+ 0, 86, 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, 85, 3, 3,
+ 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86,
+ 86, 86, 86, 116, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 86, 116, 86, 86, 86, 86, 86, 116, 86, 116, 116, 116, 116, 116, 86,
+ 116, 116, 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, 86, 86, 86, 86, 86, 86, 86, 86, 86, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 0, 0, 0, 86, 86, 116, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 116, 86, 86, 86, 86, 116, 116, 86, 86, 116, 86, 116, 116,
+ 15, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 86, 116, 86, 86, 116, 116, 116, 86, 116, 86, 86, 86,
+ 116, 116, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 15, 15, 15, 15, 116,
+ 116, 116, 116, 116, 116, 116, 116, 86, 86, 86, 86, 86, 86, 86, 86,
+ 116, 116, 86, 86, 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, 85, 85, 85, 85, 85, 85, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 86, 86, 86, 3, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 116, 86, 86, 86, 86, 86,
+ 86, 86, 15, 15, 15, 15, 86, 15, 15, 15, 15, 116, 116, 86, 15, 15, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 85, 119, 21, 21, 21, 120, 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, 85, 85, 85, 85, 85, 86, 86, 86, 86,
+ 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 86, 86, 86, 86, 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, 121, 21,
+ 21, 122, 21, 123, 123, 123, 123, 123, 123, 123, 123, 124, 124, 124,
+ 124, 124, 124, 124, 124, 123, 123, 123, 123, 123, 123, 0, 0, 124, 124,
+ 124, 124, 124, 124, 0, 0, 123, 123, 123, 123, 123, 123, 123, 123, 124,
+ 124, 124, 124, 124, 124, 124, 124, 123, 123, 123, 123, 123, 123, 123,
+ 123, 124, 124, 124, 124, 124, 124, 124, 124, 123, 123, 123, 123, 123,
+ 123, 0, 0, 124, 124, 124, 124, 124, 124, 0, 0, 21, 123, 21, 123, 21,
+ 123, 21, 123, 0, 124, 0, 124, 0, 124, 0, 124, 123, 123, 123, 123, 123,
+ 123, 123, 123, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 126,
+ 126, 126, 126, 127, 127, 128, 128, 129, 129, 130, 130, 0, 0, 123, 123,
+ 123, 123, 123, 123, 123, 123, 131, 131, 131, 131, 131, 131, 131, 131,
+ 123, 123, 123, 123, 123, 123, 123, 123, 131, 131, 131, 131, 131, 131,
+ 131, 131, 123, 123, 123, 123, 123, 123, 123, 123, 131, 131, 131, 131,
+ 131, 131, 131, 131, 123, 123, 21, 132, 21, 0, 21, 21, 124, 124, 133,
+ 133, 134, 11, 135, 11, 11, 11, 21, 132, 21, 0, 21, 21, 136, 136, 136,
+ 136, 134, 11, 11, 11, 123, 123, 21, 21, 0, 0, 21, 21, 124, 124, 137,
+ 137, 0, 11, 11, 11, 123, 123, 21, 21, 21, 106, 21, 21, 124, 124, 138,
+ 138, 109, 11, 11, 11, 0, 0, 21, 132, 21, 0, 21, 21, 139, 139, 140,
+ 140, 134, 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, 141, 142, 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, 85, 0, 0,
+ 18, 18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 85, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 7, 7, 7, 5, 6, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 111, 111, 111, 111, 86, 111, 111, 111, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 14, 14, 100, 14, 14, 14, 14, 100, 14, 14, 21, 100, 100,
+ 100, 21, 21, 100, 100, 100, 21, 14, 100, 14, 14, 7, 100, 100, 100,
+ 100, 100, 14, 14, 14, 14, 14, 14, 100, 14, 143, 14, 100, 14, 144, 145,
+ 100, 100, 14, 21, 100, 100, 146, 100, 21, 15, 15, 15, 15, 21, 14, 14,
+ 21, 21, 100, 100, 7, 7, 7, 7, 7, 100, 21, 21, 21, 21, 14, 7, 14, 14,
+ 147, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148,
+ 148, 148, 148, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149,
+ 149, 149, 149, 149, 149, 118, 118, 118, 23, 24, 118, 118, 118, 118,
+ 18, 0, 0, 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, 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, 7, 7, 14, 14,
+ 7, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 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,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14,
+ 14, 14, 14, 14, 14, 14, 5, 6, 5, 6, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 14, 14, 14, 14,
+ 14, 14, 14, 5, 6, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7,
+ 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14,
- 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 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, 7, 7, 7, 7, 7, 7, 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, 0, 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 149, 149, 149,
- 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149,
- 149, 149, 149, 149, 149, 149, 149, 149, 149, 150, 150, 150, 150, 150,
+ 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, 150, 150, 150, 150, 150, 150, 150, 150,
150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150,
- 150, 150, 150, 150, 150, 150, 150, 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,
+ 150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151,
+ 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151,
+ 151, 151, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 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, 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, 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, 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, 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, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 5, 6, 7, 7,
- 7, 7, 0, 7, 0, 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,
+ 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, 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, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 6, 7, 7, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, 7, 7, 7, 7, 7, 7, 0, 0, 0, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 113, 113, 113,
- 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
- 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
- 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
- 113, 113, 0, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114,
+ 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, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 0, 0, 0, 0, 0, 0, 114, 114, 114, 114, 114, 114, 114, 114,
114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114,
114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114,
- 114, 114, 114, 114, 114, 114, 114, 114, 0, 22, 23, 151, 152, 153, 154,
- 155, 22, 23, 22, 23, 22, 23, 156, 157, 158, 159, 15, 22, 23, 15, 22,
- 23, 15, 15, 15, 15, 15, 15, 84, 160, 160, 22, 23, 22, 23, 15, 14, 14,
- 14, 14, 14, 14, 22, 23, 22, 23, 85, 85, 85, 0, 0, 0, 0, 0, 0, 0, 3,
- 3, 3, 3, 18, 3, 3, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
- 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
- 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 84, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46,
- 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0,
- 46, 46, 46, 46, 46, 46, 46, 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, 84, 3, 3, 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, 0,
+ 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 0, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 0, 23, 24, 152, 153, 154, 155, 156, 23, 24, 23, 24,
+ 23, 24, 157, 158, 159, 160, 21, 23, 24, 21, 23, 24, 21, 21, 21, 21,
+ 21, 85, 85, 161, 161, 23, 24, 23, 24, 21, 14, 14, 14, 14, 14, 14, 23,
+ 24, 23, 24, 86, 86, 86, 23, 24, 0, 0, 0, 0, 0, 3, 3, 3, 3, 18, 3, 3,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 0, 162, 0, 0, 0,
+ 0, 0, 162, 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, 85,
+ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 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, 85, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 8, 8, 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, 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, 0, 0, 0,
+ 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 0, 0, 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, 84, 46, 117, 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, 117, 117,
- 117, 117, 117, 117, 117, 117, 117, 85, 85, 85, 85, 85, 85, 8, 84, 84,
- 84, 84, 84, 14, 14, 117, 117, 117, 84, 46, 3, 14, 14, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 0, 0, 85, 85, 11, 11, 84, 84, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 3, 84, 84, 84, 46, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0,
- 14, 14, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 14, 14, 14, 14,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 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, 85, 15, 118, 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, 118, 118, 118, 118,
+ 118, 118, 118, 118, 118, 86, 86, 86, 86, 116, 116, 8, 85, 85, 85, 85,
+ 85, 14, 14, 118, 118, 118, 85, 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, 86, 86, 11, 11, 85, 85, 15, 15, 15, 15, 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, 85, 85, 85, 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, 0,
+ 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 14, 14,
+ 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 14, 14, 14, 14, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 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,
- 14, 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
- 18, 18, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 84,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 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, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 84, 3,
- 3, 3, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 46, 85, 110, 110, 110, 3, 0, 0, 0, 0, 0, 0, 0, 0, 85,
- 85, 3, 84, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 46,
- 46, 46, 46, 46, 46, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117,
- 85, 85, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11,
+ 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, 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, 85, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 85, 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, 86, 111, 111, 111, 3, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 3, 85, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 86, 15, 15,
+ 15, 15, 15, 15, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 86,
+ 86, 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,
- 11, 84, 84, 84, 84, 84, 84, 84, 84, 84, 11, 11, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 15, 15, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 84, 15, 15, 15, 15, 15, 15, 15, 15, 22,
- 23, 22, 23, 162, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 84, 11, 11,
- 22, 23, 163, 15, 0, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 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, 85, 21, 21, 21, 21, 21, 21, 21, 21, 23, 24,
+ 23, 24, 163, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 85, 11, 11, 23,
+ 24, 164, 21, 0, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 165, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 46, 46, 46,
- 46, 46, 46, 46, 85, 46, 46, 46, 85, 46, 46, 46, 46, 85, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 115, 115, 85, 85, 115, 14, 14, 14, 14, 0, 0, 0, 0, 18,
- 18, 18, 18, 18, 18, 14, 14, 4, 14, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 3,
- 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 115, 115, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 115, 115, 115, 115, 115, 115,
- 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 85, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 85,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 46, 46, 46, 46, 46, 46, 3, 3, 3, 46, 0, 0, 0, 0, 46, 46, 46, 46, 46,
- 46, 85, 85, 85, 85, 85, 85, 85, 85, 3, 3, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 85,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 115, 115, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 3, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 85, 115, 115, 85, 85, 85, 85, 115, 115, 85,
- 115, 115, 115, 115, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 84, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 85, 85, 85, 85, 85, 85, 115, 115, 85, 85, 115, 115, 85,
- 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 85, 46, 46, 46, 46, 46,
- 46, 46, 46, 85, 115, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 3, 3,
- 3, 3, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 84, 46, 46, 46, 46, 46, 46, 14, 14, 14, 46, 115, 0, 0, 0, 0, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 85, 46, 85,
- 85, 85, 46, 46, 85, 85, 46, 46, 46, 46, 46, 85, 85, 46, 85, 46, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 21, 15, 15, 15, 15,
+ 15, 15, 15, 86, 15, 15, 15, 86, 15, 15, 15, 15, 86, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 116, 116, 86, 86, 116, 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, 116, 116, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 116, 116, 116, 116, 116, 116, 116,
+ 116, 116, 116, 116, 116, 116, 116, 116, 116, 86, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 15, 15, 15, 15, 15, 15, 3, 3, 3, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+ 15, 86, 86, 86, 86, 86, 86, 86, 86, 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, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 116, 116, 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, 86, 116, 116, 86, 86, 86, 86, 116, 116, 86,
+ 116, 116, 116, 116, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 85, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 86, 86, 86, 86, 86, 86, 116, 116, 86, 86, 116, 116, 86,
+ 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 86, 15, 15, 15, 15, 15,
+ 15, 15, 15, 86, 116, 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,
+ 85, 15, 15, 15, 15, 15, 15, 14, 14, 14, 15, 116, 0, 0, 0, 0, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86, 15, 86,
+ 86, 86, 15, 15, 86, 86, 15, 15, 15, 15, 15, 86, 86, 15, 86, 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,
- 46, 46, 84, 3, 3, 0, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46,
- 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46,
- 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 115, 115, 85, 115,
- 115, 85, 115, 115, 3, 115, 85, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165,
- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
- 165, 165, 165, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 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, 15, 15, 15, 15,
- 15, 0, 0, 0, 0, 0, 46, 85, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 7, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46,
- 46, 46, 0, 46, 0, 46, 46, 0, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 15, 15, 85, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 116,
+ 86, 86, 116, 116, 3, 3, 15, 85, 85, 116, 86, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 116, 116, 86, 116, 116, 86, 116, 116,
+ 3, 116, 86, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15,
+ 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 0, 0, 0, 0, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166,
+ 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166,
+ 166, 166, 166, 166, 166, 166, 166, 166, 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, 167, 167, 167, 167, 167, 167, 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, 21, 21, 21, 21, 21, 21, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 15,
+ 86, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 15, 0, 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, 15, 15, 15, 15, 15, 15, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 5, 6, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 4, 14, 0, 0, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 3, 3, 3, 3, 3, 3, 3, 5,
+ 6, 3, 0, 0, 0, 0, 0, 0, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 8, 8, 12, 12, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
+ 6, 5, 6, 3, 3, 5, 6, 3, 3, 3, 3, 12, 12, 12, 3, 3, 3, 0, 3, 3, 3, 3,
+ 8, 5, 6, 5, 6, 5, 6, 3, 3, 3, 7, 8, 7, 7, 7, 0, 3, 4, 3, 3, 0, 0, 0,
+ 0, 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, 15, 15, 0, 0, 17, 0, 3, 3, 3, 4,
+ 3, 3, 3, 5, 6, 3, 7, 3, 8, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3,
+ 7, 7, 7, 3, 11, 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, 5, 7, 6, 7, 5,
+ 6, 3, 5, 6, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 85, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 85, 85, 15, 15, 15, 15, 15, 15,
+ 15, 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, 0,
+ 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15,
+ 15, 15, 0, 0, 0, 4, 4, 7, 11, 14, 4, 4, 0, 14, 7, 7, 7, 7, 14, 14,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 14, 14, 0, 0
+#if TCL_UTF_MAX > 3
+ ,15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 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, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 0, 0, 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,
+ 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, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+ 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+ 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+ 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 18,
+ 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 18, 0, 0, 0, 0, 0, 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 86, 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, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 118, 15, 15, 15, 15, 15, 15, 15, 15, 118, 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, 15, 15, 15, 15, 0, 3, 15, 15, 15, 15, 0, 0, 0,
+ 0, 15, 15, 15, 15, 15, 15, 15, 15, 3, 118, 118, 118, 118, 118, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 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, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
+ 168, 168, 168, 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, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169,
+ 169, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 0, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 0, 0, 15, 0, 0, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 0, 3, 18, 18, 18, 18, 18, 18, 18, 18, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 18, 18, 18, 18, 18, 18, 0, 0, 0, 3, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 0, 0, 0, 0, 0, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 15,
+ 15, 15, 86, 86, 86, 0, 86, 86, 0, 0, 0, 0, 0, 86, 86, 86, 86, 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, 86, 86, 86, 0, 0, 0, 0, 86, 18, 18, 18, 18, 18, 18, 18, 18,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 18, 18, 3, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 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, 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, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 116, 86, 116, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 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, 0, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 116, 116, 116, 86,
+ 86, 86, 86, 116, 116, 86, 86, 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, 86, 86,
+ 86, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 86, 86, 86, 86, 86, 116, 86, 86, 86, 86, 86, 86, 86, 86,
+ 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, 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,
+ 116, 116, 116, 86, 86, 86, 86, 86, 86, 86, 86, 86, 116, 116, 15, 15,
+ 15, 15, 3, 3, 3, 3, 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, 86,
+ 116, 86, 116, 116, 86, 86, 86, 86, 86, 86, 116, 86, 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, 118, 118, 118, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0,
+ 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 116, 116,
+ 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+ 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+ 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+ 116, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 86, 86,
+ 86, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 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, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 4, 14,
- 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 3, 3, 3, 3, 3, 3, 3, 5, 6, 3, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, 85,
- 85, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 8, 12, 12, 5, 6, 5, 6, 5,
- 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 3, 3, 5, 6, 3, 3, 3, 3, 12, 12, 12,
- 3, 3, 3, 0, 3, 3, 3, 3, 8, 5, 6, 5, 6, 5, 6, 3, 3, 3, 7, 8, 7, 7, 7,
- 0, 3, 4, 3, 3, 0, 0, 0, 0, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 0, 0, 17, 0, 3, 3, 3, 4, 3, 3, 3, 5, 6, 3, 7, 3, 8, 3, 3, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 3, 3, 7, 7, 7, 3, 11, 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, 5, 7, 6, 7, 5, 6, 3, 5, 6, 3, 3, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 84, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 84,
- 84, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0,
- 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46,
- 46, 46, 46, 46, 0, 0, 46, 46, 46, 0, 0, 0, 4, 4, 7, 11, 14, 4, 4, 0,
- 14, 7, 7, 7, 7, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 14,
- 14, 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, 116, 116, 86, 86, 86, 14, 14, 14, 116,
+ 116, 116, 116, 116, 116, 17, 17, 17, 17, 17, 17, 17, 17, 86, 86, 86,
+ 86, 86, 86, 86, 86, 14, 14, 86, 86, 86, 86, 86, 86, 86, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 86, 86, 86, 86, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 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, 86, 86, 86,
+ 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 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, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 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, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 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, 100, 0,
+ 100, 100, 0, 0, 100, 0, 0, 100, 100, 0, 0, 100, 100, 100, 100, 0, 100,
+ 100, 100, 100, 100, 100, 100, 100, 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,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 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, 100, 100, 0, 100, 100, 100, 100, 0, 0,
+ 100, 100, 100, 100, 100, 100, 100, 100, 0, 100, 100, 100, 100, 100,
+ 100, 100, 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, 100, 100, 0, 100, 100,
+ 100, 100, 0, 100, 100, 100, 100, 100, 0, 100, 0, 0, 0, 100, 100, 100,
+ 100, 100, 100, 100, 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, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 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, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 100, 100, 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, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 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, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 21, 21, 21, 21, 21, 21, 0, 0, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 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, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 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, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 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, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 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, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100, 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, 100, 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, 15,
+ 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15,
+ 0, 15, 0, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15,
+ 15, 15, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 15, 0,
+ 15, 0, 15, 0, 15, 15, 15, 0, 15, 15, 0, 15, 0, 0, 15, 0, 15, 0, 15,
+ 0, 15, 0, 15, 0, 15, 15, 0, 15, 0, 0, 15, 15, 15, 15, 0, 15, 15, 15,
+ 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 0, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, 15,
+ 0, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0,
+ 0, 0, 0, 0, 14, 14, 0, 0, 0, 0, 0, 0, 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, 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, 0, 0, 0, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14,
+ 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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
+#endif /* TCL_UTF_MAX > 3 */
};
/*
@@ -739,47 +1350,43 @@ static const unsigned char groupMap[] = {
* 101 = sub delta for upper, sub 1 for title
* 110 = sub delta for upper, add delta for lower
*
- * Bits 8-21 Reserved for future use.
- *
- * Bits 22-31 Case delta: delta for case conversions. This should be the
+ * Bits 8-31 Case delta: delta for case conversions. This should be the
* highest field so we can easily sign extend.
*/
static const int groups[] = {
- 0, 15, 12, 25, 27, 21, 22, 26, 20, 9, 134217793, 28, 19, 134217858,
- 29, 2, 23, 16, 11, 1178599554, 24, -507510654, 4194369, 4194434,
- -834666431, 973078658, -507510719, 1258291330, -817889150, 880803905,
- 864026689, 859832385, 331350081, 847249473, 851443777, 868220993,
- -406847358, 884998209, 876609601, -683671422, 893386817, -545259390,
- 897581121, 914358337, 910164033, 918552641, 5, -234880894, 8388705,
- 4194467, 8388770, 331350146, -406847423, -234880959, -545259455,
- -1967128511, -683671487, -1979711423, 1883242626, -817889215,
- 289407041, 297795649, 2017460354, 2030043266, 2021654658, 880803970,
- 864026754, 859832450, 847249538, 851443842, 868221058, -1241513854,
- 876609666, 884998274, -2109734782, -2134900606, 893386882, 897581186,
- -2042625918, 914358402, 289407106, 910164098, 297795714, 918552706,
- 4, 6, -352321402, 159383617, 155189313, 268435521, 264241217,
- 159383682, 155189378, 130023554, 268435586, 264241282, 33554497,
- 260046978, 239075458, 1, 197132418, 226492546, 33554562, 360710274,
- 335544450, -29359998, -251658175, 402653314, -29360063, 335544385,
- 7, 62914625, 62914690, 201326657, 201326722, 8, 402653249, 10,
- 2130706562, 1182793858, 247464066, -1874853823, -33554302, -33554367,
- -310378366, -360710014, -419430270, -536870782, -469761918, -528482174,
- -33554365, -37748606, -310378431, -37748669, 155189378, -360710079,
- -419430335, -469761983, -536870847, -528482239, 13, 14, -1463812031,
- -801111999, -293601215, 117440577, 117440642, 67108938, 67109002,
- 109051997, 109052061, -2109734847, 1182793793, -2042625983, -1967128446,
- -1979711358, 2030043201, -2134900671, 2017460289, 2021654593,
- 1883242561, 402653314, 2130706497, -1241513919, 18, 17
+ 0, 15, 12, 25, 27, 21, 22, 26, 20, 9, 8257, 28, 19, 8322, 29,
+ 5, 23, 16, 11, -190078, 24, 2, -30846, 321, 386, -50879, 59522,
+ -30911, 76930, -49790, 53825, 52801, 52545, 20289, 51777, 52033,
+ 53057, -24702, 54081, 53569, -41598, 54593, -33150, 54849, 55873,
+ 55617, 56129, -14206, 609, 451, 674, 20354, -24767, -14271, -33215,
+ 2763585, -41663, 2762817, -2768510, -49855, 17729, 18241, -2760318,
+ -2759550, -2760062, 53890, 52866, 52610, 51842, 52098, 53122,
+ -10823550, -10830718, 53634, 54146, -2750078, -2751614, 54658,
+ 54914, -2745982, 55938, 17794, 55682, 18306, 56194, 4, 6, -21370,
+ 9793, 9537, 16449, 16193, 9858, 9602, 8066, 16514, 16258, 2113,
+ 16002, 14722, 1, 12162, 13954, 2178, 22146, 20610, -1662, -15295,
+ 24706, -1727, 20545, 7, 3905, 3970, 12353, 12418, 8, 1859649,
+ 10, -9044862, -976254, 15234, -1949375, -1918, -1983, -18814,
+ -21886, -25470, -32638, -28542, -32126, -1981, -2174, -18879,
+ -2237, 1844610, -21951, -25535, -28607, -32703, -32191, 13, 14,
+ -1924287, -2145983, -2115007, 7233, 7298, 4170, 4234, 6749, 6813,
+ -2750143, -976319, -2746047, 2763650, 2762882, -2759615, -2751679,
+ -2760383, -2760127, -2768575, 1859714, -9044927, -10823615, -10830783,
+ 18, 17, 10305, 10370
};
+#if TCL_UTF_MAX > 3
+# define UNICODE_OUT_OF_RANGE(ch) (((ch) & 0x1fffff) >= 0x2fa20)
+#else
+# define UNICODE_OUT_OF_RANGE(ch) (((ch) & 0x1f0000) != 0)
+#endif
+
/*
* The following constants are used to determine the category of a
* Unicode character.
*/
-#define UNICODE_CATEGORY_MASK 0X1F
-
enum {
UNASSIGNED,
UPPERCASE_LETTER,
@@ -819,14 +1426,13 @@ enum {
* to do sign extension on right shifts.
*/
-#define GetCaseType(info) (((info) & 0xE0) >> 5)
-#define GetCategory(info) ((info) & 0x1F)
-#define GetDelta(info) (((info) > 0) ? ((info) >> 22) : (~(~((info)) >> 22)))
+#define GetCaseType(info) (((info) & 0xe0) >> 5)
+#define GetCategory(ch) (GetUniCharInfo(ch) & 0x1f)
+#define GetDelta(info) ((info) >> 8)
/*
* This macro extracts the information about a character from the
* Unicode character tables.
*/
-#define GetUniCharInfo(ch) (groups[groupMap[(pageMap[(((int)(ch)) & 0xffff) >> OFFSET_BITS] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1))]])
-
+#define GetUniCharInfo(ch) (groups[groupMap[pageMap[((ch) & 0xffff) >> OFFSET_BITS] | ((ch) & ((1 << OFFSET_BITS)-1))]])
diff --git a/generic/tclUtf.c b/generic/tclUtf.c
index ab26779..15529c7 100644
--- a/generic/tclUtf.c
+++ b/generic/tclUtf.c
@@ -26,28 +26,27 @@
#define ALPHA_BITS ((1 << UPPERCASE_LETTER) | (1 << LOWERCASE_LETTER) \
| (1 << TITLECASE_LETTER) | (1 << MODIFIER_LETTER) | (1<<OTHER_LETTER))
+#define CONTROL_BITS ((1 << CONTROL) | (1 << FORMAT) | (1 << PRIVATE_USE))
+
#define DIGIT_BITS (1 << DECIMAL_DIGIT_NUMBER)
#define SPACE_BITS ((1 << SPACE_SEPARATOR) | (1 << LINE_SEPARATOR) \
| (1 << PARAGRAPH_SEPARATOR))
-#define CONNECTOR_BITS (1 << CONNECTOR_PUNCTUATION)
-
-#define PRINT_BITS (ALPHA_BITS | DIGIT_BITS | SPACE_BITS | \
- (1 << NON_SPACING_MARK) | (1 << ENCLOSING_MARK) | \
- (1 << COMBINING_SPACING_MARK) | (1 << LETTER_NUMBER) | \
- (1 << OTHER_NUMBER) | (1 << CONNECTOR_PUNCTUATION) | \
- (1 << DASH_PUNCTUATION) | (1 << OPEN_PUNCTUATION) | \
- (1 << CLOSE_PUNCTUATION) | (1 << INITIAL_QUOTE_PUNCTUATION) | \
- (1 << FINAL_QUOTE_PUNCTUATION) | (1 << OTHER_PUNCTUATION) | \
- (1 << MATH_SYMBOL) | (1 << CURRENCY_SYMBOL) | \
- (1 << MODIFIER_SYMBOL) | (1 << OTHER_SYMBOL))
+#define WORD_BITS (ALPHA_BITS | DIGIT_BITS | (1 << CONNECTOR_PUNCTUATION))
#define PUNCT_BITS ((1 << CONNECTOR_PUNCTUATION) | \
(1 << DASH_PUNCTUATION) | (1 << OPEN_PUNCTUATION) | \
(1 << CLOSE_PUNCTUATION) | (1 << INITIAL_QUOTE_PUNCTUATION) | \
(1 << FINAL_QUOTE_PUNCTUATION) | (1 << OTHER_PUNCTUATION))
+#define GRAPH_BITS (WORD_BITS | PUNCT_BITS | \
+ (1 << NON_SPACING_MARK) | (1 << ENCLOSING_MARK) | \
+ (1 << COMBINING_SPACING_MARK) | (1 << LETTER_NUMBER) | \
+ (1 << OTHER_NUMBER) | \
+ (1 << MATH_SYMBOL) | (1 << CURRENCY_SYMBOL) | \
+ (1 << MODIFIER_SYMBOL) | (1 << OTHER_SYMBOL))
+
/*
* Unicode characters less than this value are represented by themselves in
* UTF-8 strings.
@@ -1107,6 +1106,46 @@ Tcl_UtfNcasecmp(
/*
*----------------------------------------------------------------------
*
+ * Tcl_UtfNcasecmp --
+ *
+ * Compare UTF chars of string cs to string ct case insensitively.
+ * Replacement for strcasecmp in Tcl core, in places where UTF-8 should
+ * be handled.
+ *
+ * Results:
+ * Return <0 if cs < ct, 0 if cs == ct, or >0 if cs > ct.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclUtfCasecmp(
+ const char *cs, /* UTF string to compare to ct. */
+ const char *ct) /* UTF string cs is compared to. */
+{
+ while (*cs && *ct) {
+ Tcl_UniChar ch1, ch2;
+
+ cs += TclUtfToUniChar(cs, &ch1);
+ ct += TclUtfToUniChar(ct, &ch2);
+ if (ch1 != ch2) {
+ ch1 = Tcl_UniCharToLower(ch1);
+ ch2 = Tcl_UniCharToLower(ch2);
+ if (ch1 != ch2) {
+ return ch1 - ch2;
+ }
+ }
+ }
+ return UCHAR(*cs) - UCHAR(*ct);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
* Tcl_UniCharToUpper --
*
* Compute the uppercase equivalent of the given Unicode character.
@@ -1127,10 +1166,9 @@ Tcl_UniCharToUpper(
int info = GetUniCharInfo(ch);
if (GetCaseType(info) & 0x04) {
- return (Tcl_UniChar) (ch - GetDelta(info));
- } else {
- return ch;
+ ch -= GetDelta(info);
}
+ return (Tcl_UniChar) ch;
}
/*
@@ -1156,10 +1194,9 @@ Tcl_UniCharToLower(
int info = GetUniCharInfo(ch);
if (GetCaseType(info) & 0x02) {
- return (Tcl_UniChar) (ch + GetDelta(info));
- } else {
- return ch;
+ ch += GetDelta(info);
}
+ return (Tcl_UniChar) ch;
}
/*
@@ -1190,12 +1227,11 @@ Tcl_UniCharToTitle(
* Subtract or add one depending on the original case.
*/
- return (Tcl_UniChar) (ch + ((mode & 0x4) ? -1 : 1));
+ ch += ((mode & 0x4) ? -1 : 1);
} else if (mode == 0x4) {
- return (Tcl_UniChar) (ch - GetDelta(info));
- } else {
- return ch;
+ ch -= GetDelta(info);
}
+ return (Tcl_UniChar) ch;
}
/*
@@ -1329,9 +1365,7 @@ int
Tcl_UniCharIsAlnum(
int ch) /* Unicode character to test. */
{
- register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK);
-
- return (((ALPHA_BITS | DIGIT_BITS) >> category) & 1);
+ return (((ALPHA_BITS | DIGIT_BITS) >> GetCategory(ch)) & 1);
}
/*
@@ -1354,8 +1388,7 @@ int
Tcl_UniCharIsAlpha(
int ch) /* Unicode character to test. */
{
- register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK);
- return ((ALPHA_BITS >> category) & 1);
+ return ((ALPHA_BITS >> GetCategory(ch)) & 1);
}
/*
@@ -1378,7 +1411,7 @@ int
Tcl_UniCharIsControl(
int ch) /* Unicode character to test. */
{
- return ((GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK) == CONTROL);
+ return ((CONTROL_BITS >> GetCategory(ch)) & 1);
}
/*
@@ -1401,7 +1434,7 @@ int
Tcl_UniCharIsDigit(
int ch) /* Unicode character to test. */
{
- return (GetUniCharInfo(ch)&UNICODE_CATEGORY_MASK) == DECIMAL_DIGIT_NUMBER;
+ return (GetCategory(ch) == DECIMAL_DIGIT_NUMBER);
}
/*
@@ -1424,8 +1457,7 @@ int
Tcl_UniCharIsGraph(
int ch) /* Unicode character to test. */
{
- register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK);
- return (((PRINT_BITS >> category) & 1) && ((unsigned char) ch != ' '));
+ return ((GRAPH_BITS >> GetCategory(ch)) & 1);
}
/*
@@ -1448,7 +1480,7 @@ int
Tcl_UniCharIsLower(
int ch) /* Unicode character to test. */
{
- return ((GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK) == LOWERCASE_LETTER);
+ return (GetCategory(ch) == LOWERCASE_LETTER);
}
/*
@@ -1471,8 +1503,7 @@ int
Tcl_UniCharIsPrint(
int ch) /* Unicode character to test. */
{
- register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK);
- return ((PRINT_BITS >> category) & 1);
+ return (((GRAPH_BITS|SPACE_BITS) >> GetCategory(ch)) & 1);
}
/*
@@ -1495,8 +1526,7 @@ int
Tcl_UniCharIsPunct(
int ch) /* Unicode character to test. */
{
- register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK);
- return ((PUNCT_BITS >> category) & 1);
+ return ((PUNCT_BITS >> GetCategory(ch)) & 1);
}
/*
@@ -1519,18 +1549,19 @@ int
Tcl_UniCharIsSpace(
int ch) /* Unicode character to test. */
{
- register int category;
-
/*
* If the character is within the first 127 characters, just use the
* standard C function, otherwise consult the Unicode table.
*/
- if (ch < 0x80) {
- return TclIsSpaceProc((char)ch);
+ if (((Tcl_UniChar) ch) < ((Tcl_UniChar) 0x80)) {
+ return TclIsSpaceProc((char) ch);
+ } else if ((Tcl_UniChar) ch == 0x0085 || (Tcl_UniChar) ch == 0x180e
+ || (Tcl_UniChar) ch == 0x200b || (Tcl_UniChar) ch == 0x2060
+ || (Tcl_UniChar) ch == 0x202f || (Tcl_UniChar) ch == 0xfeff) {
+ return 1;
} else {
- category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK);
- return ((SPACE_BITS >> category) & 1);
+ return ((SPACE_BITS >> GetCategory(ch)) & 1);
}
}
@@ -1554,7 +1585,7 @@ int
Tcl_UniCharIsUpper(
int ch) /* Unicode character to test. */
{
- return ((GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK) == UPPERCASE_LETTER);
+ return (GetCategory(ch) == UPPERCASE_LETTER);
}
/*
@@ -1577,9 +1608,7 @@ int
Tcl_UniCharIsWordChar(
int ch) /* Unicode character to test. */
{
- register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK);
-
- return (((ALPHA_BITS | DIGIT_BITS | CONNECTOR_BITS) >> category) & 1);
+ return ((WORD_BITS >> GetCategory(ch)) & 1);
}
/*
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index 51508d2..2d00adf 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -13,6 +13,8 @@
*/
#include "tclInt.h"
+#include "tclParse.h"
+#include "tclStringTrim.h"
#include <math.h>
/*
@@ -25,9 +27,9 @@ static ProcessGlobalValue executableName = {
};
/*
- * The following values are used in the flags arguments of Tcl*Scan*Element and
- * Tcl*Convert*Element. The values TCL_DONT_USE_BRACES and TCL_DONT_QUOTE_HASH
- * are defined in tcl.h, like so:
+ * The following values are used in the flags arguments of Tcl*Scan*Element
+ * and Tcl*Convert*Element. The values TCL_DONT_USE_BRACES and
+ * TCL_DONT_QUOTE_HASH are defined in tcl.h, like so:
*
#define TCL_DONT_USE_BRACES 1
#define TCL_DONT_QUOTE_HASH 8
@@ -53,8 +55,8 @@ static ProcessGlobalValue executableName = {
* conversion is most appropriate for Tcl*Convert*Element() to perform, and
* sets two bits of the flags value to indicate the mode selected.
*
- * CONVERT_NONE The element needs no quoting. Its literal string
- * is suitable as is.
+ * CONVERT_NONE The element needs no quoting. Its literal string is
+ * suitable as is.
* CONVERT_BRACE The conversion should be enclosing the literal string
* in braces.
* CONVERT_ESCAPE The conversion should be using backslashes to escape
@@ -62,19 +64,19 @@ static ProcessGlobalValue executableName = {
* CONVERT_MASK A mask value used to extract the conversion mode from
* the flags argument.
* Also indicates a strange conversion mode where all
- * special characters are escaped with backslashes
- * *except for braces*. This is a strange and unnecessary
+ * special characters are escaped with backslashes
+ * *except for braces*. This is a strange and unnecessary
* case, but it's part of the historical way in which
- * lists have been formatted in Tcl. To experiment with
+ * lists have been formatted in Tcl. To experiment with
* removing this case, set the value of COMPAT to 0.
*
- * One last flag value is used only by callers of TclScanElement(). The flag
+ * One last flag value is used only by callers of TclScanElement(). The flag
* value produced by a call to Tcl*Scan*Element() will never leave this bit
* set.
*
- * CONVERT_ANY The caller of TclScanElement() declares it can make
- * no promise about what public flags will be passed to
- * the matching call of TclConvertElement(). As such,
+ * CONVERT_ANY The caller of TclScanElement() declares it can make no
+ * promise about what public flags will be passed to the
+ * matching call of TclConvertElement(). As such,
* TclScanElement() has to determine the worst case
* destination buffer length over all possibilities, and
* in other cases this means an overestimate of the
@@ -128,17 +130,17 @@ const Tcl_ObjType tclEndOffsetType = {
/*
* * STRING REPRESENTATION OF LISTS * * *
*
- * The next several routines implement the conversions of strings to and
- * from Tcl lists. To understand their operation, the rules of parsing
- * and generating the string representation of lists must be known. Here
- * we describe them in one place.
+ * The next several routines implement the conversions of strings to and from
+ * Tcl lists. To understand their operation, the rules of parsing and
+ * generating the string representation of lists must be known. Here we
+ * describe them in one place.
*
- * A list is made up of zero or more elements. Any string is a list if
- * it is made up of alternating substrings of element-separating ASCII
- * whitespace and properly formatted elements.
+ * A list is made up of zero or more elements. Any string is a list if it is
+ * made up of alternating substrings of element-separating ASCII whitespace
+ * and properly formatted elements.
*
- * The ASCII characters which can make up the whitespace between list
- * elements are:
+ * The ASCII characters which can make up the whitespace between list elements
+ * are:
*
* \u0009 \t TAB
* \u000A \n NEWLINE
@@ -157,69 +159,68 @@ const Tcl_ObjType tclEndOffsetType = {
* * Unlike command parsing, the BACKSLASH NEWLINE sequence is not
* considered to be a whitespace character.
*
- * * Other Unicode whitespace characters (recognized by
- * [string is space] or Tcl_UniCharIsSpace()) do not play any role
- * as element separators in Tcl lists.
+ * * Other Unicode whitespace characters (recognized by [string is space]
+ * or Tcl_UniCharIsSpace()) do not play any role as element separators
+ * in Tcl lists.
*
* * The NUL byte ought not appear, as it is not in strings properly
* encoded for Tcl, but if it is present, it is not treated as
- * separating whitespace, or a string terminator. It is just
- * another character in a list element.
- *
- * The interpretaton of a formatted substring as a list element follows
- * rules similar to the parsing of the words of a command in a Tcl script.
- * Backslash substitution plays a key role, and is defined exactly as it is
- * in command parsing. The same routine, TclParseBackslash() is used in both
- * command parsing and list parsing.
- *
- * NOTE: This means that if and when backslash substitution rules ever
- * change for command parsing, the interpretation of strings as lists also
- * changes.
+ * separating whitespace, or a string terminator. It is just another
+ * character in a list element.
+ *
+ * The interpretation of a formatted substring as a list element follows rules
+ * similar to the parsing of the words of a command in a Tcl script. Backslash
+ * substitution plays a key role, and is defined exactly as it is in command
+ * parsing. The same routine, TclParseBackslash() is used in both command
+ * parsing and list parsing.
+ *
+ * NOTE: This means that if and when backslash substitution rules ever change
+ * for command parsing, the interpretation of strings as lists also changes.
*
* Backslash substitution replaces an "escape sequence" of one or more
* characters starting with
* \u005c \ BACKSLASH
- * with a single character. The one character escape sequent case happens
- * only when BACKSLASH is the last character in the string. In all other
- * cases, the escape sequence is at least two characters long.
+ * with a single character. The one character escape sequence case happens only
+ * when BACKSLASH is the last character in the string. In all other cases, the
+ * escape sequence is at least two characters long.
*
- * The formatted substrings are interpreted as element values according to
- * the following cases:
+ * The formatted substrings are interpreted as element values according to the
+ * following cases:
*
* * If the first character of a formatted substring is
* \u007b { OPEN BRACE
* then the end of the substring is the matching
* \u007d } CLOSE BRACE
- * character, where matching is determined by counting nesting levels,
- * and not including any brace characters that are contained within a
- * backslash escape sequence in the nesting count. Having found the
- * matching brace, all characters between the braces are the string
- * value of the element. If no matching close brace is found before the
- * end of the string, the string is not a Tcl list. If the character
- * following the close brace is not an element separating whitespace
- * character, or the end of the string, then the string is not a Tcl list.
- *
- * NOTE: this differs from a brace-quoted word in the parsing of a
- * Tcl command only in its treatment of the backslash-newline sequence.
- * In a list element, the literal characters in the backslash-newline
- * sequence become part of the element value. In a script word,
- * conversion to a single SPACE character is done.
+ * character, where matching is determined by counting nesting levels, and
+ * not including any brace characters that are contained within a backslash
+ * escape sequence in the nesting count. Having found the matching brace,
+ * all characters between the braces are the string value of the element.
+ * If no matching close brace is found before the end of the string, the
+ * string is not a Tcl list. If the character following the close brace is
+ * not an element separating whitespace character, or the end of the string,
+ * then the string is not a Tcl list.
+ *
+ * NOTE: this differs from a brace-quoted word in the parsing of a Tcl
+ * command only in its treatment of the backslash-newline sequence. In a
+ * list element, the literal characters in the backslash-newline sequence
+ * become part of the element value. In a script word, conversion to a
+ * single SPACE character is done.
*
* NOTE: Most list element values can be represented by a formatted
- * substring using brace quoting. The exceptions are any element value
- * that includes an unbalanced brace not in a backslash escape sequence,
- * and any value that ends with a backslash not itself in a backslash
- * escape sequence.
+ * substring using brace quoting. The exceptions are any element value that
+ * includes an unbalanced brace not in a backslash escape sequence, and any
+ * value that ends with a backslash not itself in a backslash escape
+ * sequence.
*
* * If the first character of a formatted substring is
* \u0022 " QUOTE
* then the end of the substring is the next QUOTE character, not counting
* any QUOTE characters that are contained within a backslash escape
- * sequence. If no next QUOTE is found before the end of the string, the
- * string is not a Tcl list. If the character following the closing QUOTE
- * is not an element separating whitespace character, or the end of the
- * string, then the string is not a Tcl list. Having found the limits
- * of the substring, the element value is produced by performing backslash
+ * sequence. If no next QUOTE is found before the end of the string, the
+ * string is not a Tcl list. If the character following the closing QUOTE is
+ * not an element separating whitespace character, or the end of the string,
+ * then the string is not a Tcl list. Having found the limits of the
+ * substring, the element value is produced by performing backslash
* substitution on the character sequence between the open and close QUOTEs.
*
* NOTE: Any element value can be represented by this style of formatting,
@@ -230,7 +231,7 @@ const Tcl_ObjType tclEndOffsetType = {
* of the substring, the element value is produced by performing backslash
* substitution on it.
*
- * NOTE: Any element value can be represented by this style of formatting,
+ * NOTE: Any element value can be represented by this style of formatting,
* given suitable choice of backslash escape sequences, with one exception.
* The empty string cannot be represented as a list element without the use
* of either braces or quotes to delimit it.
@@ -238,32 +239,32 @@ const Tcl_ObjType tclEndOffsetType = {
* This collection of parsing rules is implemented in the routine
* TclFindElement().
*
- * In order to produce lists that can be parsed by these rules, we need
- * the ability to distinguish between characters that are part of a list
- * element value from characters providing syntax that define the structure
- * of the list. This means that our code that generates lists must at a
- * minimum be able to produce escape sequences for the 10 characters
- * identified above that have significance to a list parser.
+ * In order to produce lists that can be parsed by these rules, we need the
+ * ability to distinguish between characters that are part of a list element
+ * value from characters providing syntax that define the structure of the
+ * list. This means that our code that generates lists must at a minimum be
+ * able to produce escape sequences for the 10 characters identified above
+ * that have significance to a list parser.
*
- * * * CANONICAL LISTS * * * * *
+ * * * CANONICAL LISTS * * * * *
*
* In addition to the basic rules for parsing strings into Tcl lists, there
* are additional properties to be met by the set of list values that are
* generated by Tcl. Such list values are often said to be in "canonical
* form":
*
- * * When any canonical list is evaluated as a Tcl script, it is a script
- * of either zero commands (an empty list) or exactly one command. The
- * command word is exactly the first element of the list, and each argument
- * word is exactly one of the following elements of the list. This means
- * that any characters that have special meaning during script evaluation
- * need special treatment when canonical lists are produced:
+ * * When any canonical list is evaluated as a Tcl script, it is a script of
+ * either zero commands (an empty list) or exactly one command. The command
+ * word is exactly the first element of the list, and each argument word is
+ * exactly one of the following elements of the list. This means that any
+ * characters that have special meaning during script evaluation need
+ * special treatment when canonical lists are produced:
*
* * Whitespace between elements may not include NEWLINE.
* * The command terminating character,
* \u003b ; SEMICOLON
- * must be BRACEd, QUOTEd, or escaped so that it does not terminate
- * the command prematurely.
+ * must be BRACEd, QUOTEd, or escaped so that it does not terminate the
+ * command prematurely.
* * Any of the characters that begin substitutions in scripts,
* \u0024 $ DOLLAR
* \u005b [ OPEN BRACKET
@@ -273,11 +274,10 @@ const Tcl_ObjType tclEndOffsetType = {
* \u0023 # HASH
* that HASH character must be BRACEd, QUOTEd, or escaped so that it
* does not convert the command into a comment.
- * * Any list element that contains the character sequence
- * BACKSLASH NEWLINE cannot be formatted with BRACEs. The
- * BACKSLASH character must be represented by an escape
- * sequence, and unless QUOTEs are used, the NEWLINE must
- * be as well.
+ * * Any list element that contains the character sequence BACKSLASH
+ * NEWLINE cannot be formatted with BRACEs. The BACKSLASH character
+ * must be represented by an escape sequence, and unless QUOTEs are
+ * used, the NEWLINE must be as well.
*
* * It is also guaranteed that one can use a canonical list as a building
* block of a larger script within command substitution, as in this example:
@@ -288,66 +288,66 @@ const Tcl_ObjType tclEndOffsetType = {
*
* * Finally it is guaranteed that enclosing a canonical list in braces
* produces a new value that is also a canonical list. This new list has
- * length 1, and its only element is the original canonical list. This
- * same guarantee also makes it possible to construct scripts where an
- * argument word is given a list value by enclosing the canonical form
- * of that list in braces:
+ * length 1, and its only element is the original canonical list. This same
+ * guarantee also makes it possible to construct scripts where an argument
+ * word is given a list value by enclosing the canonical form of that list
+ * in braces:
* set script "puts {[list $one $two $three]}"; eval $script
* This sort of coding was once fairly common, though it's become more
* idiomatic to see the following instead:
* set script [list puts [list $one $two $three]]; eval $script
- * In order to support this guarantee, every canonical list must have
+ * In order to support this guarantee, every canonical list must have
* balance when counting those braces that are not in escape sequences.
*
* Within these constraints, the canonical list generation routines
- * TclScanElement() and TclConvertElement() attempt to generate the string
- * for any list that is easiest to read. When an element value is itself
+ * TclScanElement() and TclConvertElement() attempt to generate the string for
+ * any list that is easiest to read. When an element value is itself
* acceptable as the formatted substring, it is usually used (CONVERT_NONE).
- * When some quoting or escaping is required, use of BRACEs (CONVERT_BRACE)
- * is usually preferred over the use of escape sequences (CONVERT_ESCAPE).
- * There are some exceptions to both of these preferences for reasons of
- * code simplicity, efficiency, and continuation of historical habits.
- * Canonical lists never use the QUOTE formatting to delimit their elements
- * because that form of quoting does not nest, which makes construction of
- * nested lists far too much trouble. Canonical lists always use only a
- * single SPACE character for element-separating whitespace.
+ * When some quoting or escaping is required, use of BRACEs (CONVERT_BRACE) is
+ * usually preferred over the use of escape sequences (CONVERT_ESCAPE). There
+ * are some exceptions to both of these preferences for reasons of code
+ * simplicity, efficiency, and continuation of historical habits. Canonical
+ * lists never use the QUOTE formatting to delimit their elements because that
+ * form of quoting does not nest, which makes construction of nested lists far
+ * too much trouble. Canonical lists always use only a single SPACE character
+ * for element-separating whitespace.
*
* * * FUTURE CONSIDERATIONS * * *
*
* When a list element requires quoting or escaping due to a CLOSE BRACKET
* character or an internal QUOTE character, a strange formatting mode is
- * recommended. For example, if the value "a{b]c}d" is converted by the
- * usual modes:
+ * recommended. For example, if the value "a{b]c}d" is converted by the usual
+ * modes:
*
* CONVERT_BRACE: a{b]c}d => {a{b]c}d}
* CONVERT_ESCAPE: a{b]c}d => a\{b\]c\}d
*
- * we get perfectly usable formatted list elements. However, this is not
- * what Tcl releases have been producing. Instead, we have:
+ * we get perfectly usable formatted list elements. However, this is not what
+ * Tcl releases have been producing. Instead, we have:
*
* CONVERT_MASK: a{b]c}d => a{b\]c}d
*
- * where the CLOSE BRACKET is escaped, but the BRACEs are not. The same
- * effect can be seen replacing ] with " in this example. There does not
- * appear to be any functional or aesthetic purpose for this strange
- * additional mode. The sole purpose I can see for preserving it is to
- * keep generating the same formatted lists programmers have become accustomed
- * to, and perhaps written tests to expect. That is, compatibility only.
- * The additional code complexity required to support this mode is significant.
- * The lines of code supporting it are delimited in the routines below with
- * #if COMPAT directives. This makes it easy to experiment with eliminating
- * this formatting mode simply with "#define COMPAT 0" above. I believe
- * this is worth considering.
+ * where the CLOSE BRACKET is escaped, but the BRACEs are not. The same effect
+ * can be seen replacing ] with " in this example. There does not appear to be
+ * any functional or aesthetic purpose for this strange additional mode. The
+ * sole purpose I can see for preserving it is to keep generating the same
+ * formatted lists programmers have become accustomed to, and perhaps written
+ * tests to expect. That is, compatibility only. The additional code
+ * complexity required to support this mode is significant. The lines of code
+ * supporting it are delimited in the routines below with #if COMPAT
+ * directives. This makes it easy to experiment with eliminating this
+ * formatting mode simply with "#define COMPAT 0" above. I believe this is
+ * worth considering.
*
- * Another consideration is the treatment of QUOTE characters in list elements.
- * TclConvertElement() must have the ability to produce the escape sequence
- * \" so that when a list element begins with a QUOTE we do not confuse
- * that first character with a QUOTE used as list syntax to define list
- * structure. However, that is the only place where QUOTE characters need
- * quoting. In this way, handling QUOTE could really be much more like
- * the way we handle HASH which also needs quoting and escaping only in
- * particular situations. Following up this could increase the set of
- * list elements that can use the CONVERT_NONE formatting mode.
+ * Another consideration is the treatment of QUOTE characters in list
+ * elements. TclConvertElement() must have the ability to produce the escape
+ * sequence \" so that when a list element begins with a QUOTE we do not
+ * confuse that first character with a QUOTE used as list syntax to define
+ * list structure. However, that is the only place where QUOTE characters need
+ * quoting. In this way, handling QUOTE could really be much more like the way
+ * we handle HASH which also needs quoting and escaping only in particular
+ * situations. Following up this could increase the set of list elements that
+ * can use the CONVERT_NONE formatting mode.
*
* More speculative is that the demands of canonical list form require brace
* balance for the list as a whole, while the current implementation achieves
@@ -365,15 +365,15 @@ const Tcl_ObjType tclEndOffsetType = {
*
* Given 'bytes' pointing to 'numBytes' bytes, scan through them and
* count the number of whitespace runs that could be list element
- * separators. If 'numBytes' is -1, scan to the terminating '\0'.
- * Not a full list parser. Typically used to get a quick and dirty
- * overestimate of length size in order to allocate space for an
- * actual list parser to operate with.
+ * separators. If 'numBytes' is -1, scan to the terminating '\0'. Not a
+ * full list parser. Typically used to get a quick and dirty overestimate
+ * of length size in order to allocate space for an actual list parser to
+ * operate with.
*
* Results:
- * Returns the largest number of list elements that could possibly
- * be in this string, interpreted as a Tcl list. If 'endPtr' is not
- * NULL, writes a pointer to the end of the string scanned there.
+ * Returns the largest number of list elements that could possibly be in
+ * this string, interpreted as a Tcl list. If 'endPtr' is not NULL,
+ * writes a pointer to the end of the string scanned there.
*
* Side effects:
* None.
@@ -394,16 +394,25 @@ TclMaxListLength(
goto done;
}
- /* No list element before leading white space */
+ /*
+ * No list element before leading white space.
+ */
+
count += 1 - TclIsSpaceProc(*bytes);
- /* Count white space runs as potential element separators */
+ /*
+ * Count white space runs as potential element separators.
+ */
+
while (numBytes) {
if ((numBytes == -1) && (*bytes == '\0')) {
break;
}
if (TclIsSpaceProc(*bytes)) {
- /* Space run started; bump count */
+ /*
+ * Space run started; bump count.
+ */
+
count++;
do {
bytes++;
@@ -412,16 +421,22 @@ TclMaxListLength(
if ((numBytes == 0) || ((numBytes == -1) && (*bytes == '\0'))) {
break;
}
- /* (*bytes) is non-space; return to counting state */
+
+ /*
+ * (*bytes) is non-space; return to counting state.
+ */
}
bytes++;
numBytes -= (numBytes != -1);
}
- /* No list element following trailing white space */
+ /*
+ * No list element following trailing white space.
+ */
+
count -= TclIsSpaceProc(bytes[-1]);
- done:
+ done:
if (endPtr) {
*endPtr = bytes;
}
@@ -448,18 +463,18 @@ TclMaxListLength(
* that's part of the element. If this is the last argument in the list,
* then *nextPtr will point just after the last character in the list
* (i.e., at the character at list+listLength). If sizePtr is non-NULL,
- * *sizePtr is filled in with the number of bytes in the element. If
- * the element is in braces, then *elementPtr will point to the character
+ * *sizePtr is filled in with the number of bytes in the element. If the
+ * element is in braces, then *elementPtr will point to the character
* after the opening brace and *sizePtr will not include either of the
* braces. If there isn't an element in the list, *sizePtr will be zero,
* and both *elementPtr and *nextPtr will point just after the last
* character in the list. If literalPtr is non-NULL, *literalPtr is set
- * to a boolean value indicating whether the substring returned as
- * the values of **elementPtr and *sizePtr is the literal value of
- * a list element. If not, a call to TclCopyAndCollapse() is needed
- * to produce the actual value of the list element. Note: this function
- * does NOT collapse backslash sequences, but uses *literalPtr to tell
- * callers when it is required for them to do so.
+ * to a boolean value indicating whether the substring returned as the
+ * values of **elementPtr and *sizePtr is the literal value of a list
+ * element. If not, a call to TclCopyAndCollapse() is needed to produce
+ * the actual value of the list element. Note: this function does NOT
+ * collapse backslash sequences, but uses *literalPtr to tell callers
+ * when it is required for them to do so.
*
* Side effects:
* None.
@@ -586,9 +601,10 @@ TclFindElement(
/*
* A backslash sequence not within a brace quoted element
* means the value of the element is different from the
- * substring we are parsing. A call to TclCopyAndCollapse()
- * is needed to produce the element value. Inform the caller.
+ * substring we are parsing. A call to TclCopyAndCollapse() is
+ * needed to produce the element value. Inform the caller.
*/
+
literal = 0;
}
TclParseBackslash(p, limit - p, &numChars, NULL);
@@ -654,16 +670,16 @@ TclFindElement(
if (p == limit) {
if (openBraces != 0) {
if (interp != NULL) {
- Tcl_SetResult(interp, "unmatched open brace in list",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "unmatched open brace in list", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "BRACE",
NULL);
}
return TCL_ERROR;
} else if (inQuotes) {
if (interp != NULL) {
- Tcl_SetResult(interp, "unmatched open quote in list",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "unmatched open quote in list", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "QUOTE",
NULL);
}
@@ -696,9 +712,9 @@ TclFindElement(
*
* Results:
* Count bytes get copied from src to dst. Along the way, backslash
- * sequences are substituted in the copy. After scanning count bytes
- * from src, a null character is placed at the end of dst. Returns
- * the number of bytes that got written to dst.
+ * sequences are substituted in the copy. After scanning count bytes from
+ * src, a null character is placed at the end of dst. Returns the number
+ * of bytes that got written to dst.
*
* Side effects:
* None.
@@ -716,6 +732,7 @@ TclCopyAndCollapse(
while (count > 0) {
char c = *src;
+
if (c == '\\') {
int numRead;
int backslashCount = TclParseBackslash(src, count, &numRead, dst);
@@ -779,12 +796,11 @@ Tcl_SplitList(
int length, size, i, result, elSize;
/*
- * Allocate enough space to work in. A (const char *) for each
- * (possible) list element plus one more for terminating NULL,
- * plus as many bytes as in the original string value, plus one
- * more for a terminating '\0'. Space used to hold element separating
- * white space in the original string gets re-purposed to hold '\0'
- * characters in the argv array.
+ * Allocate enough space to work in. A (const char *) for each (possible)
+ * list element plus one more for terminating NULL, plus as many bytes as
+ * in the original string value, plus one more for a terminating '\0'.
+ * Space used to hold element separating white space in the original
+ * string gets re-purposed to hold '\0' characters in the argv array.
*/
size = TclMaxListLength(list, -1, &end) + 1;
@@ -809,8 +825,8 @@ Tcl_SplitList(
if (i >= size) {
ckfree(argv);
if (interp != NULL) {
- Tcl_SetResult(interp, "internal error in Tcl_SplitList",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "internal error in Tcl_SplitList", -1));
Tcl_SetErrorCode(interp, "TCL", "INTERNAL", "Tcl_SplitList",
NULL);
}
@@ -843,9 +859,9 @@ Tcl_SplitList(
* enclosing braces) to make the string into a valid Tcl list element.
*
* Results:
- * The return value is an overestimate of the number of bytes that
- * will be needed by Tcl_ConvertElement to produce a valid list element
- * from src. The word at *flagPtr is filled in with a value needed by
+ * The return value is an overestimate of the number of bytes that will
+ * be needed by Tcl_ConvertElement to produce a valid list element from
+ * src. The word at *flagPtr is filled in with a value needed by
* Tcl_ConvertElement when doing the actual conversion.
*
* Side effects:
@@ -875,10 +891,10 @@ Tcl_ScanElement(
* to the first null byte.
*
* Results:
- * The return value is an overestimate of the number of bytes that
- * will be needed by Tcl_ConvertCountedElement to produce a valid list
- * element from src. The word at *flagPtr is filled in with a value
- * needed by Tcl_ConvertCountedElement when doing the actual conversion.
+ * The return value is an overestimate of the number of bytes that will
+ * be needed by Tcl_ConvertCountedElement to produce a valid list element
+ * from src. The word at *flagPtr is filled in with a value needed by
+ * Tcl_ConvertCountedElement when doing the actual conversion.
*
* Side effects:
* None.
@@ -905,24 +921,24 @@ Tcl_ScanCountedElement(
*
* TclScanElement --
*
- * This function is a companion function to TclConvertElement. It
- * scans a string to see what needs to be done to it (e.g. add
- * backslashes or enclosing braces) to make the string into a valid Tcl
- * list element. If length is -1, then the string is scanned from src up
- * to the first null byte. A NULL value for src is treated as an
- * empty string. The incoming value of *flagPtr is a report from the
- * caller what additional flags it will pass to TclConvertElement().
+ * This function is a companion function to TclConvertElement. It scans a
+ * string to see what needs to be done to it (e.g. add backslashes or
+ * enclosing braces) to make the string into a valid Tcl list element. If
+ * length is -1, then the string is scanned from src up to the first null
+ * byte. A NULL value for src is treated as an empty string. The incoming
+ * value of *flagPtr is a report from the caller what additional flags it
+ * will pass to TclConvertElement().
*
* Results:
- * The recommended formatting mode for the element is determined and
- * a value is written to *flagPtr indicating that recommendation. This
+ * The recommended formatting mode for the element is determined and a
+ * value is written to *flagPtr indicating that recommendation. This
* recommendation is combined with the incoming flag values in *flagPtr
* set by the caller to determine how many bytes will be needed by
* TclConvertElement() in which to write the formatted element following
- * the recommendation modified by the flag values. This number of bytes
- * is the return value of the routine. In some situations it may be
- * an overestimate, but so long as the caller passes the same flags
- * to TclConvertElement(), it will be large enough.
+ * the recommendation modified by the flag values. This number of bytes
+ * is the return value of the routine. In some situations it may be an
+ * overestimate, but so long as the caller passes the same flags to
+ * TclConvertElement(), it will be large enough.
*
* Side effects:
* None.
@@ -940,7 +956,7 @@ TclScanElement(
const char *p = src;
int nestingLevel = 0; /* Brace nesting count */
int forbidNone = 0; /* Do not permit CONVERT_NONE mode. Something
- needs protection or escape. */
+ * needs protection or escape. */
int requireEscape = 0; /* Force use of CONVERT_ESCAPE mode. For some
* reason bare or brace-quoted form fails. */
int extra = 0; /* Count of number of extra bytes needed for
@@ -952,10 +968,13 @@ TclScanElement(
int preferEscape = 0; /* Use preferences to track whether to use */
int preferBrace = 0; /* CONVERT_MASK mode. */
int braceCount = 0; /* Count of all braces '{' '}' seen. */
-#endif
+#endif /* COMPAT */
if ((p == NULL) || (length == 0) || ((*p == '\0') && (length == -1))) {
- /* Empty string element must be brace quoted. */
+ /*
+ * Empty string element must be brace quoted.
+ */
+
*flagPtr = CONVERT_BRACE;
return 2;
}
@@ -965,34 +984,39 @@ TclScanElement(
* Must escape or protect so leading character of value is not
* misinterpreted as list element delimiting syntax.
*/
+
forbidNone = 1;
#if COMPAT
preferBrace = 1;
-#endif
+#endif /* COMPAT */
}
while (length) {
+ if (CHAR_TYPE(*p) != TYPE_NORMAL) {
switch (*p) {
- case '{':
+ case '{': /* TYPE_BRACE */
#if COMPAT
braceCount++;
-#endif
+#endif /* COMPAT */
extra++; /* Escape '{' => '\{' */
nestingLevel++;
break;
- case '}':
+ case '}': /* TYPE_BRACE */
#if COMPAT
braceCount++;
-#endif
+#endif /* COMPAT */
extra++; /* Escape '}' => '\}' */
nestingLevel--;
if (nestingLevel < 0) {
- /* Unbalanced braces! Cannot format with brace quoting. */
+ /*
+ * Unbalanced braces! Cannot format with brace quoting.
+ */
+
requireEscape = 1;
}
break;
- case ']':
- case '"':
+ case ']': /* TYPE_CLOSE_BRACK */
+ case '"': /* TYPE_SPACE */
#if COMPAT
forbidNone = 1;
extra++; /* Escapes all just prepend a backslash */
@@ -1000,32 +1024,39 @@ TclScanElement(
break;
#else
/* FLOW THROUGH */
-#endif
- case '[':
- case '$':
- case ';':
- case ' ':
- case '\f':
- case '\n':
- case '\r':
- case '\t':
- case '\v':
+#endif /* COMPAT */
+ case '[': /* TYPE_SUBS */
+ case '$': /* TYPE_SUBS */
+ case ';': /* TYPE_COMMAND_END */
+ case ' ': /* TYPE_SPACE */
+ case '\f': /* TYPE_SPACE */
+ case '\n': /* TYPE_COMMAND_END */
+ case '\r': /* TYPE_SPACE */
+ case '\t': /* TYPE_SPACE */
+ case '\v': /* TYPE_SPACE */
forbidNone = 1;
extra++; /* Escape sequences all one byte longer. */
#if COMPAT
preferBrace = 1;
-#endif
+#endif /* COMPAT */
break;
- case '\\':
+ case '\\': /* TYPE_SUBS */
extra++; /* Escape '\' => '\\' */
if ((length == 1) || ((length == -1) && (p[1] == '\0'))) {
- /* Final backslash. Cannot format with brace quoting. */
+ /*
+ * Final backslash. Cannot format with brace quoting.
+ */
+
requireEscape = 1;
break;
}
if (p[1] == '\n') {
extra++; /* Escape newline => '\n', one byte longer */
- /* Backslash newline sequence. Brace quoting not permitted. */
+
+ /*
+ * Backslash newline sequence. Brace quoting not permitted.
+ */
+
requireEscape = 1;
length -= (length > 0);
p++;
@@ -1039,35 +1070,47 @@ TclScanElement(
forbidNone = 1;
#if COMPAT
preferBrace = 1;
-#endif
+#endif /* COMPAT */
break;
- case '\0':
+ case '\0': /* TYPE_SUBS */
if (length == -1) {
goto endOfString;
}
/* TODO: Panic on improper encoding? */
break;
}
+ }
length -= (length > 0);
p++;
}
- endOfString:
+ endOfString:
if (nestingLevel != 0) {
- /* Unbalanced braces! Cannot format with brace quoting. */
+ /*
+ * Unbalanced braces! Cannot format with brace quoting.
+ */
+
requireEscape = 1;
}
- /* We need at least as many bytes as are in the element value... */
+ /*
+ * We need at least as many bytes as are in the element value...
+ */
+
bytesNeeded = p - src;
if (requireEscape) {
/*
- * We must use escape sequences. Add all the extra bytes needed
- * to have room to create them.
+ * We must use escape sequences. Add all the extra bytes needed to
+ * have room to create them.
*/
+
bytesNeeded += extra;
- /* Make room to escape leading #, if needed. */
+
+ /*
+ * Make room to escape leading #, if needed.
+ */
+
if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) {
bytesNeeded++;
}
@@ -1077,12 +1120,13 @@ TclScanElement(
if (*flagPtr & CONVERT_ANY) {
/*
* The caller has not let us know what flags it will pass to
- * TclConvertElement() so compute the max size we might need for
- * any possible choice. Normally the formatting using escape
- * sequences is the longer one, and a minimum "extra" value of 2
- * makes sure we don't request too small a buffer in those edge
- * cases where that's not true.
+ * TclConvertElement() so compute the max size we might need for any
+ * possible choice. Normally the formatting using escape sequences is
+ * the longer one, and a minimum "extra" value of 2 makes sure we
+ * don't request too small a buffer in those edge cases where that's
+ * not true.
*/
+
if (extra < 2) {
extra = 2;
}
@@ -1090,59 +1134,78 @@ TclScanElement(
*flagPtr |= TCL_DONT_USE_BRACES;
}
if (forbidNone) {
- /* We must request some form of quoting of escaping... */
+ /*
+ * We must request some form of quoting of escaping...
+ */
+
#if COMPAT
if (preferEscape && !preferBrace) {
/*
- * If we are quoting solely due to ] or internal " characters
- * use the CONVERT_MASK mode where we escape all special
- * characters except for braces. "extra" counted space needed
- * to escape braces too, so substract "braceCount" to get our
- * actual needs.
+ * If we are quoting solely due to ] or internal " characters use
+ * the CONVERT_MASK mode where we escape all special characters
+ * except for braces. "extra" counted space needed to escape
+ * braces too, so substract "braceCount" to get our actual needs.
*/
+
bytesNeeded += (extra - braceCount);
/* Make room to escape leading #, if needed. */
if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) {
bytesNeeded++;
}
+
/*
* If the caller reports it will direct TclConvertElement() to
* use full escapes on the element, add back the bytes needed to
* escape the braces.
*/
+
if (*flagPtr & TCL_DONT_USE_BRACES) {
bytesNeeded += braceCount;
}
*flagPtr = CONVERT_MASK;
goto overflowCheck;
}
-#endif
+#endif /* COMPAT */
if (*flagPtr & TCL_DONT_USE_BRACES) {
/*
* If the caller reports it will direct TclConvertElement() to
* use escapes, add the extra bytes needed to have room for them.
*/
+
bytesNeeded += extra;
- /* Make room to escape leading #, if needed. */
+
+ /*
+ * Make room to escape leading #, if needed.
+ */
+
if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) {
bytesNeeded++;
}
} else {
- /* Add 2 bytes for room for the enclosing braces. */
+ /*
+ * Add 2 bytes for room for the enclosing braces.
+ */
+
bytesNeeded += 2;
}
*flagPtr = CONVERT_BRACE;
goto overflowCheck;
}
- /* So far, no need to quote or escape anything. */
+ /*
+ * So far, no need to quote or escape anything.
+ */
+
if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) {
- /* If we need to quote a leading #, make room to enclose in braces. */
+ /*
+ * If we need to quote a leading #, make room to enclose in braces.
+ */
+
bytesNeeded += 2;
}
*flagPtr = CONVERT_NONE;
- overflowCheck:
+ overflowCheck:
if (bytesNeeded < 0) {
Tcl_Panic("TclScanElement: string length overflow");
}
@@ -1217,9 +1280,9 @@ Tcl_ConvertCountedElement(
*
* TclConvertElement --
*
- * This is a companion function to TclScanElement. Given the
- * information produced by TclScanElement, this function converts
- * a string to a list element equal to that string.
+ * This is a companion function to TclScanElement. Given the information
+ * produced by TclScanElement, this function converts a string to a list
+ * element equal to that string.
*
* Results:
* Information is copied to *dst in the form of a list element identical
@@ -1233,7 +1296,8 @@ Tcl_ConvertCountedElement(
*----------------------------------------------------------------------
*/
-int TclConvertElement(
+int
+TclConvertElement(
register const char *src, /* Source information for list element. */
int length, /* Number of bytes in src, or -1. */
char *dst, /* Place to put list-ified element. */
@@ -1242,19 +1306,28 @@ int TclConvertElement(
int conversion = flags & CONVERT_MASK;
char *p = dst;
- /* Let the caller demand we use escape sequences rather than braces. */
+ /*
+ * Let the caller demand we use escape sequences rather than braces.
+ */
+
if ((flags & TCL_DONT_USE_BRACES) && (conversion & CONVERT_BRACE)) {
conversion = CONVERT_ESCAPE;
}
- /* No matter what the caller demands, empty string must be braced! */
- if ((src == NULL) || (length == 0) || ((*src == '\0') && (length == -1))) {
+ /*
+ * No matter what the caller demands, empty string must be braced!
+ */
+
+ if ((src == NULL) || (length == 0) || (*src == '\0' && length == -1)) {
src = tclEmptyStringRep;
length = 0;
conversion = CONVERT_BRACE;
}
- /* Escape leading hash as needed and requested. */
+ /*
+ * Escape leading hash as needed and requested.
+ */
+
if ((*src == '#') && !(flags & TCL_DONT_QUOTE_HASH)) {
if (conversion == CONVERT_ESCAPE) {
p[0] = '\\';
@@ -1267,7 +1340,10 @@ int TclConvertElement(
}
}
- /* No escape or quoting needed. Copy the literal string value. */
+ /*
+ * No escape or quoting needed. Copy the literal string value.
+ */
+
if (conversion == CONVERT_NONE) {
if (length == -1) {
/* TODO: INT_MAX overflow? */
@@ -1281,7 +1357,10 @@ int TclConvertElement(
}
}
- /* Formatted string is original string enclosed in braces. */
+ /*
+ * Formatted string is original string enclosed in braces.
+ */
+
if (conversion == CONVERT_BRACE) {
*p = '{';
p++;
@@ -1301,7 +1380,10 @@ int TclConvertElement(
/* conversion == CONVERT_ESCAPE or CONVERT_MASK */
- /* Formatted string is original string converted to escape sequences. */
+ /*
+ * Formatted string is original string converted to escape sequences.
+ */
+
for ( ; length; src++, length -= (length > 0)) {
switch (*src) {
case ']':
@@ -1317,13 +1399,12 @@ int TclConvertElement(
case '{':
case '}':
#if COMPAT
- if (conversion == CONVERT_ESCAPE) {
-#endif
+ if (conversion == CONVERT_ESCAPE)
+#endif /* COMPAT */
+ {
*p = '\\';
p++;
-#if COMPAT
}
-#endif
break;
case '\f':
*p = '\\';
@@ -1359,13 +1440,15 @@ int TclConvertElement(
if (length == -1) {
return p - dst;
}
+
/*
- * If we reach this point, there's an embedded NULL in the
- * string range being processed, which should not happen when
- * the encoding rules for Tcl strings are properly followed.
- * If the day ever comes when we stop tolerating such things,
- * this is where to put the Tcl_Panic().
+ * If we reach this point, there's an embedded NULL in the string
+ * range being processed, which should not happen when the
+ * encoding rules for Tcl strings are properly followed. If the
+ * day ever comes when we stop tolerating such things, this is
+ * where to put the Tcl_Panic().
*/
+
break;
}
*p = *src;
@@ -1399,17 +1482,18 @@ Tcl_Merge(
int argc, /* How many strings to merge. */
const char *const *argv) /* Array of string values. */
{
-# define LOCAL_SIZE 20
+#define LOCAL_SIZE 20
int localFlags[LOCAL_SIZE], *flagPtr = NULL;
int i, bytesNeeded = 0;
char *result, *dst;
const int maxFlags = UINT_MAX / sizeof(int);
+ /*
+ * Handle empty list case first, so logic of the general case can be
+ * simpler.
+ */
+
if (argc == 0) {
- /*
- * Handle empty list case first, so logic of the general case
- * can be simpler.
- */
result = ckalloc(1);
result[0] = '\0';
return result;
@@ -1423,17 +1507,17 @@ Tcl_Merge(
flagPtr = localFlags;
} else if (argc > maxFlags) {
/*
- * We cannot allocate a large enough flag array to format this
- * list in one pass. We could imagine converting this routine
- * to a multi-pass implementation, but for sizeof(int) == 4,
- * the limit is a max of 2^30 list elements and since each element
- * is at least one byte formatted, and requires one byte space
- * between it and the next one, that a minimum space requirement
- * of 2^31 bytes, which is already INT_MAX. If we tried to format
- * a list of > maxFlags elements, we're just going to overflow
- * the size limits on the formatted string anyway, so just issue
- * that same panic early.
+ * We cannot allocate a large enough flag array to format this list in
+ * one pass. We could imagine converting this routine to a multi-pass
+ * implementation, but for sizeof(int) == 4, the limit is a max of
+ * 2^30 list elements and since each element is at least one byte
+ * formatted, and requires one byte space between it and the next one,
+ * that a minimum space requirement of 2^31 bytes, which is already
+ * INT_MAX. If we tried to format a list of > maxFlags elements, we're
+ * just going to overflow the size limits on the formatted string
+ * anyway, so just issue that same panic early.
*/
+
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
} else {
flagPtr = ckalloc(argc * sizeof(int));
@@ -1508,9 +1592,10 @@ Tcl_Backslash(
*----------------------------------------------------------------------
*
* TclTrimRight --
- * 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.
+ *
+ * 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.
*
* Results:
* The number of bytes to be removed from the end of the string.
@@ -1523,10 +1608,10 @@ Tcl_Backslash(
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 */
+ 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 */
{
const char *p = bytes + numBytes;
int pInc;
@@ -1535,12 +1620,18 @@ TclTrimRight(
Tcl_Panic("TclTrimRight works only on null-terminated strings");
}
- /* Empty strings -> nothing to do */
+ /*
+ * Empty strings -> nothing to do.
+ */
+
if ((numBytes == 0) || (numTrim == 0)) {
return 0;
}
- /* Outer loop: iterate over string to be trimmed */
+ /*
+ * Outer loop: iterate over string to be trimmed.
+ */
+
do {
Tcl_UniChar ch1;
const char *q = trim;
@@ -1549,7 +1640,10 @@ TclTrimRight(
p = Tcl_UtfPrev(p, bytes);
pInc = TclUtfToUniChar(p, &ch1);
- /* Inner loop: scan trim string for match to current character */
+ /*
+ * Inner loop: scan trim string for match to current character.
+ */
+
do {
Tcl_UniChar ch2;
int qInc = TclUtfToUniChar(q, &ch2);
@@ -1563,7 +1657,10 @@ TclTrimRight(
} while (bytesLeft);
if (bytesLeft == 0) {
- /* No match; trim task done; *p is last non-trimmed char */
+ /*
+ * No match; trim task done; *p is last non-trimmed char.
+ */
+
p += pInc;
break;
}
@@ -1576,9 +1673,10 @@ TclTrimRight(
*----------------------------------------------------------------------
*
* 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 which must both be null
+ * terminated. Conceptually trims 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.
@@ -1591,10 +1689,10 @@ TclTrimRight(
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 */
+ 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 */
{
const char *p = bytes;
@@ -1602,19 +1700,28 @@ TclTrimLeft(
Tcl_Panic("TclTrimLeft works only on null-terminated strings");
}
- /* Empty strings -> nothing to do */
+ /*
+ * Empty strings -> nothing to do.
+ */
+
if ((numBytes == 0) || (numTrim == 0)) {
return 0;
}
- /* Outer loop: iterate over string to be trimmed */
+ /*
+ * Outer loop: iterate over string to be trimmed.
+ */
+
do {
Tcl_UniChar ch1;
int pInc = TclUtfToUniChar(p, &ch1);
const char *q = trim;
int bytesLeft = numTrim;
- /* Inner loop: scan trim string for match to current character */
+ /*
+ * Inner loop: scan trim string for match to current character.
+ */
+
do {
Tcl_UniChar ch2;
int qInc = TclUtfToUniChar(q, &ch2);
@@ -1628,7 +1735,10 @@ TclTrimLeft(
} while (bytesLeft);
if (bytesLeft == 0) {
- /* No match; trim task done; *p is first non-trimmed char */
+ /*
+ * No match; trim task done; *p is first non-trimmed char.
+ */
+
break;
}
@@ -1659,8 +1769,7 @@ TclTrimLeft(
*/
/* The whitespace characters trimmed during [concat] operations */
-#define CONCAT_WS " \f\v\r\t\n"
-#define CONCAT_WS_SIZE (int) (sizeof(CONCAT_WS "") - 1)
+#define CONCAT_WS_SIZE (int) (sizeof(CONCAT_TRIM_SET "") - 1)
char *
Tcl_Concat(
@@ -1670,14 +1779,20 @@ Tcl_Concat(
int i, needSpace = 0, bytesNeeded = 0;
char *result, *p;
- /* Dispose of the empty result corner case first to simplify later code */
+ /*
+ * Dispose of the empty result corner case first to simplify later code.
+ */
+
if (argc == 0) {
result = (char *) ckalloc(1);
result[0] = '\0';
return result;
}
- /* First allocate the result buffer at the size required */
+ /*
+ * First allocate the result buffer at the size required.
+ */
+
for (i = 0; i < argc; i++) {
bytesNeeded += strlen(argv[i]);
if (bytesNeeded < 0) {
@@ -1686,13 +1801,18 @@ Tcl_Concat(
}
if (bytesNeeded + argc - 1 < 0) {
/*
- * Panic test could be tighter, but not going to bother for
- * this legacy routine.
+ * Panic test could be tighter, but not going to bother for this
+ * legacy routine.
*/
+
Tcl_Panic("Tcl_Concat: max size of Tcl value exceeded");
}
- /* All element bytes + (argc - 1) spaces + 1 terminating NULL */
- result = (char *) ckalloc((unsigned) (bytesNeeded + argc));
+
+ /*
+ * All element bytes + (argc - 1) spaces + 1 terminating NULL.
+ */
+
+ result = ckalloc((unsigned) (bytesNeeded + argc));
for (p = result, i = 0; i < argc; i++) {
int trim, elemLength;
@@ -1701,26 +1821,37 @@ Tcl_Concat(
element = argv[i];
elemLength = strlen(argv[i]);
- /* Trim away the leading whitespace */
- trim = TclTrimLeft(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE);
+ /*
+ * 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 trailing whitespace. Do not permit trimming to expose
+ * a final backslash character.
*/
- trim = TclTrimRight(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE);
+ trim = TclTrimRight(element, elemLength, CONCAT_TRIM_SET,
+ CONCAT_WS_SIZE);
trim -= trim && (element[elemLength - trim - 1] == '\\');
elemLength -= trim;
- /* If we're left with empty element after trimming, do nothing */
+ /*
+ * If we're left with empty element after trimming, do nothing.
+ */
+
if (elemLength == 0) {
continue;
}
- /* Append to the result with space if needed */
+ /*
+ * Append to the result with space if needed.
+ */
+
if (needSpace) {
*p++ = ' ';
}
@@ -1799,9 +1930,10 @@ Tcl_ConcatObj(
/*
* Something cannot be determined to be safe, so build the concatenation
* the slow way, using the string representations.
+ *
+ * First try to pre-allocate the size required.
*/
- /* First try to pre-allocate the size required */
for (i = 0; i < objc; i++) {
element = TclGetStringFromObj(objv[i], &elemLength);
bytesNeeded += elemLength;
@@ -1809,11 +1941,13 @@ Tcl_ConcatObj(
break;
}
}
+
/*
- * Does not matter if this fails, will simply try later to build up
- * the string with each Append reallocating as needed with the usual
- * string append algorithm. When that fails it will report the error.
+ * Does not matter if this fails, will simply try later to build up the
+ * string with each Append reallocating as needed with the usual string
+ * append algorithm. When that fails it will report the error.
*/
+
TclNewObj(resPtr);
Tcl_AttemptSetObjLength(resPtr, bytesNeeded + objc - 1);
Tcl_SetObjLength(resPtr, 0);
@@ -1823,26 +1957,37 @@ Tcl_ConcatObj(
element = TclGetStringFromObj(objv[i], &elemLength);
- /* Trim away the leading whitespace */
- trim = TclTrimLeft(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE);
+ /*
+ * 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 trailing whitespace. Do not permit trimming to expose
+ * a final backslash character.
*/
- trim = TclTrimRight(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE);
+ trim = TclTrimRight(element, elemLength, CONCAT_TRIM_SET,
+ CONCAT_WS_SIZE);
trim -= trim && (element[elemLength - trim - 1] == '\\');
elemLength -= trim;
- /* If we're left with empty element after trimming, do nothing */
+ /*
+ * If we're left with empty element after trimming, do nothing.
+ */
+
if (elemLength == 0) {
continue;
}
- /* Append to the result with space if needed */
+ /*
+ * Append to the result with space if needed.
+ */
+
if (needSpace) {
Tcl_AppendToObj(resPtr, " ", 1);
}
@@ -2246,6 +2391,7 @@ TclByteArrayMatch(
/*
* Matches ranges of form [a-z] or [z-a].
*/
+
break;
}
} else if (startChar == ch1) {
@@ -2292,9 +2438,9 @@ TclByteArrayMatch(
*
* TclStringMatchObj --
*
- * See if a particular string matches a particular pattern.
- * Allows case insensitivity. This is the generic multi-type handler
- * for the various matching algorithms.
+ * See if a particular string matches a particular pattern. Allows case
+ * insensitivity. This is the generic multi-type handler for the various
+ * matching algorithms.
*
* Results:
* The return value is 1 if string matches pattern, and 0 otherwise. The
@@ -2435,6 +2581,37 @@ Tcl_DStringAppend(
/*
*----------------------------------------------------------------------
*
+ * TclDStringAppendObj, TclDStringAppendDString --
+ *
+ * Simple wrappers round Tcl_DStringAppend that make it easier to append
+ * from particular sources of strings.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+TclDStringAppendObj(
+ Tcl_DString *dsPtr,
+ Tcl_Obj *objPtr)
+{
+ int length;
+ char *bytes = Tcl_GetStringFromObj(objPtr, &length);
+
+ return Tcl_DStringAppend(dsPtr, bytes, length);
+}
+
+char *
+TclDStringAppendDString(
+ Tcl_DString *dsPtr,
+ Tcl_DString *toAppendPtr)
+{
+ return Tcl_DStringAppend(dsPtr, Tcl_DStringValue(toAppendPtr),
+ Tcl_DStringLength(toAppendPtr));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* Tcl_DStringAppendElement --
*
* Append a list element to the current value of a dynamic string.
@@ -2623,24 +2800,8 @@ Tcl_DStringResult(
Tcl_DString *dsPtr) /* Dynamic string that is to become the
* result of interp. */
{
- Interp *iPtr = (Interp *) interp;
-
Tcl_ResetResult(interp);
-
- if (dsPtr->string != dsPtr->staticSpace) {
- iPtr->result = dsPtr->string;
- iPtr->freeProc = TCL_DYNAMIC;
- } else if (dsPtr->length < TCL_RESULT_SIZE) {
- iPtr->result = iPtr->resultSpace;
- memcpy(iPtr->result, dsPtr->string, dsPtr->length + 1);
- } else {
- Tcl_SetResult(interp, dsPtr->string, TCL_VOLATILE);
- }
-
- dsPtr->string = dsPtr->staticSpace;
- dsPtr->length = 0;
- dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
- dsPtr->staticSpace[0] = '\0';
+ Tcl_SetObjResult(interp, TclDStringToObj(dsPtr));
}
/*
@@ -2676,6 +2837,39 @@ Tcl_DStringGetResult(
}
/*
+ * Do more efficient transfer when we know the result is a Tcl_Obj. When
+ * there's no st`ring result, we only have to deal with two cases:
+ *
+ * 1. When the string rep is the empty string, when we don't copy but
+ * instead use the staticSpace in the DString to hold an empty string.
+
+ * 2. When the string rep is not there or there's a real string rep, when
+ * we use Tcl_GetString to fetch (or generate) the string rep - which
+ * we know to have been allocated with ckalloc() - and use it to
+ * populate the DString space. Then, we free the internal rep. and set
+ * the object's string representation back to the canonical empty
+ * string.
+ */
+
+ if (!iPtr->result[0] && iPtr->objResultPtr
+ && !Tcl_IsShared(iPtr->objResultPtr)) {
+ if (iPtr->objResultPtr->bytes == tclEmptyStringRep) {
+ dsPtr->string = dsPtr->staticSpace;
+ dsPtr->string[0] = 0;
+ dsPtr->length = 0;
+ dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
+ } else {
+ dsPtr->string = Tcl_GetString(iPtr->objResultPtr);
+ dsPtr->length = iPtr->objResultPtr->length;
+ dsPtr->spaceAvl = dsPtr->length + 1;
+ TclFreeIntRep(iPtr->objResultPtr);
+ iPtr->objResultPtr->bytes = tclEmptyStringRep;
+ iPtr->objResultPtr->length = 0;
+ }
+ return;
+ }
+
+ /*
* If the string result is empty, move the object result to the string
* result, then reset the object result.
*/
@@ -2712,6 +2906,66 @@ Tcl_DStringGetResult(
/*
*----------------------------------------------------------------------
*
+ * TclDStringToObj --
+ *
+ * This function moves a dynamic string's contents to a new Tcl_Obj. Be
+ * aware that this function does *not* check that the encoding of the
+ * contents of the dynamic string is correct; this is the caller's
+ * responsibility to enforce.
+ *
+ * Results:
+ * The newly-allocated untyped (i.e., typePtr==NULL) Tcl_Obj with a
+ * reference count of zero.
+ *
+ * Side effects:
+ * The string is "moved" to the object. dsPtr is reinitialized to an
+ * empty string; it does not need to be Tcl_DStringFree'd after this if
+ * not used further.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclDStringToObj(
+ Tcl_DString *dsPtr)
+{
+ Tcl_Obj *result;
+
+ if (dsPtr->string == dsPtr->staticSpace) {
+ if (dsPtr->length == 0) {
+ TclNewObj(result);
+ } else {
+ /*
+ * Static buffer, so must copy.
+ */
+
+ TclNewStringObj(result, dsPtr->string, dsPtr->length);
+ }
+ } else {
+ /*
+ * Dynamic buffer, so transfer ownership and reset.
+ */
+
+ TclNewObj(result);
+ result->bytes = dsPtr->string;
+ result->length = dsPtr->length;
+ }
+
+ /*
+ * Re-establish the DString as empty with no buffer allocated.
+ */
+
+ dsPtr->string = dsPtr->staticSpace;
+ dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
+ dsPtr->length = 0;
+ dsPtr->staticSpace[0] = '\0';
+
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* Tcl_DStringStartSublist --
*
* This function adds the necessary information to a dynamic string
@@ -2732,9 +2986,9 @@ Tcl_DStringStartSublist(
Tcl_DString *dsPtr) /* Dynamic string. */
{
if (TclNeedSpace(dsPtr->string, dsPtr->string + dsPtr->length)) {
- Tcl_DStringAppend(dsPtr, " {", -1);
+ TclDStringAppendLiteral(dsPtr, " {");
} else {
- Tcl_DStringAppend(dsPtr, "{", -1);
+ TclDStringAppendLiteral(dsPtr, "{");
}
}
@@ -2760,7 +3014,7 @@ void
Tcl_DStringEndSublist(
Tcl_DString *dsPtr) /* Dynamic string. */
{
- Tcl_DStringAppend(dsPtr, "}", -1);
+ TclDStringAppendLiteral(dsPtr, "}");
}
/*
@@ -2855,12 +3109,12 @@ Tcl_PrintDouble(
* Tcl 8.4 implements the first of these, which gives rise to
* anomalies in formatting:
*
- * % expr 0.1
- * 0.10000000000000001
- * % expr 0.01
- * 0.01
- * % expr 1e-7
- * 9.9999999999999995e-08
+ * % expr 0.1
+ * 0.10000000000000001
+ * % expr 0.01
+ * 0.01
+ * % expr 1e-7
+ * 9.9999999999999995e-08
*
* For human readability, it appears better to choose the second rule,
* and let [expr 0.1] return 0.1. But for 8.4 compatibility, we prefer
@@ -2873,8 +3127,8 @@ Tcl_PrintDouble(
*/
digits = TclDoubleDigits(value, *precisionPtr,
- TCL_DD_E_FORMAT /* | TCL_DD_SHORTEN_FLAG */,
- &exponent, &signum, &end);
+ TCL_DD_E_FORMAT /* | TCL_DD_SHORTEN_FLAG */,
+ &exponent, &signum, &end);
}
if (signum) {
*dst++ = '-';
@@ -3130,10 +3384,10 @@ TclNeedSpace(
*/
int
-TclFormatInt(buffer, n)
- char *buffer; /* Points to the storage into which the
+TclFormatInt(
+ char *buffer, /* Points to the storage into which the
* formatted characters are written. */
- long n; /* The integer to format. */
+ long n) /* The integer to format. */
{
long intVal;
int i;
@@ -3151,12 +3405,13 @@ TclFormatInt(buffer, n)
}
/*
- * Check whether "n" is the maximum negative value. This is
- * -2^(m-1) for an m-bit word, and has no positive equivalent;
- * negating it produces the same value.
+ * Check whether "n" is the maximum negative value. This is -2^(m-1) for
+ * an m-bit word, and has no positive equivalent; negating it produces the
+ * same value.
*/
- if (n == -n) {
+ intVal = -n; /* [Bug 3390638] Workaround for*/
+ if (n == -n || intVal == n) { /* broken compiler optimizers. */
return sprintf(buffer, "%ld", n);
}
@@ -3184,6 +3439,7 @@ TclFormatInt(buffer, n)
for (j = 0; j < i; j++, i--) {
char tmp = buffer[i];
+
buffer[i] = buffer[j];
buffer[j] = tmp;
}
@@ -3289,16 +3545,10 @@ TclGetIntForIndex(
parseError:
if (interp != NULL) {
- /*
- * The result might not be empty; this resets it which should be both
- * a cheap operation, and of little problem because this is an
- * error-generation path anyway.
- */
-
bytes = Tcl_GetString(objPtr);
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad index \"", bytes,
- "\": must be integer?[+-]integer? or end?[+-]integer?", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad index \"%s\": must be integer?[+-]integer? or"
+ " end?[+-]integer?", bytes));
if (!strncmp(bytes, "end-", 4)) {
bytes += 4;
}
@@ -3333,11 +3583,10 @@ static void
UpdateStringOfEndOffset(
register Tcl_Obj *objPtr)
{
- char buffer[TCL_INTEGER_SPACE + sizeof("end") + 1];
- register int len;
+ char buffer[TCL_INTEGER_SPACE + 5];
+ register int len = 3;
- memcpy(buffer, "end", sizeof("end") + 1);
- len = sizeof("end") - 1;
+ memcpy(buffer, "end", 4);
if (objPtr->internalRep.longValue != 0) {
buffer[len++] = '-';
len += TclFormatInt(buffer+len, -(objPtr->internalRep.longValue));
@@ -3390,9 +3639,8 @@ SetEndOffsetFromAny(
if ((*bytes != 'e') || (strncmp(bytes, "end",
(size_t)((length > 3) ? 3 : length)) != 0)) {
if (interp != NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad index \"", bytes,
- "\": must be end?[+-]integer?", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad index \"%s\": must be end?[+-]integer?", bytes));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL);
}
return TCL_ERROR;
@@ -3426,9 +3674,8 @@ SetEndOffsetFromAny(
badIndexFormat:
if (interp != NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad index \"", bytes,
- "\": must be end?[+-]integer?", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad index \"%s\": must be end?[+-]integer?", bytes));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL);
}
return TCL_ERROR;
@@ -3504,8 +3751,8 @@ TclCheckBadOctal(
* be added to an existing error message as extra info.
*/
- Tcl_AppendResult(interp, " (looks like invalid octal number)",
- NULL);
+ Tcl_AppendToObj(Tcl_GetObjResult(interp),
+ " (looks like invalid octal number)", -1);
}
return 1;
}
@@ -3657,7 +3904,7 @@ TclSetProcessGlobalValue(
if (NULL != pgvPtr->value) {
ckfree(pgvPtr->value);
} else {
- Tcl_CreateExitHandler(FreeProcessGlobalValue, (ClientData) pgvPtr);
+ Tcl_CreateExitHandler(FreeProcessGlobalValue, pgvPtr);
}
bytes = Tcl_GetStringFromObj(newValue, &pgvPtr->numBytes);
pgvPtr->value = ckalloc(pgvPtr->numBytes + 1);
@@ -4117,22 +4364,11 @@ TclReToGlob(
*exactPtr = (anchorLeft && anchorRight);
}
-#if 0
- fprintf(stderr, "INPUT RE '%.*s' OUTPUT GLOB '%s' anchor %d:%d \n",
- reStrLen, reStr,
- Tcl_DStringValue(dsPtr), anchorLeft, anchorRight);
- fflush(stderr);
-#endif
return TCL_OK;
invalidGlob:
-#if 0
- fprintf(stderr, "INPUT RE '%.*s' NO OUTPUT GLOB %s (%c)\n",
- reStrLen, reStr, msg, *p);
- fflush(stderr);
-#endif
if (interp != NULL) {
- Tcl_AppendResult(interp, msg, NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1));
Tcl_SetErrorCode(interp, "TCL", "RE2GLOB", code, NULL);
}
Tcl_DStringFree(dsPtr);
diff --git a/generic/tclVar.c b/generic/tclVar.c
index 4df5d43..4694cd8 100644
--- a/generic/tclVar.c
+++ b/generic/tclVar.c
@@ -18,6 +18,7 @@
*/
#include "tclInt.h"
+#include "tclOOInt.h"
/*
* Prototypes for the variable hash key methods.
@@ -46,6 +47,13 @@ static inline void CleanupVar(Var *varPtr, Var *arrayPtr);
#define VarHashGetValue(hPtr) \
((Var *) ((char *)hPtr - TclOffset(VarInHash, entry)))
+/*
+ * NOTE: VarHashCreateVar increments the recount of its key argument.
+ * All callers that will call Tcl_DecrRefCount on that argument must
+ * call Tcl_IncrRefCount on it before passing it in. This requirement
+ * can bubble up to callers of callers .... etc.
+ */
+
static inline Var *
VarHashCreateVar(
TclVarHashTable *tablePtr,
@@ -136,6 +144,30 @@ static const char *isArrayElement =
#define HasLocalVars(framePtr) ((framePtr)->isProcCallFrame & FRAME_IS_PROC)
/*
+ * The following structure describes an enumerative search in progress on an
+ * array variable; this are invoked with options to the "array" command.
+ */
+
+typedef struct ArraySearch {
+ int id; /* Integer id used to distinguish among
+ * multiple concurrent searches for the same
+ * array. */
+ struct Var *varPtr; /* Pointer to array variable that's being
+ * searched. */
+ Tcl_HashSearch search; /* Info kept by the hash module about progress
+ * through the array. */
+ Tcl_HashEntry *nextEntry; /* Non-null means this is the next element to
+ * be enumerated (it's leftover from the
+ * Tcl_FirstHashEntry call or from an "array
+ * anymore" command). NULL means must call
+ * Tcl_NextHashEntry to get value to
+ * return. */
+ struct ArraySearch *nextPtr;/* Next in list of all active searches for
+ * this variable, or NULL if this is the last
+ * one. */
+} ArraySearch;
+
+/*
* Forward references to functions defined later in this file:
*/
@@ -382,11 +414,12 @@ TclLookupVar(
* address of array variable. Otherwise this
* is set to NULL. */
{
- Tcl_Obj *part1Ptr;
Var *varPtr;
+ Tcl_Obj *part1Ptr = Tcl_NewStringObj(part1, -1);
- part1Ptr = Tcl_NewStringObj(part1, -1);
- Tcl_IncrRefCount(part1Ptr);
+ if (createPart1) {
+ Tcl_IncrRefCount(part1Ptr);
+ }
varPtr = TclObjLookupVar(interp, part1Ptr, part2, flags, msg,
createPart1, createPart2, arrayPtrPtr);
@@ -431,6 +464,8 @@ TclLookupVar(
* are 1. The object part1Ptr is converted to one of localVarNameType,
* tclNsVarNameType or tclParsedVarNameType and caches as much of the
* lookup as it can.
+ * When createPart1 is 1, callers must IncrRefCount part1Ptr if they
+ * plan to DecrRefCount it.
*
*----------------------------------------------------------------------
*/
@@ -459,14 +494,14 @@ TclObjLookupVar(
* address of array variable. Otherwise this
* is set to NULL. */
{
- Tcl_Obj *part2Ptr;
+ Tcl_Obj *part2Ptr = NULL;
Var *resPtr;
if (part2) {
part2Ptr = Tcl_NewStringObj(part2, -1);
- Tcl_IncrRefCount(part2Ptr);
- } else {
- part2Ptr = NULL;
+ if (createPart2) {
+ Tcl_IncrRefCount(part2Ptr);
+ }
}
resPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr,
@@ -479,6 +514,12 @@ TclObjLookupVar(
return resPtr;
}
+/*
+ * When createPart1 is 1, callers must IncrRefCount part1Ptr if they
+ * plan to DecrRefCount it.
+ * When createPart2 is 1, callers must IncrRefCount part2Ptr if they
+ * plan to DecrRefCount it.
+ */
Var *
TclObjLookupVarEx(
Tcl_Interp *interp, /* Interpreter to use for lookup. */
@@ -619,7 +660,9 @@ TclObjLookupVarEx(
part2 = newPart2 = part1Ptr->internalRep.twoPtrValue.ptr2;
if (newPart2) {
part2Ptr = Tcl_NewStringObj(newPart2, -1);
- Tcl_IncrRefCount(part2Ptr);
+ if (createPart2) {
+ Tcl_IncrRefCount(part2Ptr);
+ }
}
part1Ptr = part1Ptr->internalRep.twoPtrValue.ptr1;
typePtr = part1Ptr->typePtr;
@@ -665,7 +708,9 @@ TclObjLookupVarEx(
*(newPart2+len2) = '\0';
part2 = newPart2;
part2Ptr = Tcl_NewStringObj(newPart2, -1);
- Tcl_IncrRefCount(part2Ptr);
+ if (createPart2) {
+ Tcl_IncrRefCount(part2Ptr);
+ }
/*
* Free the internal rep of the original part1Ptr, now renamed
@@ -762,7 +807,7 @@ TclObjLookupVarEx(
}
donePart1:
-#if 0
+#if 0 /* ENABLE_NS_VARNAME_CACHING perhaps? */
if (varPtr == NULL) {
if (flags & TCL_LEAVE_ERR_MSG) {
part1 = TclGetString(part1Ptr);
@@ -846,6 +891,7 @@ TclObjLookupVarEx(
*
* Side effects:
* A new hashtable entry may be created if create is 1.
+ * Callers must Incr varNamePtr if they plan to Decr it if create is 1.
*
*----------------------------------------------------------------------
*/
@@ -1074,6 +1120,8 @@ TclLookupSimpleVar(
* The variable at arrayPtr may be converted to be an array if
* createPart1 is 1. A new hashtable entry may be created if createPart2
* is 1.
+ * When createElem is 1, callers must incr elNamePtr if they plan
+ * to decr it.
*
*----------------------------------------------------------------------
*/
@@ -1199,6 +1247,7 @@ TclLookupArrayElement(
*----------------------------------------------------------------------
*/
+#undef Tcl_GetVar
const char *
Tcl_GetVar(
Tcl_Interp *interp, /* Command interpreter in which varName is to
@@ -1208,11 +1257,9 @@ Tcl_GetVar(
* TCL_NAMESPACE_ONLY or TCL_LEAVE_ERR_MSG
* bits. */
{
- Tcl_Obj *varNamePtr, *resultPtr;
+ Tcl_Obj *varNamePtr = Tcl_NewStringObj(varName, -1);
+ Tcl_Obj *resultPtr = Tcl_ObjGetVar2(interp, varNamePtr, NULL, flags);
- varNamePtr = Tcl_NewStringObj(varName, -1);
- Tcl_IncrRefCount(varNamePtr);
- resultPtr = Tcl_ObjGetVar2(interp, varNamePtr, NULL, flags);
TclDecrRefCount(varNamePtr);
if (resultPtr == NULL) {
@@ -1256,15 +1303,12 @@ Tcl_GetVar2(
* TCL_NAMESPACE_ONLY and TCL_LEAVE_ERR_MSG *
* bits. */
{
- Tcl_Obj *resultPtr, *part1Ptr, *part2Ptr;
+ Tcl_Obj *resultPtr;
+ Tcl_Obj *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1);
- part1Ptr = Tcl_NewStringObj(part1, -1);
- Tcl_IncrRefCount(part1Ptr);
if (part2) {
part2Ptr = Tcl_NewStringObj(part2, -1);
Tcl_IncrRefCount(part2Ptr);
- } else {
- part2Ptr = NULL;
}
resultPtr = Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags);
@@ -1313,15 +1357,11 @@ Tcl_GetVar2Ex(
int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and
* TCL_LEAVE_ERR_MSG bits. */
{
- Tcl_Obj *part1Ptr, *part2Ptr, *resPtr;
+ Tcl_Obj *resPtr, *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1);
- part1Ptr = Tcl_NewStringObj(part1, -1);
- Tcl_IncrRefCount(part1Ptr);
if (part2) {
part2Ptr = Tcl_NewStringObj(part2, -1);
Tcl_IncrRefCount(part2Ptr);
- } else {
- part2Ptr = NULL;
}
resPtr = Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags);
@@ -1354,6 +1394,8 @@ Tcl_GetVar2Ex(
* the returned reference; if you want to keep a reference to the object
* you must increment its ref count yourself.
*
+ * Callers must incr part2Ptr if they plan to decr it.
+ *
*----------------------------------------------------------------------
*/
@@ -1548,6 +1590,7 @@ Tcl_SetObjCmd(
*----------------------------------------------------------------------
*/
+#undef Tcl_SetVar
const char *
Tcl_SetVar(
Tcl_Interp *interp, /* Command interpreter in which varName is to
@@ -1559,17 +1602,13 @@ Tcl_SetVar(
* TCL_APPEND_VALUE, TCL_LIST_ELEMENT,
* TCL_LEAVE_ERR_MSG. */
{
- Tcl_Obj *valuePtr, *varNamePtr, *varValuePtr;
+ Tcl_Obj *varValuePtr, *varNamePtr = Tcl_NewStringObj(varName, -1);
- varNamePtr = Tcl_NewStringObj(varName, -1);
Tcl_IncrRefCount(varNamePtr);
- valuePtr = Tcl_NewStringObj(newValue, -1);
- Tcl_IncrRefCount(valuePtr);
-
- varValuePtr = Tcl_ObjSetVar2(interp, varNamePtr, NULL, valuePtr, flags);
-
+ varValuePtr = Tcl_ObjSetVar2(interp, varNamePtr, NULL,
+ Tcl_NewStringObj(newValue, -1), flags);
Tcl_DecrRefCount(varNamePtr);
- Tcl_DecrRefCount(valuePtr);
+
if (varValuePtr == NULL) {
return NULL;
}
@@ -1617,27 +1656,9 @@ Tcl_SetVar2(
* TCL_APPEND_VALUE, TCL_LIST_ELEMENT, or
* TCL_LEAVE_ERR_MSG. */
{
- Tcl_Obj *valuePtr, *part1Ptr, *part2Ptr;
- Tcl_Obj *varValuePtr;
-
- part1Ptr = Tcl_NewStringObj(part1, -1);
- Tcl_IncrRefCount(part1Ptr);
- if (part2 != NULL) {
- part2Ptr = Tcl_NewStringObj(part2, -1);
- Tcl_IncrRefCount(part2Ptr);
- } else {
- part2Ptr = NULL;
- }
- valuePtr = Tcl_NewStringObj(newValue, -1);
- Tcl_IncrRefCount(valuePtr);
+ Tcl_Obj *varValuePtr = Tcl_SetVar2Ex(interp, part1, part2,
+ Tcl_NewStringObj(newValue, -1), flags);
- varValuePtr = Tcl_ObjSetVar2(interp, part1Ptr, part2Ptr, valuePtr, flags);
-
- Tcl_DecrRefCount(part1Ptr);
- if (part2Ptr != NULL) {
- Tcl_DecrRefCount(part2Ptr);
- }
- Tcl_DecrRefCount(valuePtr);
if (varValuePtr == NULL) {
return NULL;
}
@@ -1696,15 +1717,12 @@ Tcl_SetVar2Ex(
* TCL_APPEND_VALUE, TCL_LIST_ELEMENT or
* TCL_LEAVE_ERR_MSG. */
{
- Tcl_Obj *part1Ptr, *part2Ptr, *resPtr;
+ Tcl_Obj *resPtr, *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1);
- part1Ptr = Tcl_NewStringObj(part1, -1);
Tcl_IncrRefCount(part1Ptr);
if (part2) {
part2Ptr = Tcl_NewStringObj(part2, -1);
Tcl_IncrRefCount(part2Ptr);
- } else {
- part2Ptr = NULL;
}
resPtr = Tcl_ObjSetVar2(interp, part1Ptr, part2Ptr, newValuePtr, flags);
@@ -1737,6 +1755,8 @@ Tcl_SetVar2Ex(
* Side effects:
* The value of the given variable is set. If either the array or the
* entry didn't exist then a new variable is created.
+ * Callers must Incr part1Ptr if they plan to Decr it.
+ * Callers must Incr part2Ptr if they plan to Decr it.
*
*----------------------------------------------------------------------
*/
@@ -1892,7 +1912,7 @@ TclPtrSetVar(
varPtr->value.objPtr = NULL;
}
if (flags & (TCL_APPEND_VALUE|TCL_LIST_ELEMENT)) {
-#if 0
+#if 0 /* ENABLE_NS_VARNAME_CACHING perhaps? */
/*
* Can't happen now!
*/
@@ -2026,6 +2046,8 @@ TclPtrSetVar(
* variable is created. The ref count for the returned object is _not_
* incremented to reflect the returned reference; if you want to keep a
* reference to the object you must increment its ref count yourself.
+ * Callers must Incr part1Ptr if they plan to Decr it.
+ * Callers must Incr part2Ptr if they plan to Decr it.
*
*----------------------------------------------------------------------
*/
@@ -2051,8 +2073,8 @@ TclIncrObjVar2(
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, "read",
1, 1, &arrayPtr);
if (varPtr == NULL) {
- Tcl_AddObjErrorInfo(interp,
- "\n (reading value of variable to increment)", -1);
+ Tcl_AddErrorInfo(interp,
+ "\n (reading value of variable to increment)");
return NULL;
}
return TclPtrIncrObjVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
@@ -2108,8 +2130,7 @@ TclPtrIncrObjVar(
* variable, or -1. Only used when part1Ptr is
* NULL. */
{
- register Tcl_Obj *varValuePtr, *newValuePtr = NULL;
- int duplicated, code;
+ register Tcl_Obj *varValuePtr;
if (TclIsVarInHash(varPtr)) {
VarHashRefCount(varPtr)++;
@@ -2123,19 +2144,33 @@ TclPtrIncrObjVar(
varValuePtr = Tcl_NewIntObj(0);
}
if (Tcl_IsShared(varValuePtr)) {
- duplicated = 1;
+ /* Copy on write */
varValuePtr = Tcl_DuplicateObj(varValuePtr);
+
+ if (TCL_OK == TclIncrObj(interp, varValuePtr, incrPtr)) {
+ return TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
+ varValuePtr, flags, index);
+ } else {
+ Tcl_DecrRefCount(varValuePtr);
+ return NULL;
+ }
} else {
- duplicated = 0;
- }
- code = TclIncrObj(interp, varValuePtr, incrPtr);
- if (code == TCL_OK) {
- newValuePtr = TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr,
- part2Ptr, varValuePtr, flags, index);
- } else if (duplicated) {
- Tcl_DecrRefCount(varValuePtr);
+ /* Unshared - can Incr in place */
+ if (TCL_OK == TclIncrObj(interp, varValuePtr, incrPtr)) {
+
+ /*
+ * This seems dumb to write the incremeted value into the var
+ * after we just adjusted the value in place, but the spec for
+ * [incr] requires that write traces fire, and making this call
+ * is the way to make that happen.
+ */
+
+ return TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
+ varValuePtr, flags, index);
+ } else {
+ return NULL;
+ }
}
- return newValuePtr;
}
/*
@@ -2158,6 +2193,7 @@ TclPtrIncrObjVar(
*----------------------------------------------------------------------
*/
+#undef Tcl_UnsetVar
int
Tcl_UnsetVar(
Tcl_Interp *interp, /* Command interpreter in which varName is to
@@ -2218,13 +2254,10 @@ Tcl_UnsetVar2(
* TCL_LEAVE_ERR_MSG. */
{
int result;
- Tcl_Obj *part1Ptr, *part2Ptr = NULL;
+ Tcl_Obj *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1);
- part1Ptr = Tcl_NewStringObj(part1, -1);
- Tcl_IncrRefCount(part1Ptr);
if (part2) {
part2Ptr = Tcl_NewStringObj(part2, -1);
- Tcl_IncrRefCount(part2Ptr);
}
/*
@@ -2840,6 +2873,7 @@ Tcl_LappendObjCmd(
*
* Side effects:
* A variable will be created if one does not already exist.
+ * Callers must Incr arrayNameObj if they pland to Decr it.
*
*----------------------------------------------------------------------
*/
@@ -3064,7 +3098,8 @@ ArrayStartSearchCmd(
if ((varPtr == NULL) || !TclIsVarArray(varPtr)
|| TclIsVarUndefined(varPtr)) {
- Tcl_AppendResult(interp, "\"", varName, "\" isn't an array", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" isn't an array", varName));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY", varName, NULL);
return TCL_ERROR;
}
@@ -3159,8 +3194,8 @@ ArrayAnyMoreCmd(
if ((varPtr == NULL) || !TclIsVarArray(varPtr)
|| TclIsVarUndefined(varPtr)) {
- Tcl_AppendResult(interp, "\"", TclGetString(varNameObj),
- "\" isn't an array", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" isn't an array", TclGetString(varNameObj)));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
TclGetString(varNameObj), NULL);
return TCL_ERROR;
@@ -3265,8 +3300,8 @@ ArrayNextElementCmd(
if ((varPtr == NULL) || !TclIsVarArray(varPtr)
|| TclIsVarUndefined(varPtr)) {
- Tcl_AppendResult(interp, "\"", TclGetString(varNameObj),
- "\" isn't an array", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" isn't an array", TclGetString(varNameObj)));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
TclGetString(varNameObj), NULL);
return TCL_ERROR;
@@ -3375,8 +3410,8 @@ ArrayDoneSearchCmd(
if ((varPtr == NULL) || !TclIsVarArray(varPtr)
|| TclIsVarUndefined(varPtr)) {
- Tcl_AppendResult(interp, "\"", TclGetString(varNameObj),
- "\" isn't an array", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" isn't an array", TclGetString(varNameObj)));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
TclGetString(varNameObj), NULL);
return TCL_ERROR;
@@ -3815,6 +3850,53 @@ ArrayNamesCmd(
/*
*----------------------------------------------------------------------
*
+ * TclFindArrayPtrElements --
+ *
+ * Fill out a hash table (which *must* use Tcl_Obj* keys) with an entry
+ * for each existing element of the given array. The provided hash table
+ * is assumed to be initially empty.
+ *
+ * Result:
+ * none
+ *
+ * Side effects:
+ * The keys of the array gain an extra reference. The supplied hash table
+ * has elements added to it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFindArrayPtrElements(
+ Var *arrayPtr,
+ Tcl_HashTable *tablePtr)
+{
+ Var *varPtr;
+ Tcl_HashSearch search;
+
+ if ((arrayPtr == NULL) || !TclIsVarArray(arrayPtr)
+ || TclIsVarUndefined(arrayPtr)) {
+ return;
+ }
+
+ for (varPtr=VarHashFirstVar(arrayPtr->value.tablePtr, &search);
+ varPtr!=NULL ; varPtr=VarHashNextVar(&search)) {
+ Tcl_HashEntry *hPtr;
+ Tcl_Obj *nameObj;
+ int dummy;
+
+ if (TclIsVarUndefined(varPtr)) {
+ continue;
+ }
+ nameObj = VarHashGetKey(varPtr);
+ hPtr = Tcl_CreateHashEntry(tablePtr, (char *) nameObj, &dummy);
+ Tcl_SetHashValue(hPtr, nameObj);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* ArraySetCmd --
*
* This object-based function is invoked to process the "array set" Tcl
@@ -4018,8 +4100,8 @@ ArrayStatsCmd(
if ((varPtr == NULL) || !TclIsVarArray(varPtr)
|| TclIsVarUndefined(varPtr)) {
- Tcl_AppendResult(interp, "\"", TclGetString(varNameObj),
- "\" isn't an array", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "\"%s\" isn't an array", TclGetString(varNameObj)));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
TclGetString(varNameObj), NULL);
return TCL_ERROR;
@@ -4027,7 +4109,8 @@ ArrayStatsCmd(
stats = Tcl_HashStats((Tcl_HashTable *) varPtr->value.tablePtr);
if (stats == NULL) {
- Tcl_SetResult(interp, "error reading array statistics", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "error reading array statistics", -1));
return TCL_ERROR;
}
Tcl_SetObjResult(interp, Tcl_NewStringObj(stats, -1));
@@ -4219,17 +4302,17 @@ TclInitArrayCmd(
Tcl_Interp *interp) /* Current interpreter. */
{
static const EnsembleImplMap arrayImplMap[] = {
- {"anymore", ArrayAnyMoreCmd, NULL, NULL, NULL, 0},
- {"donesearch", ArrayDoneSearchCmd, NULL, NULL, NULL, 0},
- {"exists", ArrayExistsCmd, NULL, NULL, NULL, 0},
- {"get", ArrayGetCmd, NULL, NULL, NULL, 0},
- {"names", ArrayNamesCmd, NULL, NULL, NULL, 0},
- {"nextelement", ArrayNextElementCmd, NULL, NULL, NULL, 0},
- {"set", ArraySetCmd, NULL, NULL, NULL, 0},
- {"size", ArraySizeCmd, NULL, NULL, NULL, 0},
- {"startsearch", ArrayStartSearchCmd, NULL, NULL, NULL, 0},
- {"statistics", ArrayStatsCmd, NULL, NULL, NULL, 0},
- {"unset", ArrayUnsetCmd, NULL, NULL, NULL, 0},
+ {"anymore", ArrayAnyMoreCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"donesearch", ArrayDoneSearchCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"exists", ArrayExistsCmd, TclCompileArrayExistsCmd, NULL, NULL, 0},
+ {"get", ArrayGetCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+ {"names", ArrayNamesCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
+ {"nextelement", ArrayNextElementCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+ {"set", ArraySetCmd, TclCompileArraySetCmd, NULL, NULL, 0},
+ {"size", ArraySizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"startsearch", ArrayStartSearchCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"statistics", ArrayStatsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+ {"unset", ArrayUnsetCmd, TclCompileArrayUnsetCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
};
@@ -4252,6 +4335,8 @@ TclInitArrayCmd(
* The variable given by myName is linked to the variable in framePtr
* given by otherP1 and otherP2, so that references to myName are
* redirected to the other variable like a symbolic link.
+ * Callers must Incr myNamePtr if they plan to Decr it.
+ * Callers must Incr otherP1Ptr if they plan to Decr it.
*
*----------------------------------------------------------------------
*/
@@ -4316,10 +4401,10 @@ ObjMakeUpvar(
|| (varFramePtr == NULL)
|| !HasLocalVars(varFramePtr)
|| (strstr(TclGetString(myNamePtr), "::") != NULL))) {
- Tcl_AppendResult((Tcl_Interp *) iPtr, "bad variable name \"",
- TclGetString(myNamePtr), "\": upvar won't create "
+ Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_ObjPrintf(
+ "bad variable name \"%s\": upvar won't create "
"namespace variable that refers to procedure variable",
- NULL);
+ TclGetString(myNamePtr)));
Tcl_SetErrorCode(interp, "TCL", "UPVAR", "INVERTED", NULL);
return TCL_ERROR;
}
@@ -4360,14 +4445,12 @@ TclPtrMakeUpvar(
int index) /* If the variable to be linked is an indexed
* scalar, this is its index. Otherwise, -1 */
{
- Tcl_Obj *myNamePtr;
+ Tcl_Obj *myNamePtr = NULL;
int result;
if (myName) {
myNamePtr = Tcl_NewStringObj(myName, -1);
Tcl_IncrRefCount(myNamePtr);
- } else {
- myNamePtr = NULL;
}
result = TclPtrObjMakeUpvar(interp, otherPtr, myNamePtr, myFlags, index);
if (myNamePtr) {
@@ -4376,6 +4459,8 @@ TclPtrMakeUpvar(
return result;
}
+/* Callers must Incr myNamePtr if they plan to Decr it. */
+
int
TclPtrObjMakeUpvar(
Tcl_Interp *interp, /* Interpreter containing variables. Used for
@@ -4417,9 +4502,10 @@ TclPtrObjMakeUpvar(
* myName looks like an array reference.
*/
- Tcl_AppendResult((Tcl_Interp *) iPtr, "bad variable name \"",
- myName, "\": upvar won't create a scalar variable "
- "that looks like an array element", NULL);
+ Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_ObjPrintf(
+ "bad variable name \"%s\": upvar won't create a"
+ " scalar variable that looks like an array element",
+ myName));
Tcl_SetErrorCode(interp, "TCL", "UPVAR", "LOCAL_ELEMENT",
NULL);
return TCL_ERROR;
@@ -4446,15 +4532,15 @@ TclPtrObjMakeUpvar(
}
if (varPtr == otherPtr) {
- Tcl_SetResult((Tcl_Interp *) iPtr,
- "can't upvar from variable to itself", TCL_STATIC);
+ Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_NewStringObj(
+ "can't upvar from variable to itself", -1));
Tcl_SetErrorCode(interp, "TCL", "UPVAR", "SELF", NULL);
return TCL_ERROR;
}
if (TclIsVarTraced(varPtr)) {
- Tcl_AppendResult((Tcl_Interp *) iPtr, "variable \"", myName,
- "\" has traces: can't use for upvar", NULL);
+ Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_ObjPrintf(
+ "variable \"%s\" has traces: can't use for upvar", myName));
Tcl_SetErrorCode(interp, "TCL", "UPVAR", "TRACED", NULL);
return TCL_ERROR;
} else if (!TclIsVarUndefined(varPtr)) {
@@ -4468,8 +4554,8 @@ TclPtrObjMakeUpvar(
*/
if (!TclIsVarLink(varPtr)) {
- Tcl_AppendResult((Tcl_Interp *) iPtr, "variable \"", myName,
- "\" already exists", NULL);
+ Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_ObjPrintf(
+ "variable \"%s\" already exists", myName));
Tcl_SetErrorCode(interp, "TCL", "UPVAR", "EXISTS", NULL);
return TCL_ERROR;
}
@@ -4514,6 +4600,7 @@ TclPtrObjMakeUpvar(
*----------------------------------------------------------------------
*/
+#undef Tcl_UpVar
int
Tcl_UpVar(
Tcl_Interp *interp, /* Command interpreter in which varName is to
@@ -4967,8 +5054,8 @@ Tcl_UpvarObjCmd(
* for this particular case.
*/
- Tcl_AppendResult(interp, "bad level \"", TclGetString(levelObj), "\"",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad level \"%s\"", TclGetString(levelObj)));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "LEVEL", NULL);
return TCL_ERROR;
}
@@ -4977,8 +5064,8 @@ Tcl_UpvarObjCmd(
* We've now finished with parsing levels; skip to the variable names.
*/
- objc -= hasLevel+1;
- objv += hasLevel+1;
+ objc -= hasLevel + 1;
+ objv += hasLevel + 1;
/*
* Iterate over each (other variable, local variable) pair. Divide the
@@ -5059,8 +5146,8 @@ SetArraySearchObj(
return TCL_OK;
syntax:
- Tcl_AppendResult(interp, "illegal search identifier \"", string, "\"",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "illegal search identifier \"%s\"", string));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAYSEARCH", string, NULL);
return TCL_ERROR;
}
@@ -5107,7 +5194,8 @@ ParseSearchId(
* Parse the id.
*/
- if (Tcl_ConvertToType(interp, handleObj, &tclArraySearchType) != TCL_OK) {
+ if ((handleObj->typePtr != &tclArraySearchType)
+ && (SetArraySearchObj(interp, handleObj) != TCL_OK)) {
return NULL;
}
@@ -5125,10 +5213,9 @@ ParseSearchId(
*/
if (strcmp(string+offset, varName) != 0) {
- Tcl_AppendResult(interp, "search identifier \"", string,
- "\" isn't for variable \"", varName, "\"", NULL);
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAYSEARCH", string,
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "search identifier \"%s\" isn't for variable \"%s\"",
+ string, varName));
goto badLookup;
}
@@ -5152,7 +5239,8 @@ ParseSearchId(
}
}
}
- Tcl_AppendResult(interp, "couldn't find search \"", string, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't find search \"%s\"", string));
badLookup:
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAYSEARCH", string, NULL);
return NULL;
@@ -5238,8 +5326,6 @@ TclDeleteNamespaceVars(
for (varPtr = VarHashFirstVar(tablePtr, &search); varPtr != NULL;
varPtr = VarHashFirstVar(tablePtr, &search)) {
Tcl_Obj *objPtr = Tcl_NewObj();
-
- Tcl_IncrRefCount(objPtr);
VarHashRefCount(varPtr)++; /* Make sure we get to remove from
* hash. */
Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr, objPtr);
@@ -5503,15 +5589,10 @@ TclVarErrMsg(
* e.g. "read", "set", or "unset". */
const char *reason) /* String describing why operation failed. */
{
- Tcl_Obj *part1Ptr = NULL, *part2Ptr = NULL;
+ Tcl_Obj *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1);
- part1Ptr = Tcl_NewStringObj(part1, -1);
- Tcl_IncrRefCount(part1Ptr);
if (part2) {
part2Ptr = Tcl_NewStringObj(part2, -1);
- Tcl_IncrRefCount(part2Ptr);
- } else {
- part2 = NULL;
}
TclObjVarErrMsg(interp, part1Ptr, part2Ptr, operation, reason, -1);
@@ -5784,7 +5865,6 @@ Tcl_FindNamespaceVar(
Tcl_Obj *namePtr = Tcl_NewStringObj(name, -1);
Tcl_Var var;
- Tcl_IncrRefCount(namePtr);
var = ObjFindNamespaceVar(interp, namePtr, contextNsPtr, flags);
Tcl_DecrRefCount(namePtr);
return var;
@@ -5879,7 +5959,6 @@ ObjFindNamespaceVar(
varPtr = NULL;
if (simpleName != name) {
simpleNamePtr = Tcl_NewStringObj(simpleName, -1);
- Tcl_IncrRefCount(simpleNamePtr);
} else {
simpleNamePtr = namePtr;
}
@@ -5893,8 +5972,8 @@ ObjFindNamespaceVar(
Tcl_DecrRefCount(simpleNamePtr);
}
if ((varPtr == NULL) && (flags & TCL_LEAVE_ERR_MSG)) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "unknown variable \"", name, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown variable \"%s\"", name));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", name, NULL);
}
return (Tcl_Var) varPtr;
@@ -6083,7 +6162,7 @@ TclInfoVarsCmd(
}
}
}
- } else if (((Interp *)interp)->varFramePtr->procPtr != NULL) {
+ } else if (iPtr->varFramePtr->procPtr != NULL) {
AppendLocals(interp, listPtr, simplePatternPtr, 1);
}
@@ -6269,17 +6348,21 @@ AppendLocals(
{
Interp *iPtr = (Interp *) interp;
Var *varPtr;
- int i, localVarCt;
+ int i, localVarCt, added;
Tcl_Obj **varNamePtr, *objNamePtr;
const char *varName;
TclVarHashTable *localVarTablePtr;
Tcl_HashSearch search;
+ Tcl_HashTable addedTable;
const char *pattern = patternPtr? TclGetString(patternPtr) : NULL;
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++) {
/*
@@ -6291,6 +6374,9 @@ AppendLocals(
varName = TclGetString(*varNamePtr);
if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
Tcl_ListObjAppendElement(interp, listPtr, *varNamePtr);
+ if (includeLinks) {
+ Tcl_CreateHashEntry(&addedTable, *varNamePtr, &added);
+ }
}
}
varPtr++;
@@ -6301,7 +6387,7 @@ AppendLocals(
*/
if (localVarTablePtr == NULL) {
- return;
+ goto objectVars;
}
/*
@@ -6315,9 +6401,13 @@ AppendLocals(
&& (includeLinks || !TclIsVarLink(varPtr))) {
Tcl_ListObjAppendElement(interp, listPtr,
VarHashGetKey(varPtr));
+ if (includeLinks) {
+ Tcl_CreateHashEntry(&addedTable, VarHashGetKey(varPtr),
+ &added);
+ }
}
}
- return;
+ goto objectVars;
}
/*
@@ -6333,9 +6423,41 @@ AppendLocals(
varName = TclGetString(objNamePtr);
if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
Tcl_ListObjAppendElement(interp, listPtr, objNamePtr);
+ if (includeLinks) {
+ Tcl_CreateHashEntry(&addedTable, objNamePtr, &added);
+ }
+ }
+ }
+ }
+
+ objectVars:
+ if (!includeLinks) {
+ return;
+ }
+
+ if (iPtr->varFramePtr->isProcCallFrame & FRAME_IS_METHOD) {
+ CallContext *contextPtr = iPtr->varFramePtr->clientData;
+ Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr;
+
+ if (mPtr->declaringObjectPtr) {
+ FOREACH(objNamePtr, mPtr->declaringObjectPtr->variables) {
+ Tcl_CreateHashEntry(&addedTable, objNamePtr, &added);
+ if (added && (!pattern ||
+ Tcl_StringMatch(TclGetString(objNamePtr), pattern))) {
+ Tcl_ListObjAppendElement(interp, listPtr, objNamePtr);
+ }
+ }
+ } else {
+ FOREACH(objNamePtr, mPtr->declaringClassPtr->variables) {
+ Tcl_CreateHashEntry(&addedTable, objNamePtr, &added);
+ if (added && (!pattern ||
+ Tcl_StringMatch(TclGetString(objNamePtr), pattern))) {
+ Tcl_ListObjAppendElement(interp, listPtr, objNamePtr);
+ }
}
}
}
+ Tcl_DeleteHashTable(&addedTable);
}
/*
diff --git a/generic/tclZlib.c b/generic/tclZlib.c
index 81012dc..9bceb4c 100644
--- a/generic/tclZlib.c
+++ b/generic/tclZlib.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2004-2005 Pascal Scheffers <pascal@scheffers.net>
* Copyright (C) 2005 Unitas Software B.V.
- * Copyright (c) 2008-2009 Donal K. Fellows
+ * Copyright (c) 2008-2012 Donal K. Fellows
*
* Parts written by Jean-Claude Wippler, as part of Tclkit, placed in the
* public domain March 2003.
@@ -17,6 +17,16 @@
#include "tclInt.h"
#ifdef HAVE_ZLIB
#include <zlib.h>
+#include "tclIO.h"
+
+/*
+ * The version of the zlib "package" that this implements. Note that this
+ * thoroughly supersedes the versions included with tclkit, which are "1.1",
+ * so this is at least "2.0" (there's no general *commitment* to have the same
+ * interface, even if that is mostly true).
+ */
+
+#define TCL_ZLIB_VERSION "2.0"
/*
* Magic flags used with wbits fields to indicate that we're handling the gzip
@@ -64,8 +74,27 @@ typedef struct {
int wbits; /* The encoded compression mode, so we can
* restart the stream if necessary. */
Tcl_Command cmd; /* Token for the associated Tcl command. */
+ Tcl_Obj *compDictObj; /* Byte-array object containing compression
+ * dictionary (not dictObj!) to use if
+ * necessary. */
+ int flags; /* Miscellaneous flag bits. */
+ GzipHeader *gzHeaderPtr; /* If we've allocated a gzip header
+ * structure. */
} ZlibStreamHandle;
+#define DICT_TO_SET 0x1 /* If we need to set a compression dictionary
+ * in the low-level engine at the next
+ * opportunity. */
+
+/*
+ * Macros to make it clearer in some of the twiddlier accesses what is
+ * happening.
+ */
+
+#define IsRawStream(zshPtr) ((zshPtr)->format == TCL_ZLIB_FORMAT_RAW)
+#define HaveDictToSet(zshPtr) ((zshPtr)->flags & DICT_TO_SET)
+#define DictWasSet(zshPtr) ((zshPtr)->flags |= ~DICT_TO_SET)
+
/*
* Structure used for stacked channel compression and decompression.
*/
@@ -78,6 +107,11 @@ typedef struct {
* for compression on output, or
* TCL_ZLIB_STREAM_INFLATE for decompression
* on input. */
+ int format; /* What format of data is going on the wire.
+ * Needed so that the correct [fconfigure]
+ * options can be enabled. */
+ int readAheadLimit; /* The maximum number of bytes to read from
+ * the underlying stream in one go. */
z_stream inStream; /* Structure used by zlib for decompression of
* input. */
z_stream outStream; /* Structure used by zlib for compression of
@@ -90,6 +124,10 @@ typedef struct {
GzipHeader outHeader; /* Header to write to an output stream, when
* compressing a gzip stream. */
Tcl_TimerToken timer; /* Timer used for keeping events fresh. */
+ Tcl_DString decompressed; /* Buffer for decompression results. */
+ Tcl_Obj *compDictObj; /* Byte-array object containing compression
+ * dictionary (not dictObj!) to use if
+ * necessary. */
} ZlibChannelData;
/*
@@ -106,17 +144,15 @@ typedef struct {
#define OUT_HEADER 0x4
/*
- * Size of buffers allocated by default. Should be enough...
+ * Size of buffers allocated by default, and the range it can be set to. The
+ * same sorts of values apply to streams, except with different limits (they
+ * permit byte-level activity). Channels always use bytes unless told to use
+ * larger buffers.
*/
#define DEFAULT_BUFFER_SIZE 4096
-
-/*
- * Time to wait (in milliseconds) before flushing the channel when reading
- * data through the transform.
- */
-
-#define TRANSFORM_FLUSH_DELAY 5
+#define MIN_NONSTREAM_BUFFER_SIZE 16
+#define MAX_BUFFER_SIZE 65536
/*
* Prototypes for private procedures defined later in this file:
@@ -127,25 +163,38 @@ static Tcl_DriverBlockModeProc ZlibTransformBlockMode;
static Tcl_DriverCloseProc ZlibTransformClose;
static Tcl_DriverGetHandleProc ZlibTransformGetHandle;
static Tcl_DriverGetOptionProc ZlibTransformGetOption;
-static Tcl_DriverHandlerProc ZlibTransformHandler;
+static Tcl_DriverHandlerProc ZlibTransformEventHandler;
static Tcl_DriverInputProc ZlibTransformInput;
static Tcl_DriverOutputProc ZlibTransformOutput;
static Tcl_DriverSetOptionProc ZlibTransformSetOption;
static Tcl_DriverWatchProc ZlibTransformWatch;
static Tcl_ObjCmdProc ZlibCmd;
static Tcl_ObjCmdProc ZlibStreamCmd;
+static Tcl_ObjCmdProc ZlibStreamAddCmd;
+static Tcl_ObjCmdProc ZlibStreamHeaderCmd;
+static Tcl_ObjCmdProc ZlibStreamPutCmd;
-static void ConvertError(Tcl_Interp *interp, int code);
+static void ConvertError(Tcl_Interp *interp, int code,
+ uLong adler);
+static Tcl_Obj * ConvertErrorToList(int code, uLong adler);
static void ExtractHeader(gz_header *headerPtr, Tcl_Obj *dictObj);
static int GenerateHeader(Tcl_Interp *interp, Tcl_Obj *dictObj,
GzipHeader *headerPtr, int *extraSizePtr);
+static int ZlibPushSubcmd(Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+static inline int ResultCopy(ZlibChannelData *cd, char *buf,
+ int toRead);
+static int ResultGenerate(ZlibChannelData *cd, int n, int flush,
+ int *errorCodePtr);
static Tcl_Channel ZlibStackChannelTransform(Tcl_Interp *interp,
- int mode, int format, int level,
- Tcl_Channel channel, Tcl_Obj *gzipHeaderDictPtr);
+ int mode, int format, int level, int limit,
+ Tcl_Channel channel, Tcl_Obj *gzipHeaderDictPtr,
+ Tcl_Obj *compDictObj);
static void ZlibStreamCleanup(ZlibStreamHandle *zshPtr);
-static void ZlibTransformTimerKill(ZlibChannelData *cd);
+static int ZlibStreamSubcmd(Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+static inline void ZlibTransformEventTimerKill(ZlibChannelData *cd);
static void ZlibTransformTimerRun(ClientData clientData);
-static void ZlibTransformTimerSetup(ZlibChannelData *cd);
/*
* Type of zlib-based compressing and decompressing channels.
@@ -165,7 +214,7 @@ static const Tcl_ChannelType zlibChannelType = {
NULL, /* close2Proc */
ZlibTransformBlockMode,
NULL, /* flushProc */
- ZlibTransformHandler,
+ ZlibTransformEventHandler,
NULL, /* wideSeekProc */
NULL,
NULL
@@ -191,38 +240,139 @@ static void
ConvertError(
Tcl_Interp *interp, /* Interpreter to store the error in. May be
* NULL, in which case nothing happens. */
- int code) /* The zlib error code. */
+ int code, /* The zlib error code. */
+ uLong adler) /* The checksum expected (for Z_NEED_DICT) */
{
+ const char *codeStr, *codeStr2 = NULL;
+ char codeStrBuf[TCL_INTEGER_SPACE];
+
if (interp == NULL) {
return;
}
- if (code == Z_ERRNO) {
+ switch (code) {
+ /*
+ * Firstly, the case that is *different* because it's really coming
+ * from the OS and is just being reported via zlib. It should be
+ * really uncommon because Tcl handles all I/O rather than delegating
+ * it to zlib, but proving it can't happen is hard.
+ */
+
+ case Z_ERRNO:
Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_PosixError(interp),-1));
- } else {
- const char *codeStr, *codeStr2 = NULL;
- char codeStrBuf[TCL_INTEGER_SPACE];
-
- switch (code) {
- case Z_STREAM_ERROR: codeStr = "STREAM"; break;
- case Z_DATA_ERROR: codeStr = "DATA"; break;
- case Z_MEM_ERROR: codeStr = "MEM"; break;
- case Z_BUF_ERROR: codeStr = "BUF"; break;
- case Z_VERSION_ERROR: codeStr = "VERSION"; break;
- default:
- codeStr = "unknown";
- codeStr2 = codeStrBuf;
- sprintf(codeStrBuf, "%d", code);
- break;
- }
- Tcl_SetObjResult(interp, Tcl_NewStringObj(zError(code), -1));
+ return;
+
+ /*
+ * Normal errors/conditions, some of which have additional detail and
+ * some which don't. (This is not defined by array lookup because zlib
+ * error codes are sometimes negative.)
+ */
+
+ case Z_STREAM_ERROR:
+ codeStr = "STREAM";
+ break;
+ case Z_DATA_ERROR:
+ codeStr = "DATA";
+ break;
+ case Z_MEM_ERROR:
+ codeStr = "MEM";
+ break;
+ case Z_BUF_ERROR:
+ codeStr = "BUF";
+ break;
+ case Z_VERSION_ERROR:
+ codeStr = "VERSION";
+ break;
+ case Z_NEED_DICT:
+ codeStr = "NEED_DICT";
+ codeStr2 = codeStrBuf;
+ sprintf(codeStrBuf, "%lu", adler);
+ break;
+
+ /*
+ * These should _not_ happen! This function is for dealing with error
+ * cases, not non-errors!
+ */
+
+ case Z_OK:
+ Tcl_Panic("unexpected zlib result in error handler: Z_OK");
+ case Z_STREAM_END:
+ Tcl_Panic("unexpected zlib result in error handler: Z_STREAM_END");
/*
- * Tricky point! We might pass NULL twice here (and will when the
- * error type is known).
+ * Anything else is bad news; it's unexpected. Convert to generic
+ * error.
*/
- Tcl_SetErrorCode(interp, "TCL", "ZLIB", codeStr, codeStr2, NULL);
+ default:
+ codeStr = "UNKNOWN";
+ codeStr2 = codeStrBuf;
+ sprintf(codeStrBuf, "%d", code);
+ break;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(zError(code), -1));
+
+ /*
+ * Tricky point! We might pass NULL twice here (and will when the error
+ * type is known).
+ */
+
+ Tcl_SetErrorCode(interp, "TCL", "ZLIB", codeStr, codeStr2, NULL);
+}
+
+static Tcl_Obj *
+ConvertErrorToList(
+ int code, /* The zlib error code. */
+ uLong adler) /* The checksum expected (for Z_NEED_DICT) */
+{
+ Tcl_Obj *objv[4];
+
+ TclNewLiteralStringObj(objv[0], "TCL");
+ TclNewLiteralStringObj(objv[1], "ZLIB");
+ switch (code) {
+ case Z_STREAM_ERROR:
+ TclNewLiteralStringObj(objv[2], "STREAM");
+ return Tcl_NewListObj(3, objv);
+ case Z_DATA_ERROR:
+ TclNewLiteralStringObj(objv[2], "DATA");
+ return Tcl_NewListObj(3, objv);
+ case Z_MEM_ERROR:
+ TclNewLiteralStringObj(objv[2], "MEM");
+ return Tcl_NewListObj(3, objv);
+ case Z_BUF_ERROR:
+ TclNewLiteralStringObj(objv[2], "BUF");
+ return Tcl_NewListObj(3, objv);
+ case Z_VERSION_ERROR:
+ TclNewLiteralStringObj(objv[2], "VERSION");
+ return Tcl_NewListObj(3, objv);
+ case Z_ERRNO:
+ TclNewLiteralStringObj(objv[2], "POSIX");
+ objv[3] = Tcl_NewStringObj(Tcl_ErrnoId(), -1);
+ return Tcl_NewListObj(4, objv);
+ case Z_NEED_DICT:
+ TclNewLiteralStringObj(objv[2], "NEED_DICT");
+ objv[3] = Tcl_NewWideIntObj((Tcl_WideInt) adler);
+ return Tcl_NewListObj(4, objv);
+
+ /*
+ * These should _not_ happen! This function is for dealing with error
+ * cases, not non-errors!
+ */
+
+ case Z_OK:
+ Tcl_Panic("unexpected zlib result in error handler: Z_OK");
+ case Z_STREAM_END:
+ Tcl_Panic("unexpected zlib result in error handler: Z_STREAM_END");
+
+ /*
+ * Catch-all. Should be unreachable because all cases are already
+ * listed above.
+ */
+
+ default:
+ TclNewLiteralStringObj(objv[2], "UNKNOWN");
+ TclNewIntObj(objv[3], code);
+ return Tcl_NewListObj(4, objv);
}
}
@@ -294,7 +444,9 @@ GenerateHeader(
NULL);
headerPtr->nativeCommentBuf[len] = '\0';
headerPtr->header.comment = (Bytef *) headerPtr->nativeCommentBuf;
- *extraSizePtr += len;
+ if (extraSizePtr != NULL) {
+ *extraSizePtr += len;
+ }
}
if (GetValue(interp, dictObj, "crc", &value) != TCL_OK) {
@@ -312,7 +464,9 @@ GenerateHeader(
headerPtr->nativeFilenameBuf, MAXPATHLEN-1, NULL, &len, NULL);
headerPtr->nativeFilenameBuf[len] = '\0';
headerPtr->header.name = (Bytef *) headerPtr->nativeFilenameBuf;
- *extraSizePtr += len;
+ if (extraSizePtr != NULL) {
+ *extraSizePtr += len;
+ }
}
if (GetValue(interp, dictObj, "os", &value) != TCL_OK) {
@@ -353,7 +507,7 @@ GenerateHeader(
* ExtractHeader --
*
* Take the values out of a gzip header and store them in a dictionary.
- * SetValue is a helper function.
+ * SetValue is a helper macro.
*
* Results:
* None.
@@ -364,18 +518,8 @@ GenerateHeader(
*----------------------------------------------------------------------
*/
-static inline void
-SetValue(
- Tcl_Obj *dictObj,
- const char *key,
- Tcl_Obj *value)
-{
- Tcl_Obj *keyObj = Tcl_NewStringObj(key, -1);
-
- Tcl_IncrRefCount(keyObj);
- Tcl_DictObjPut(NULL, dictObj, keyObj, value);
- TclDecrRefCount(keyObj);
-}
+#define SetValue(dictObj, key, value) \
+ Tcl_DictObjPut(NULL, (dictObj), Tcl_NewStringObj((key), -1), (value))
static void
ExtractHeader(
@@ -399,9 +543,7 @@ ExtractHeader(
Tcl_ExternalToUtfDString(latin1enc, (char *) headerPtr->comment, -1,
&tmp);
- SetValue(dictObj, "comment", Tcl_NewStringObj(Tcl_DStringValue(&tmp),
- Tcl_DStringLength(&tmp)));
- Tcl_DStringFree(&tmp);
+ SetValue(dictObj, "comment", TclDStringToObj(&tmp));
}
SetValue(dictObj, "crc", Tcl_NewBooleanObj(headerPtr->hcrc));
if (headerPtr->name != Z_NULL) {
@@ -418,9 +560,7 @@ ExtractHeader(
Tcl_ExternalToUtfDString(latin1enc, (char *) headerPtr->name, -1,
&tmp);
- SetValue(dictObj, "filename", Tcl_NewStringObj(Tcl_DStringValue(&tmp),
- Tcl_DStringLength(&tmp)));
- Tcl_DStringFree(&tmp);
+ SetValue(dictObj, "filename", TclDStringToObj(&tmp));
}
if (headerPtr->os != 255) {
SetValue(dictObj, "os", Tcl_NewIntObj(headerPtr->os));
@@ -438,6 +578,34 @@ ExtractHeader(
}
}
+static int
+SetInflateDictionary(
+ z_streamp strm,
+ Tcl_Obj *compDictObj)
+{
+ if (compDictObj != NULL) {
+ int length;
+ unsigned char *bytes = Tcl_GetByteArrayFromObj(compDictObj, &length);
+
+ return inflateSetDictionary(strm, bytes, (unsigned) length);
+ }
+ return Z_OK;
+}
+
+static int
+SetDeflateDictionary(
+ z_streamp strm,
+ Tcl_Obj *compDictObj)
+{
+ if (compDictObj != NULL) {
+ int length;
+ unsigned char *bytes = Tcl_GetByteArrayFromObj(compDictObj, &length);
+
+ return deflateSetDictionary(strm, bytes, (unsigned) length);
+ }
+ return Z_OK;
+}
+
/*
*----------------------------------------------------------------------
*
@@ -476,6 +644,7 @@ Tcl_ZlibStreamInit(
ZlibStreamHandle *zshPtr = NULL;
Tcl_DString cmdname;
Tcl_CmdInfo cmdinfo;
+ GzipHeader *gzHeaderPtr = NULL;
switch (mode) {
case TCL_ZLIB_STREAM_DEFLATE:
@@ -490,6 +659,15 @@ Tcl_ZlibStreamInit(
break;
case TCL_ZLIB_FORMAT_GZIP:
wbits = WBITS_GZIP;
+ if (dictObj) {
+ gzHeaderPtr = ckalloc(sizeof(GzipHeader));
+ memset(gzHeaderPtr, 0, sizeof(GzipHeader));
+ if (GenerateHeader(interp, dictObj, gzHeaderPtr,
+ NULL) != TCL_OK) {
+ ckfree(gzHeaderPtr);
+ return TCL_ERROR;
+ }
+ }
break;
case TCL_ZLIB_FORMAT_ZLIB:
wbits = WBITS_ZLIB;
@@ -516,6 +694,14 @@ Tcl_ZlibStreamInit(
break;
case TCL_ZLIB_FORMAT_GZIP:
wbits = WBITS_GZIP;
+ gzHeaderPtr = ckalloc(sizeof(GzipHeader));
+ memset(gzHeaderPtr, 0, sizeof(GzipHeader));
+ gzHeaderPtr->header.name = (Bytef *)
+ gzHeaderPtr->nativeFilenameBuf;
+ gzHeaderPtr->header.name_max = MAXPATHLEN - 1;
+ gzHeaderPtr->header.comment = (Bytef *)
+ gzHeaderPtr->nativeCommentBuf;
+ gzHeaderPtr->header.name_max = MAX_COMMENT_LEN - 1;
break;
case TCL_ZLIB_FORMAT_ZLIB:
wbits = WBITS_ZLIB;
@@ -542,7 +728,11 @@ Tcl_ZlibStreamInit(
zshPtr->wbits = wbits;
zshPtr->currentInput = NULL;
zshPtr->streamEnd = 0;
+ zshPtr->compDictObj = NULL;
+ zshPtr->flags = 0;
+ zshPtr->gzHeaderPtr = gzHeaderPtr;
memset(&zshPtr->stream, 0, sizeof(z_stream));
+ zshPtr->stream.adler = 1;
/*
* No output buffer available yet
@@ -551,12 +741,20 @@ Tcl_ZlibStreamInit(
if (mode == TCL_ZLIB_STREAM_DEFLATE) {
e = deflateInit2(&zshPtr->stream, level, Z_DEFLATED, wbits,
MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
+ if (e == Z_OK && zshPtr->gzHeaderPtr) {
+ e = deflateSetHeader(&zshPtr->stream,
+ &zshPtr->gzHeaderPtr->header);
+ }
} else {
e = inflateInit2(&zshPtr->stream, wbits);
+ if (e == Z_OK && zshPtr->gzHeaderPtr) {
+ e = inflateGetHeader(&zshPtr->stream,
+ &zshPtr->gzHeaderPtr->header);
+ }
}
if (e != Z_OK) {
- ConvertError(interp, e);
+ ConvertError(interp, e, zshPtr->stream.adler);
goto error;
}
@@ -569,13 +767,12 @@ Tcl_ZlibStreamInit(
goto error;
}
Tcl_DStringInit(&cmdname);
- Tcl_DStringAppend(&cmdname, "::tcl::zlib::streamcmd_", -1);
- Tcl_DStringAppend(&cmdname, Tcl_GetString(Tcl_GetObjResult(interp)),
- -1);
+ TclDStringAppendLiteral(&cmdname, "::tcl::zlib::streamcmd_");
+ TclDStringAppendObj(&cmdname, Tcl_GetObjResult(interp));
if (Tcl_GetCommandInfo(interp, Tcl_DStringValue(&cmdname),
&cmdinfo) == 1) {
- Tcl_SetResult(interp,
- "BUG: Stream command name already exists", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "BUG: Stream command name already exists", -1));
Tcl_SetErrorCode(interp, "TCL", "BUG", "EXISTING_CMD", NULL);
Tcl_DStringFree(&cmdname);
goto error;
@@ -617,7 +814,14 @@ Tcl_ZlibStreamInit(
}
return TCL_OK;
- error:
+
+ error:
+ if (zshPtr->compDictObj) {
+ Tcl_DecrRefCount(zshPtr->compDictObj);
+ }
+ if (zshPtr->gzHeaderPtr) {
+ ckfree(zshPtr->gzHeaderPtr);
+ }
ckfree(zshPtr);
return TCL_ERROR;
}
@@ -725,6 +929,12 @@ ZlibStreamCleanup(
if (zshPtr->currentInput) {
Tcl_DecrRefCount(zshPtr->currentInput);
}
+ if (zshPtr->compDictObj) {
+ Tcl_DecrRefCount(zshPtr->compDictObj);
+ }
+ if (zshPtr->gzHeaderPtr) {
+ ckfree(zshPtr->gzHeaderPtr);
+ }
ckfree(zshPtr);
}
@@ -777,12 +987,24 @@ Tcl_ZlibStreamReset(
if (zshPtr->mode == TCL_ZLIB_STREAM_DEFLATE) {
e = deflateInit2(&zshPtr->stream, zshPtr->level, Z_DEFLATED,
zshPtr->wbits, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
+ if (e == Z_OK && HaveDictToSet(zshPtr)) {
+ e = SetDeflateDictionary(&zshPtr->stream, zshPtr->compDictObj);
+ if (e == Z_OK) {
+ DictWasSet(zshPtr);
+ }
+ }
} else {
e = inflateInit2(&zshPtr->stream, zshPtr->wbits);
+ if (IsRawStream(zshPtr) && HaveDictToSet(zshPtr) && e == Z_OK) {
+ e = SetInflateDictionary(&zshPtr->stream, zshPtr->compDictObj);
+ if (e == Z_OK) {
+ DictWasSet(zshPtr);
+ }
+ }
}
if (e != Z_OK) {
- ConvertError(zshPtr->interp, e);
+ ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
/* TODO:cleanup */
return TCL_ERROR;
}
@@ -875,6 +1097,41 @@ Tcl_ZlibStreamChecksum(
/*
*----------------------------------------------------------------------
*
+ * Tcl_ZlibStreamSetCompressionDictionary --
+ *
+ * Sets the compression dictionary for a stream. This will be used as
+ * appropriate for the next compression or decompression action performed
+ * on the stream.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_ZlibStreamSetCompressionDictionary(
+ Tcl_ZlibStream zshandle,
+ Tcl_Obj *compressionDictionaryObj)
+{
+ ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle;
+
+ if (compressionDictionaryObj != NULL) {
+ if (Tcl_IsShared(compressionDictionaryObj)) {
+ compressionDictionaryObj =
+ Tcl_DuplicateObj(compressionDictionaryObj);
+ }
+ Tcl_IncrRefCount(compressionDictionaryObj);
+ zshPtr->flags |= DICT_TO_SET;
+ } else {
+ zshPtr->flags &= ~DICT_TO_SET;
+ }
+ if (zshPtr->compDictObj != NULL) {
+ Tcl_DecrRefCount(zshPtr->compDictObj);
+ }
+ zshPtr->compDictObj = compressionDictionaryObj;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* Tcl_ZlibStreamPut --
*
* Add data to the stream for compression or decompression from a
@@ -897,8 +1154,8 @@ Tcl_ZlibStreamPut(
if (zshPtr->streamEnd) {
if (zshPtr->interp) {
- Tcl_SetResult(zshPtr->interp,
- "already past compressed stream end", TCL_STATIC);
+ Tcl_SetObjResult(zshPtr->interp, Tcl_NewStringObj(
+ "already past compressed stream end", -1));
Tcl_SetErrorCode(zshPtr->interp, "TCL", "ZIP", "CLOSED", NULL);
}
return TCL_ERROR;
@@ -908,6 +1165,17 @@ Tcl_ZlibStreamPut(
zshPtr->stream.next_in = Tcl_GetByteArrayFromObj(data, &size);
zshPtr->stream.avail_in = size;
+ if (HaveDictToSet(zshPtr)) {
+ e = SetDeflateDictionary(&zshPtr->stream, zshPtr->compDictObj);
+ if (e != Z_OK) {
+ if (zshPtr->interp) {
+ ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
+ }
+ return TCL_ERROR;
+ }
+ DictWasSet(zshPtr);
+ }
+
/*
* Deflatebound doesn't seem to take various header sizes into
* account, so we add 100 extra bytes.
@@ -945,6 +1213,12 @@ Tcl_ZlibStreamPut(
e = deflate(&zshPtr->stream, flush);
}
+ if (e != Z_OK && !(flush==Z_FINISH && e==Z_STREAM_END)) {
+ if (zshPtr->interp) {
+ ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
+ }
+ return TCL_ERROR;
+ }
/*
* And append the final data block.
@@ -1022,7 +1296,7 @@ Tcl_ZlibStreamGet(
* panic for out of memory if we just kept growing the buffer.
*/
- count = 65536;
+ count = MAX_BUFFER_SIZE;
}
/*
@@ -1070,7 +1344,30 @@ Tcl_ZlibStreamGet(
}
}
+ /*
+ * When dealing with a raw stream, we set the dictionary here, once.
+ * (You can't do it in response to getting Z_NEED_DATA as raw streams
+ * don't ever issue that.)
+ */
+
+ if (IsRawStream(zshPtr) && HaveDictToSet(zshPtr)) {
+ e = SetInflateDictionary(&zshPtr->stream, zshPtr->compDictObj);
+ if (e != Z_OK) {
+ if (zshPtr->interp) {
+ ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
+ }
+ return TCL_ERROR;
+ }
+ DictWasSet(zshPtr);
+ }
e = inflate(&zshPtr->stream, zshPtr->flush);
+ if (e == Z_NEED_DICT && HaveDictToSet(zshPtr)) {
+ e = SetInflateDictionary(&zshPtr->stream, zshPtr->compDictObj);
+ if (e == Z_OK) {
+ DictWasSet(zshPtr);
+ e = inflate(&zshPtr->stream, zshPtr->flush);
+ }
+ };
Tcl_ListObjLength(NULL, zshPtr->inData, &listLen);
while ((zshPtr->stream.avail_out > 0)
@@ -1082,9 +1379,9 @@ Tcl_ZlibStreamGet(
if (zshPtr->stream.avail_in > 0) {
if (zshPtr->interp) {
- Tcl_SetResult(zshPtr->interp,
- "Unexpected zlib internal state during decompression",
- TCL_STATIC);
+ Tcl_SetObjResult(zshPtr->interp, Tcl_NewStringObj(
+ "unexpected zlib internal state during"
+ " decompression", -1));
Tcl_SetErrorCode(zshPtr->interp, "TCL", "ZIP", "STATE",
NULL);
}
@@ -1124,7 +1421,14 @@ Tcl_ZlibStreamGet(
* And call inflate again.
*/
- e = inflate(&zshPtr->stream, zshPtr->flush);
+ do {
+ e = inflate(&zshPtr->stream, zshPtr->flush);
+ if (e != Z_NEED_DICT || !HaveDictToSet(zshPtr)) {
+ break;
+ }
+ e = SetInflateDictionary(&zshPtr->stream,zshPtr->compDictObj);
+ DictWasSet(zshPtr);
+ } while (e == Z_OK);
}
if (zshPtr->stream.avail_out > 0) {
Tcl_SetByteArrayLength(data,
@@ -1132,7 +1436,7 @@ Tcl_ZlibStreamGet(
}
if (!(e==Z_OK || e==Z_STREAM_END || e==Z_BUF_ERROR)) {
Tcl_SetByteArrayLength(data, existing);
- ConvertError(zshPtr->interp, e);
+ ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
return TCL_ERROR;
}
if (e == Z_STREAM_END) {
@@ -1348,7 +1652,7 @@ Tcl_ZlibDeflate(
return TCL_OK;
error:
- ConvertError(interp, e);
+ ConvertError(interp, e, stream.adler);
TclDecrRefCount(obj);
return TCL_ERROR;
}
@@ -1527,7 +1831,7 @@ Tcl_ZlibInflate(
error:
TclDecrRefCount(obj);
- ConvertError(interp, e);
+ ConvertError(interp, e, stream.adler);
if (nameBuf) {
ckfree(nameBuf);
}
@@ -1583,11 +1887,10 @@ ZlibCmd(
int objc,
Tcl_Obj *const objv[])
{
- int command, dlen, mode, format, i, option, level = -1;
+ int command, dlen, i, option, level = -1;
unsigned start, buffersize = 0;
- Tcl_ZlibStream zh;
Byte *data;
- Tcl_Obj *headerDictObj, *headerVarObj;
+ Tcl_Obj *headerDictObj;
const char *extraInfoStr = NULL;
static const char *const commands[] = {
"adler32", "compress", "crc32", "decompress", "deflate", "gunzip",
@@ -1598,14 +1901,6 @@ ZlibCmd(
CMD_ADLER, CMD_COMPRESS, CMD_CRC, CMD_DECOMPRESS, CMD_DEFLATE,
CMD_GUNZIP, CMD_GZIP, CMD_INFLATE, CMD_PUSH, CMD_STREAM
};
- static const char *const stream_formats[] = {
- "compress", "decompress", "deflate", "gunzip", "gzip", "inflate",
- NULL
- };
- enum zlibFormats {
- FMT_COMPRESS, FMT_DECOMPRESS, FMT_DEFLATE, FMT_GUNZIP, FMT_GZIP,
- FMT_INFLATE
- };
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "command arg ?...?");
@@ -1632,7 +1927,7 @@ ZlibCmd(
}
data = Tcl_GetByteArrayFromObj(objv[2], &dlen);
Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)
- Tcl_ZlibAdler32(start, data, dlen)));
+ (uLong) Tcl_ZlibAdler32(start, data, dlen)));
return TCL_OK;
case CMD_CRC: /* crc32 str ?startvalue?
* -> checksum */
@@ -1649,7 +1944,7 @@ ZlibCmd(
}
data = Tcl_GetByteArrayFromObj(objv[2], &dlen);
Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)
- Tcl_ZlibCRC32(start, data, dlen)));
+ (uLong) Tcl_ZlibCRC32(start, data, dlen)));
return TCL_OK;
case CMD_DEFLATE: /* deflate data ?level?
* -> rawCompressedData */
@@ -1685,12 +1980,27 @@ ZlibCmd(
NULL);
case CMD_GZIP: /* gzip data ?level?
* -> gzippedCompressedData */
+ headerDictObj = NULL;
+
+ /*
+ * Legacy argument format support.
+ */
+
+ if (objc == 4
+ && Tcl_GetIntFromObj(interp, objv[3], &level) == TCL_OK) {
+ if (level < 0 || level > 9) {
+ extraInfoStr = "\n (in -level option)";
+ goto badLevel;
+ }
+ return Tcl_ZlibDeflate(interp, TCL_ZLIB_FORMAT_GZIP, objv[2],
+ level, NULL);
+ }
+
if (objc < 3 || objc > 7 || ((objc & 1) == 0)) {
Tcl_WrongNumArgs(interp, 2, objv,
"data ?-level level? ?-header header?");
return TCL_ERROR;
}
- headerDictObj = NULL;
for (i=3 ; i<objc ; i+=2) {
static const char *const gzipopts[] = {
"-header", "-level", NULL
@@ -1729,7 +2039,8 @@ ZlibCmd(
(int *) &buffersize) != TCL_OK) {
return TCL_ERROR;
}
- if (buffersize < 16 || buffersize > 65536) {
+ if (buffersize < MIN_NONSTREAM_BUFFER_SIZE
+ || buffersize > MAX_BUFFER_SIZE) {
goto badBuffer;
}
}
@@ -1747,14 +2058,17 @@ ZlibCmd(
(int *) &buffersize) != TCL_OK) {
return TCL_ERROR;
}
- if (buffersize < 16 || buffersize > 65536) {
+ if (buffersize < MIN_NONSTREAM_BUFFER_SIZE
+ || buffersize > MAX_BUFFER_SIZE) {
goto badBuffer;
}
}
return Tcl_ZlibInflate(interp, TCL_ZLIB_FORMAT_ZLIB, objv[2],
buffersize, NULL);
- case CMD_GUNZIP: /* gunzip gzippeddata ?bufferSize?
+ case CMD_GUNZIP: { /* gunzip gzippeddata ?bufferSize?
* -> decompressedData */
+ Tcl_Obj *headerVarObj;
+
if (objc < 3 || objc > 5 || ((objc & 1) == 0)) {
Tcl_WrongNumArgs(interp, 2, objv, "data ?-headerVar varName?");
return TCL_ERROR;
@@ -1775,7 +2089,8 @@ ZlibCmd(
(int *) &buffersize) != TCL_OK) {
return TCL_ERROR;
}
- if (buffersize < 16 || buffersize > 65536) {
+ if (buffersize < MIN_NONSTREAM_BUFFER_SIZE
+ || buffersize > MAX_BUFFER_SIZE) {
goto badBuffer;
}
break;
@@ -1794,214 +2109,360 @@ ZlibCmd(
}
if (headerVarObj != NULL && Tcl_ObjSetVar2(interp, headerVarObj, NULL,
headerDictObj, TCL_LEAVE_ERR_MSG) == NULL) {
- if (headerDictObj) {
- TclDecrRefCount(headerDictObj);
- }
return TCL_ERROR;
}
return TCL_OK;
+ }
case CMD_STREAM: /* stream deflate/inflate/...gunzip \
- * ?level?
+ * ?options...?
* -> handleCmd */
- if (objc < 3 || objc > 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "mode ?level?");
- return TCL_ERROR;
- }
- if (Tcl_GetIndexFromObj(interp, objv[2], stream_formats, "mode", 0,
- &format) != TCL_OK) {
- return TCL_ERROR;
- }
- mode = TCL_ZLIB_STREAM_INFLATE;
- switch ((enum zlibFormats) format) {
- case FMT_DEFLATE:
- mode = TCL_ZLIB_STREAM_DEFLATE;
- case FMT_INFLATE:
- format = TCL_ZLIB_FORMAT_RAW;
- break;
- case FMT_COMPRESS:
- mode = TCL_ZLIB_STREAM_DEFLATE;
- case FMT_DECOMPRESS:
- format = TCL_ZLIB_FORMAT_ZLIB;
- break;
- case FMT_GZIP:
- mode = TCL_ZLIB_STREAM_DEFLATE;
- case FMT_GUNZIP:
- format = TCL_ZLIB_FORMAT_GZIP;
- break;
- }
- if (objc == 4) {
- if (Tcl_GetIntFromObj(interp, objv[3],
- (int *) &level) != TCL_OK) {
- return TCL_ERROR;
- }
- if (level < 0 || level > 9) {
- goto badLevel;
- }
- } else {
- level = Z_DEFAULT_COMPRESSION;
- }
- if (Tcl_ZlibStreamInit(interp, mode, format, level, NULL,
- &zh) != TCL_OK) {
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, Tcl_ZlibStreamGetCommandName(zh));
- return TCL_OK;
- case CMD_PUSH: { /* push mode channel options...
+ return ZlibStreamSubcmd(interp, objc, objv);
+ case CMD_PUSH: /* push mode channel options...
* -> channel */
- Tcl_Channel chan;
- int chanMode;
- static const char *const pushOptions[] = {
- "-header", "-level", "-limit",
- NULL
- };
- enum pushOptions {poHeader, poLevel, poLimit};
- Tcl_Obj *headerObj = NULL;
- int limit = 1, dummy;
+ return ZlibPushSubcmd(interp, objc, objv);
+ };
- if (objc < 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "mode channel ?options...?");
- return TCL_ERROR;
- }
+ return TCL_ERROR;
- if (Tcl_GetIndexFromObj(interp, objv[2], stream_formats, "mode", 0,
- &format) != TCL_OK) {
- return TCL_ERROR;
- }
- switch ((enum zlibFormats) format) {
- case FMT_DEFLATE:
- mode = TCL_ZLIB_STREAM_DEFLATE;
- format = TCL_ZLIB_FORMAT_RAW;
- break;
- case FMT_INFLATE:
- mode = TCL_ZLIB_STREAM_INFLATE;
- format = TCL_ZLIB_FORMAT_RAW;
- break;
- case FMT_COMPRESS:
- mode = TCL_ZLIB_STREAM_DEFLATE;
- format = TCL_ZLIB_FORMAT_ZLIB;
- break;
- case FMT_DECOMPRESS:
- mode = TCL_ZLIB_STREAM_INFLATE;
- format = TCL_ZLIB_FORMAT_ZLIB;
- break;
- case FMT_GZIP:
- mode = TCL_ZLIB_STREAM_DEFLATE;
- format = TCL_ZLIB_FORMAT_GZIP;
- break;
- case FMT_GUNZIP:
- mode = TCL_ZLIB_STREAM_INFLATE;
- format = TCL_ZLIB_FORMAT_GZIP;
- break;
- default:
- Tcl_AppendResult(interp, "IMPOSSIBLE", NULL);
- return TCL_ERROR;
- }
+ badLevel:
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("level must be 0 to 9", -1));
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMPRESSIONLEVEL", NULL);
+ if (extraInfoStr) {
+ Tcl_AddErrorInfo(interp, extraInfoStr);
+ }
+ return TCL_ERROR;
+ badBuffer:
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "buffer size must be %d to %d",
+ MIN_NONSTREAM_BUFFER_SIZE, MAX_BUFFER_SIZE));
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "BUFFERSIZE", NULL);
+ return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibStreamSubcmd --
+ *
+ * Implementation of the [zlib stream] subcommand.
+ *
+ *----------------------------------------------------------------------
+ */
- if (TclGetChannelFromObj(interp, objv[3], &chan, &chanMode,
- 0) != TCL_OK) {
+static int
+ZlibStreamSubcmd(
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ static const char *const stream_formats[] = {
+ "compress", "decompress", "deflate", "gunzip", "gzip", "inflate",
+ NULL
+ };
+ enum zlibFormats {
+ FMT_COMPRESS, FMT_DECOMPRESS, FMT_DEFLATE, FMT_GUNZIP, FMT_GZIP,
+ FMT_INFLATE
+ };
+ int i, format, mode = 0, option, level;
+ enum objIndices {
+ OPT_COMPRESSION_DICTIONARY = 0,
+ OPT_GZIP_HEADER = 1,
+ OPT_COMPRESSION_LEVEL = 2,
+ OPT_END = -1
+ };
+ Tcl_Obj *obj[3] = { NULL, NULL, NULL };
+#define compDictObj obj[OPT_COMPRESSION_DICTIONARY]
+#define gzipHeaderObj obj[OPT_GZIP_HEADER]
+#define levelObj obj[OPT_COMPRESSION_LEVEL]
+ typedef struct {
+ const char *name;
+ enum objIndices offset;
+ } OptDescriptor;
+ static const OptDescriptor compressionOpts[] = {
+ { "-dictionary", OPT_COMPRESSION_DICTIONARY },
+ { "-level", OPT_COMPRESSION_LEVEL },
+ { NULL, OPT_END }
+ };
+ static const OptDescriptor gzipOpts[] = {
+ { "-header", OPT_GZIP_HEADER },
+ { "-level", OPT_COMPRESSION_LEVEL },
+ { NULL, OPT_END }
+ };
+ static const OptDescriptor expansionOpts[] = {
+ { "-dictionary", OPT_COMPRESSION_DICTIONARY },
+ { NULL, OPT_END }
+ };
+ static const OptDescriptor gunzipOpts[] = {
+ { NULL, OPT_END }
+ };
+ const OptDescriptor *desc = NULL;
+ Tcl_ZlibStream zh;
+
+ if (objc < 3 || !(objc & 1)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "mode ?-option value...?");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], stream_formats, "mode", 0,
+ &format) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * The format determines the compression mode and the options that may be
+ * specified.
+ */
+
+ switch ((enum zlibFormats) format) {
+ case FMT_DEFLATE:
+ desc = compressionOpts;
+ mode = TCL_ZLIB_STREAM_DEFLATE;
+ format = TCL_ZLIB_FORMAT_RAW;
+ break;
+ case FMT_INFLATE:
+ desc = expansionOpts;
+ mode = TCL_ZLIB_STREAM_INFLATE;
+ format = TCL_ZLIB_FORMAT_RAW;
+ break;
+ case FMT_COMPRESS:
+ desc = compressionOpts;
+ mode = TCL_ZLIB_STREAM_DEFLATE;
+ format = TCL_ZLIB_FORMAT_ZLIB;
+ break;
+ case FMT_DECOMPRESS:
+ desc = expansionOpts;
+ mode = TCL_ZLIB_STREAM_INFLATE;
+ format = TCL_ZLIB_FORMAT_ZLIB;
+ break;
+ case FMT_GZIP:
+ desc = gzipOpts;
+ mode = TCL_ZLIB_STREAM_DEFLATE;
+ format = TCL_ZLIB_FORMAT_GZIP;
+ break;
+ case FMT_GUNZIP:
+ desc = gunzipOpts;
+ mode = TCL_ZLIB_STREAM_INFLATE;
+ format = TCL_ZLIB_FORMAT_GZIP;
+ break;
+ default:
+ Tcl_Panic("should be unreachable");
+ }
+
+ /*
+ * Parse the options.
+ */
+
+ for (i=3 ; i<objc ; i+=2) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], desc,
+ sizeof(OptDescriptor), "option", 0, &option) != TCL_OK) {
return TCL_ERROR;
}
+ obj[desc[option].offset] = objv[i+1];
+ }
- /*
- * Sanity checks.
- */
+ /*
+ * If a compression level was given, parse it (integral: 0..9). Otherwise
+ * use the default.
+ */
- if (mode == TCL_ZLIB_STREAM_DEFLATE && !(chanMode & TCL_WRITABLE)) {
- Tcl_AppendResult(interp,
- "compression may only be applied to writable channels",
- NULL);
- Tcl_SetErrorCode(interp, "TCL", "ZIP", "UNWRITABLE", NULL);
+ if (levelObj == NULL) {
+ level = Z_DEFAULT_COMPRESSION;
+ } else if (Tcl_GetIntFromObj(interp, levelObj, &level) != TCL_OK) {
+ return TCL_ERROR;
+ } else if (level < 0 || level > 9) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("level must be 0 to 9",-1));
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMPRESSIONLEVEL", NULL);
+ Tcl_AddErrorInfo(interp, "\n (in -level option)");
+ return TCL_ERROR;
+ }
+
+ /*
+ * Construct the stream now we know its configuration.
+ */
+
+ if (Tcl_ZlibStreamInit(interp, mode, format, level, gzipHeaderObj,
+ &zh) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (compDictObj != NULL) {
+ Tcl_ZlibStreamSetCompressionDictionary(zh, compDictObj);
+ }
+ Tcl_SetObjResult(interp, Tcl_ZlibStreamGetCommandName(zh));
+ return TCL_OK;
+#undef compDictObj
+#undef gzipHeaderObj
+#undef levelObj
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibPushSubcmd --
+ *
+ * Implementation of the [zlib push] subcommand.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibPushSubcmd(
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ static const char *const stream_formats[] = {
+ "compress", "decompress", "deflate", "gunzip", "gzip", "inflate",
+ NULL
+ };
+ enum zlibFormats {
+ FMT_COMPRESS, FMT_DECOMPRESS, FMT_DEFLATE, FMT_GUNZIP, FMT_GZIP,
+ FMT_INFLATE
+ };
+ Tcl_Channel chan;
+ int chanMode, format, mode = 0, level, i, option;
+ static const char *const pushCompressOptions[] = {
+ "-dictionary", "-header", "-level", NULL
+ };
+ static const char *const pushDecompressOptions[] = {
+ "-dictionary", "-header", "-level", "-limit", NULL
+ };
+ const char *const *pushOptions = pushDecompressOptions;
+ enum pushOptions {poDictionary, poHeader, poLevel, poLimit};
+ Tcl_Obj *headerObj = NULL, *compDictObj = NULL;
+ int limit = 1, dummy;
+
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "mode channel ?options...?");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetIndexFromObj(interp, objv[2], stream_formats, "mode", 0,
+ &format) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch ((enum zlibFormats) format) {
+ case FMT_DEFLATE:
+ mode = TCL_ZLIB_STREAM_DEFLATE;
+ format = TCL_ZLIB_FORMAT_RAW;
+ pushOptions = pushCompressOptions;
+ break;
+ case FMT_INFLATE:
+ mode = TCL_ZLIB_STREAM_INFLATE;
+ format = TCL_ZLIB_FORMAT_RAW;
+ break;
+ case FMT_COMPRESS:
+ mode = TCL_ZLIB_STREAM_DEFLATE;
+ format = TCL_ZLIB_FORMAT_ZLIB;
+ pushOptions = pushCompressOptions;
+ break;
+ case FMT_DECOMPRESS:
+ mode = TCL_ZLIB_STREAM_INFLATE;
+ format = TCL_ZLIB_FORMAT_ZLIB;
+ break;
+ case FMT_GZIP:
+ mode = TCL_ZLIB_STREAM_DEFLATE;
+ format = TCL_ZLIB_FORMAT_GZIP;
+ pushOptions = pushCompressOptions;
+ break;
+ case FMT_GUNZIP:
+ mode = TCL_ZLIB_STREAM_INFLATE;
+ format = TCL_ZLIB_FORMAT_GZIP;
+ break;
+ default:
+ Tcl_Panic("should be unreachable");
+ }
+
+ if (TclGetChannelFromObj(interp, objv[3], &chan, &chanMode, 0) != TCL_OK){
+ return TCL_ERROR;
+ }
+
+ /*
+ * Sanity checks.
+ */
+
+ if (mode == TCL_ZLIB_STREAM_DEFLATE && !(chanMode & TCL_WRITABLE)) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "compression may only be applied to writable channels", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ZIP", "UNWRITABLE", NULL);
+ return TCL_ERROR;
+ }
+ if (mode == TCL_ZLIB_STREAM_INFLATE && !(chanMode & TCL_READABLE)) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "decompression may only be applied to readable channels",-1));
+ Tcl_SetErrorCode(interp, "TCL", "ZIP", "UNREADABLE", NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Parse options.
+ */
+
+ level = Z_DEFAULT_COMPRESSION;
+ for (i=4 ; i<objc ; i++) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], pushOptions, "option", 0,
+ &option) != TCL_OK) {
return TCL_ERROR;
}
- if (mode == TCL_ZLIB_STREAM_INFLATE && !(chanMode & TCL_READABLE)) {
- Tcl_AppendResult(interp,
- "decompression may only be applied to readable channels",
- NULL);
- Tcl_SetErrorCode(interp, "TCL", "ZIP", "UNREADABLE", NULL);
+ if (++i > objc-1) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "value missing for %s option", pushOptions[option]));
+ Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL);
return TCL_ERROR;
}
-
- /*
- * Parse options.
- */
-
- level = Z_DEFAULT_COMPRESSION;
- for (i=4 ; i<objc ; i++) {
- if (Tcl_GetIndexFromObj(interp, objv[i], pushOptions, "option", 0,
- &option) != TCL_OK) {
- return TCL_ERROR;
+ switch ((enum pushOptions) option) {
+ case poHeader:
+ headerObj = objv[i];
+ if (Tcl_DictObjSize(interp, headerObj, &dummy) != TCL_OK) {
+ goto genericOptionError;
}
- switch ((enum pushOptions) option) {
- case poHeader:
- if (++i > objc-1) {
- Tcl_AppendResult(interp,
- "value missing for -header option", NULL);
- Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL);
- return TCL_ERROR;
- }
- headerObj = objv[i];
- if (Tcl_DictObjSize(interp, headerObj, &dummy) != TCL_OK) {
- Tcl_AddErrorInfo(interp, "\n (in -header option)");
- return TCL_ERROR;
- }
- break;
- case poLevel:
- if (++i > objc-1) {
- Tcl_AppendResult(interp,
- "value missing for -level option", NULL);
- Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL);
- return TCL_ERROR;
- }
- if (Tcl_GetIntFromObj(interp, objv[i],
- (int *) &level) != TCL_OK) {
- Tcl_AddErrorInfo(interp, "\n (in -level option)");
- return TCL_ERROR;
- }
- if (level < 0 || level > 9) {
- extraInfoStr = "\n (in -level option)";
- goto badLevel;
- }
- break;
- case poLimit:
- if (++i > objc-1) {
- Tcl_AppendResult(interp,
- "value missing for -limit option", NULL);
- Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL);
- return TCL_ERROR;
- }
- if (Tcl_GetIntFromObj(interp, objv[i],
- (int *) &limit) != TCL_OK) {
- Tcl_AddErrorInfo(interp, "\n (in -limit option)");
- return TCL_ERROR;
- }
- if (limit < 1) {
- limit = 1;
- }
- break;
+ break;
+ case poLevel:
+ if (Tcl_GetIntFromObj(interp, objv[i], (int*) &level) != TCL_OK) {
+ goto genericOptionError;
}
+ if (level < 0 || level > 9) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "level must be 0 to 9", -1));
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMPRESSIONLEVEL",
+ NULL);
+ goto genericOptionError;
+ }
+ break;
+ case poLimit:
+ if (Tcl_GetIntFromObj(interp, objv[i], (int*) &limit) != TCL_OK) {
+ goto genericOptionError;
+ }
+ if (limit < 1 || limit > MAX_BUFFER_SIZE) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "read ahead limit must be 1 to %d",
+ MAX_BUFFER_SIZE));
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "BUFFERSIZE", NULL);
+ goto genericOptionError;
+ }
+ break;
+ case poDictionary:
+ if (format == TCL_ZLIB_FORMAT_GZIP) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "a compression dictionary may not be set in the "
+ "gzip format", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ZIP", "BADOPT", NULL);
+ goto genericOptionError;
+ }
+ compDictObj = objv[i];
+ break;
}
-
- if (ZlibStackChannelTransform(interp, mode, format, level, chan,
- headerObj) == NULL) {
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, objv[3]);
- return TCL_OK;
}
- };
- return TCL_ERROR;
-
- badLevel:
- Tcl_AppendResult(interp, "level must be 0 to 9", NULL);
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMPRESSIONLEVEL", NULL);
- if (extraInfoStr) {
- Tcl_AddErrorInfo(interp, extraInfoStr);
+ if (ZlibStackChannelTransform(interp, mode, format, level, limit, chan,
+ headerObj, compDictObj) == NULL) {
+ return TCL_ERROR;
}
- return TCL_ERROR;
- badBuffer:
- Tcl_AppendResult(interp, "buffer size must be 32 to 65536", NULL);
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "BUFFERSIZE", NULL);
+ Tcl_SetObjResult(interp, objv[3]);
+ return TCL_OK;
+
+ genericOptionError:
+ Tcl_AddErrorInfo(interp, "\n (in ");
+ Tcl_AddErrorInfo(interp, pushOptions[option]);
+ Tcl_AddErrorInfo(interp, " option)");
return TCL_ERROR;
}
@@ -2023,22 +2484,16 @@ ZlibStreamCmd(
Tcl_Obj *const objv[])
{
Tcl_ZlibStream zstream = cd;
- int command, index, count, code, buffersize = -1, flush = -1, i;
+ int command, count, code;
Tcl_Obj *obj;
static const char *const cmds[] = {
"add", "checksum", "close", "eof", "finalize", "flush",
- "fullflush", "get", "put", "reset",
+ "fullflush", "get", "header", "put", "reset",
NULL
};
enum zlibStreamCommands {
zs_add, zs_checksum, zs_close, zs_eof, zs_finalize, zs_flush,
- zs_fullflush, zs_get, zs_put, zs_reset
- };
- static const char *const add_options[] = {
- "-buffer", "-finalize", "-flush", "-fullflush", NULL
- };
- enum addOptions {
- ao_buffer, ao_finalize, ao_flush, ao_fullflush
+ zs_fullflush, zs_get, zs_header, zs_put, zs_reset
};
if (objc < 2) {
@@ -2053,123 +2508,11 @@ ZlibStreamCmd(
switch ((enum zlibStreamCommands) command) {
case zs_add: /* $strm add ?$flushopt? $data */
- for (i=2; i<objc-1; i++) {
- if (Tcl_GetIndexFromObj(interp, objv[i], add_options, "option", 0,
- &index) != TCL_OK) {
- return TCL_ERROR;
- }
-
- switch ((enum addOptions) index) {
- case ao_flush: /* -flush */
- if (flush > -1) {
- flush = -2;
- } else {
- flush = Z_SYNC_FLUSH;
- }
- break;
- case ao_fullflush: /* -fullflush */
- if (flush > -1) {
- flush = -2;
- } else {
- flush = Z_FULL_FLUSH;
- }
- break;
- case ao_finalize: /* -finalize */
- if (flush > -1) {
- flush = -2;
- } else {
- flush = Z_FINISH;
- }
- break;
- case ao_buffer: /* -buffer */
- if (i == objc-2) {
- Tcl_AppendResult(interp, "\"-buffer\" option must be "
- "followed by integer decompression buffersize",
- NULL);
- Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL);
- return TCL_ERROR;
- }
- if (Tcl_GetIntFromObj(interp, objv[i+1],
- &buffersize) != TCL_OK) {
- return TCL_ERROR;
- }
- if (buffersize < 1 || buffersize > 65536) {
- Tcl_AppendResult(interp,
- "buffer size must be 32 to 65536", NULL);
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "BUFFERSIZE",
- NULL);
- return TCL_ERROR;
- }
- }
-
- if (flush == -2) {
- Tcl_AppendResult(interp, "\"-flush\", \"-fullflush\" and "
- "\"-finalize\" options are mutually exclusive", NULL);
- Tcl_SetErrorCode(interp, "TCL", "ZIP", "EXCLUSIVE", NULL);
- return TCL_ERROR;
- }
- }
- if (flush == -1) {
- flush = 0;
- }
-
- if (Tcl_ZlibStreamPut(zstream, objv[objc-1], flush) != TCL_OK) {
- return TCL_ERROR;
- }
- TclNewObj(obj);
- code = Tcl_ZlibStreamGet(zstream, obj, buffersize);
- if (code == TCL_OK) {
- Tcl_SetObjResult(interp, obj);
- } else {
- TclDecrRefCount(obj);
- }
- return code;
-
+ return ZlibStreamAddCmd(zstream, interp, objc, objv);
+ case zs_header: /* $strm header */
+ return ZlibStreamHeaderCmd(zstream, interp, objc, objv);
case zs_put: /* $strm put ?$flushopt? $data */
- for (i=2; i<objc-1; i++) {
- if (Tcl_GetIndexFromObj(interp, objv[i], add_options, "option", 0,
- &index) != TCL_OK) {
- return TCL_ERROR;
- }
-
- switch ((enum addOptions) index) {
- case ao_flush: /* -flush */
- if (flush > -1) {
- flush = -2;
- } else {
- flush = Z_SYNC_FLUSH;
- }
- break;
- case ao_fullflush: /* -fullflush */
- if (flush > -1) {
- flush = -2;
- } else {
- flush = Z_FULL_FLUSH;
- }
- break;
- case ao_finalize: /* -finalize */
- if (flush > -1) {
- flush = -2;
- } else {
- flush = Z_FINISH;
- }
- break;
- case ao_buffer:
- Tcl_AppendResult(interp,
- "\"-buffer\" option not supported here", NULL);
- return TCL_ERROR;
- }
- if (flush == -2) {
- Tcl_AppendResult(interp, "\"-flush\", \"-fullflush\" and "
- "\"-finalize\" options are mutually exclusive", NULL);
- Tcl_SetErrorCode(interp, "TCL", "ZIP", "EXCLUSIVE", NULL);
- return TCL_ERROR;
- }
- }
- if (flush == -1) {
- flush = 0;
- }
- return Tcl_ZlibStreamPut(zstream, objv[objc-1], flush);
+ return ZlibStreamPutCmd(zstream, interp, objc, objv);
case zs_get: /* $strm get ?count? */
if (objc > 3) {
@@ -2246,7 +2589,7 @@ ZlibStreamCmd(
return TCL_ERROR;
}
Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)
- Tcl_ZlibStreamChecksum(zstream)));
+ (uLong) Tcl_ZlibStreamChecksum(zstream)));
return TCL_OK;
case zs_reset: /* $strm reset */
if (objc != 2) {
@@ -2258,11 +2601,257 @@ ZlibStreamCmd(
return TCL_OK;
}
+
+static int
+ZlibStreamAddCmd(
+ ClientData cd,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ Tcl_ZlibStream zstream = cd;
+ int index, code, buffersize = -1, flush = -1, i;
+ Tcl_Obj *obj, *compDictObj = NULL;
+ static const char *const add_options[] = {
+ "-buffer", "-dictionary", "-finalize", "-flush", "-fullflush", NULL
+ };
+ enum addOptions {
+ ao_buffer, ao_dictionary, ao_finalize, ao_flush, ao_fullflush
+ };
+
+ for (i=2; i<objc-1; i++) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], add_options, "option", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ switch ((enum addOptions) index) {
+ case ao_flush: /* -flush */
+ if (flush > -1) {
+ flush = -2;
+ } else {
+ flush = Z_SYNC_FLUSH;
+ }
+ break;
+ case ao_fullflush: /* -fullflush */
+ if (flush > -1) {
+ flush = -2;
+ } else {
+ flush = Z_FULL_FLUSH;
+ }
+ break;
+ case ao_finalize: /* -finalize */
+ if (flush > -1) {
+ flush = -2;
+ } else {
+ flush = Z_FINISH;
+ }
+ break;
+ case ao_buffer: /* -buffer */
+ if (i == objc-2) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "\"-buffer\" option must be followed by integer "
+ "decompression buffersize", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL);
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIntFromObj(interp, objv[++i], &buffersize) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (buffersize < 1 || buffersize > MAX_BUFFER_SIZE) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "buffer size must be 1 to %d",
+ MAX_BUFFER_SIZE));
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "BUFFERSIZE", NULL);
+ return TCL_ERROR;
+ }
+ break;
+ case ao_dictionary:
+ if (i == objc-2) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "\"-dictionary\" option must be followed by"
+ " compression dictionary bytes", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL);
+ return TCL_ERROR;
+ }
+ compDictObj = objv[++i];
+ break;
+ }
+
+ if (flush == -2) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "\"-flush\", \"-fullflush\" and \"-finalize\" options"
+ " are mutually exclusive", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ZIP", "EXCLUSIVE", NULL);
+ return TCL_ERROR;
+ }
+ }
+ if (flush == -1) {
+ flush = 0;
+ }
+
+ /*
+ * Set the compression dictionary if requested.
+ */
+
+ if (compDictObj != NULL) {
+ int len;
+
+ (void) Tcl_GetByteArrayFromObj(compDictObj, &len);
+ if (len == 0) {
+ compDictObj = NULL;
+ }
+ Tcl_ZlibStreamSetCompressionDictionary(zstream, compDictObj);
+ }
+
+ /*
+ * Send the data to the stream core, along with any flushing directive.
+ */
+
+ if (Tcl_ZlibStreamPut(zstream, objv[objc-1], flush) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Get such data out as we can (up to the requested length).
+ */
+
+ TclNewObj(obj);
+ code = Tcl_ZlibStreamGet(zstream, obj, buffersize);
+ if (code == TCL_OK) {
+ Tcl_SetObjResult(interp, obj);
+ } else {
+ TclDecrRefCount(obj);
+ }
+ return code;
+}
+
+static int
+ZlibStreamPutCmd(
+ ClientData cd,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ Tcl_ZlibStream zstream = cd;
+ int index, flush = -1, i;
+ Tcl_Obj *compDictObj = NULL;
+ static const char *const put_options[] = {
+ "-dictionary", "-finalize", "-flush", "-fullflush", NULL
+ };
+ enum putOptions {
+ po_dictionary, po_finalize, po_flush, po_fullflush
+ };
+
+ for (i=2; i<objc-1; i++) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], put_options, "option", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ switch ((enum putOptions) index) {
+ case po_flush: /* -flush */
+ if (flush > -1) {
+ flush = -2;
+ } else {
+ flush = Z_SYNC_FLUSH;
+ }
+ break;
+ case po_fullflush: /* -fullflush */
+ if (flush > -1) {
+ flush = -2;
+ } else {
+ flush = Z_FULL_FLUSH;
+ }
+ break;
+ case po_finalize: /* -finalize */
+ if (flush > -1) {
+ flush = -2;
+ } else {
+ flush = Z_FINISH;
+ }
+ break;
+ case po_dictionary:
+ if (i == objc-2) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "\"-dictionary\" option must be followed by"
+ " compression dictionary bytes", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL);
+ return TCL_ERROR;
+ }
+ compDictObj = objv[++i];
+ break;
+ }
+ if (flush == -2) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "\"-flush\", \"-fullflush\" and \"-finalize\" options"
+ " are mutually exclusive", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ZIP", "EXCLUSIVE", NULL);
+ return TCL_ERROR;
+ }
+ }
+ if (flush == -1) {
+ flush = 0;
+ }
+
+ /*
+ * Set the compression dictionary if requested.
+ */
+
+ if (compDictObj != NULL) {
+ int len;
+
+ (void) Tcl_GetByteArrayFromObj(compDictObj, &len);
+ if (len == 0) {
+ compDictObj = NULL;
+ }
+ Tcl_ZlibStreamSetCompressionDictionary(zstream, compDictObj);
+ }
+
+ /*
+ * Send the data to the stream core, along with any flushing directive.
+ */
+
+ return Tcl_ZlibStreamPut(zstream, objv[objc-1], flush);
+}
+
+static int
+ZlibStreamHeaderCmd(
+ ClientData cd,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ ZlibStreamHandle *zshPtr = cd;
+ Tcl_Obj *resultObj;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if (zshPtr->mode != TCL_ZLIB_STREAM_INFLATE
+ || zshPtr->format != TCL_ZLIB_FORMAT_GZIP) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "only gunzip streams can produce header information", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ZIP", "BADOP", NULL);
+ return TCL_ERROR;
+ }
+
+ TclNewObj(resultObj);
+ ExtractHeader(&zshPtr->gzHeaderPtr->header, resultObj);
+ Tcl_SetObjResult(interp, resultObj);
+ return TCL_OK;
+}
/*
*----------------------------------------------------------------------
* Set of functions to support channel stacking.
*----------------------------------------------------------------------
+ *
+ * ZlibTransformClose --
+ *
+ * How to shut down a stacked compressing/decompressing transform.
+ *
+ *----------------------------------------------------------------------
*/
static int
@@ -2277,7 +2866,7 @@ ZlibTransformClose(
* Delete the support timer.
*/
- ZlibTransformTimerKill(cd);
+ ZlibTransformEventTimerKill(cd);
/*
* Flush any data waiting to be compressed.
@@ -2292,7 +2881,7 @@ ZlibTransformClose(
if (e != Z_OK && e != Z_STREAM_END) {
/* TODO: is this the right way to do errors on close? */
if (!TclInThreadExit()) {
- ConvertError(interp, e);
+ ConvertError(interp, e, cd->outStream.adler);
}
result = TCL_ERROR;
break;
@@ -2303,12 +2892,10 @@ ZlibTransformClose(
/* TODO: is this the right way to do errors on close?
* Note: when close is called from FinalizeIOSubsystem
* then interp may be NULL */
- if (!TclInThreadExit()) {
- if (interp) {
- Tcl_AppendResult(interp,
- "error while finalizing file: ",
- Tcl_PosixError(interp), NULL);
- }
+ if (!TclInThreadExit() && interp) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error while finalizing file: %s",
+ Tcl_PosixError(interp)));
}
result = TCL_ERROR;
break;
@@ -2324,6 +2911,8 @@ ZlibTransformClose(
* Release all memory.
*/
+ Tcl_DStringFree(&cd->decompressed);
+
if (cd->inBuffer) {
ckfree(cd->inBuffer);
cd->inBuffer = NULL;
@@ -2335,6 +2924,16 @@ ZlibTransformClose(
ckfree(cd);
return result;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformInput --
+ *
+ * Reader filter that does decompression.
+ *
+ *----------------------------------------------------------------------
+ */
static int
ZlibTransformInput(
@@ -2346,78 +2945,144 @@ ZlibTransformInput(
ZlibChannelData *cd = instanceData;
Tcl_DriverInputProc *inProc =
Tcl_ChannelInputProc(Tcl_GetChannelType(cd->parent));
- int e, readBytes, flush = Z_NO_FLUSH;
+ int readBytes, gotBytes, copied;
if (cd->mode == TCL_ZLIB_STREAM_DEFLATE) {
return inProc(Tcl_GetChannelInstanceData(cd->parent), buf, toRead,
errorCodePtr);
}
- cd->inStream.next_out = (Bytef *) buf;
- cd->inStream.avail_out = toRead;
- if (cd->inStream.next_in == NULL) {
- goto doReadFirst;
- }
- while (1) {
- e = inflate(&cd->inStream, flush);
- if ((e == Z_STREAM_END) || (e==Z_OK && cd->inStream.avail_out==0)) {
- return toRead - cd->inStream.avail_out;
- }
-
+ gotBytes = 0;
+ while (toRead > 0) {
/*
- * Z_BUF_ERROR can be ignored as per http://www.zlib.net/zlib_how.html
- *
- * Just indicates that the zlib couldn't consume input/produce output,
- * and is fixed by supplying more input.
+ * Loop until the request is satisfied (or no data available from
+ * below, possibly EOF).
*/
- if ((e != Z_OK) && (e != Z_BUF_ERROR)) {
- Tcl_Obj *errObj = Tcl_NewListObj(0, NULL);
+ copied = ResultCopy(cd, buf, toRead);
+ toRead -= copied;
+ buf += copied;
+ gotBytes += copied;
- Tcl_ListObjAppendElement(NULL, errObj,
- Tcl_NewStringObj(cd->inStream.msg, -1));
- Tcl_SetChannelError(cd->parent, errObj);
- *errorCodePtr = EINVAL;
- return -1;
+ if (toRead == 0) {
+ return gotBytes;
}
/*
- * Check if the inflate stopped early.
+ * The buffer is exhausted, but the caller wants even more. We now
+ * have to go to the underlying channel, get more bytes and then
+ * transform them for delivery. We may not get what we want (full EOF
+ * or temporarily out of data).
+ *
+ * Length (cd->decompressed) == 0, toRead > 0 here.
+ *
+ * The zlib transform allows us to read at most one character from the
+ * underlying channel to properly identify Z_STREAM_END without
+ * reading over the border.
*/
- if (cd->inStream.avail_in > 0) {
- continue;
- }
+ readBytes = Tcl_ReadRaw(cd->parent, cd->inBuffer, cd->readAheadLimit);
/*
- * Emptied the buffer of data from the underlying channel. Get some
- * more.
+ * Three cases here:
+ * 1. Got some data from the underlying channel (readBytes > 0) so
+ * it should be fed through the decompression engine.
+ * 2. Got an error (readBytes < 0) which we should report up except
+ * for the case where we can convert it to a short read.
+ * 3. Got an end-of-data from EOF or blocking (readBytes == 0). If
+ * it is EOF, try flushing the data out of the decompressor.
*/
- doReadFirst:
- /*
- * Hack for Bug 2762041. Disable pre-reading of lots of input, read
- * only one character. This way the Z_END_OF_STREAM can be read
- * without triggering an EOF in the base channel. The higher input
- * loops in DoReadChars() would react to that by stopping, despite the
- * transform still having data which could be read.
- *
- * This is only a hack because other transforms may not be able to
- * work around the general problem in this way.
- */
-
- readBytes = Tcl_ReadRaw(cd->parent, cd->inBuffer, 1);
if (readBytes < 0) {
+ /*
+ * Report errors to caller. The state of the seek system is
+ * unchanged!
+ */
+
+ if ((Tcl_GetErrno() == EAGAIN) && (gotBytes > 0)) {
+ /*
+ * EAGAIN is a special situation. If we had some data before
+ * we report that instead of the request to re-try.
+ */
+
+ return gotBytes;
+ }
+
*errorCodePtr = Tcl_GetErrno();
return -1;
} else if (readBytes == 0) {
- flush = Z_SYNC_FLUSH;
- }
+ /*
+ * Check wether we hit on EOF in 'parent' or not. If not,
+ * differentiate between blocking and non-blocking modes. In
+ * non-blocking mode we ran temporarily out of data. Signal this
+ * to the caller via EWOULDBLOCK and error return (-1). In the
+ * other cases we simply return what we got and let the caller
+ * wait for more. On the other hand, if we got an EOF we have to
+ * convert and flush all waiting partial data.
+ */
+
+ if (!Tcl_Eof(cd->parent)) {
+ /*
+ * The state of the seek system is unchanged!
+ */
- cd->inStream.next_in = (Bytef *) cd->inBuffer;
- cd->inStream.avail_in = readBytes;
+ if ((gotBytes == 0) && (cd->flags & ASYNC)) {
+ *errorCodePtr = EWOULDBLOCK;
+ return -1;
+ }
+ return gotBytes;
+ }
+
+ /*
+ * (Semi-)Eof in parent.
+ *
+ * Now this is a bit different. The partial data waiting is
+ * converted and returned.
+ */
+
+ if (ResultGenerate(cd, 0, Z_SYNC_FLUSH, errorCodePtr) != TCL_OK) {
+ return -1;
+ }
+
+ if (Tcl_DStringLength(&cd->decompressed) == 0) {
+ /*
+ * The drain delivered nothing. Time to deliver what we've
+ * got.
+ */
+
+ return gotBytes;
+ }
+
+ /*
+ * Reset eof, force caller to drain result buffer.
+ */
+
+ ((Channel *) cd->parent)->state->flags &= ~CHANNEL_EOF;
+ } else /* readBytes > 0 */ {
+ /*
+ * Transform the read chunk, which was not empty. Anything we get
+ * back is a transformation result to be put into our buffers, and
+ * the next iteration will put it into the result.
+ */
+
+ if (ResultGenerate(cd, readBytes, Z_NO_FLUSH,
+ errorCodePtr) != TCL_OK) {
+ return -1;
+ }
+ }
}
+ return gotBytes;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformOutput --
+ *
+ * Writer filter that does compression.
+ *
+ *----------------------------------------------------------------------
+ */
static int
ZlibTransformOutput(
@@ -2430,6 +3095,7 @@ ZlibTransformOutput(
Tcl_DriverOutputProc *outProc =
Tcl_ChannelOutputProc(Tcl_GetChannelType(cd->parent));
int e, produced;
+ Tcl_Obj *errObj;
if (cd->mode == TCL_ZLIB_STREAM_INFLATE) {
return outProc(Tcl_GetChannelInstanceData(cd->parent), buf, toWrite,
@@ -2445,7 +3111,7 @@ ZlibTransformOutput(
e = deflate(&cd->outStream, Z_NO_FLUSH);
produced = cd->outAllocated - cd->outStream.avail_out;
- if (e == Z_OK && cd->outStream.avail_out > 0) {
+ if (e == Z_OK && produced > 0) {
if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) < 0) {
*errorCodePtr = Tcl_GetErrno();
return -1;
@@ -2453,15 +3119,30 @@ ZlibTransformOutput(
}
} while (e == Z_OK && produced > 0 && cd->outStream.avail_in > 0);
- if (e != Z_OK) {
- Tcl_SetChannelError(cd->parent,
- Tcl_NewStringObj(cd->outStream.msg, -1));
- *errorCodePtr = EINVAL;
- return -1;
+ if (e == Z_OK) {
+ return toWrite - cd->outStream.avail_in;
}
- return toWrite - cd->outStream.avail_in;
+ errObj = Tcl_NewListObj(0, NULL);
+ Tcl_ListObjAppendElement(NULL, errObj, Tcl_NewStringObj("-errorcode",-1));
+ Tcl_ListObjAppendElement(NULL, errObj,
+ ConvertErrorToList(e, cd->outStream.adler));
+ Tcl_ListObjAppendElement(NULL, errObj,
+ Tcl_NewStringObj(cd->outStream.msg, -1));
+ Tcl_SetChannelError(cd->parent, errObj);
+ *errorCodePtr = EINVAL;
+ return -1;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformSetOption --
+ *
+ * Writing side of [fconfigure] on our channel.
+ *
+ *----------------------------------------------------------------------
+ */
static int
ZlibTransformSetOption( /* not used */
@@ -2473,59 +3154,133 @@ ZlibTransformSetOption( /* not used */
ZlibChannelData *cd = instanceData;
Tcl_DriverSetOptionProc *setOptionProc =
Tcl_ChannelSetOptionProc(Tcl_GetChannelType(cd->parent));
- static const char *chanOptions = "flush";
+ static const char *compressChanOptions = "dictionary flush";
+ static const char *gzipChanOptions = "flush";
+ static const char *decompressChanOptions = "dictionary limit";
+ static const char *gunzipChanOptions = "flush limit";
int haveFlushOpt = (cd->mode == TCL_ZLIB_STREAM_DEFLATE);
- if (haveFlushOpt && optionName && strcmp(optionName, "-flush") == 0) {
- int flushType;
+ if (optionName && (strcmp(optionName, "-dictionary") == 0)
+ && (cd->format != TCL_ZLIB_FORMAT_GZIP)) {
+ Tcl_Obj *compDictObj;
+ int code;
- if (value[0] == 'f' && strcmp(value, "full") == 0) {
- flushType = Z_FULL_FLUSH;
- } else if (value[0] == 's' && strcmp(value, "sync") == 0) {
- flushType = Z_SYNC_FLUSH;
- } else {
- Tcl_AppendResult(interp, "unknown -flush type \"", value,
- "\": must be full or sync", NULL);
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "FLUSH", NULL);
- return TCL_ERROR;
+ TclNewStringObj(compDictObj, value, strlen(value));
+ Tcl_IncrRefCount(compDictObj);
+ (void) Tcl_GetByteArrayFromObj(compDictObj, NULL);
+ if (cd->compDictObj) {
+ TclDecrRefCount(cd->compDictObj);
}
+ cd->compDictObj = compDictObj;
+ code = Z_OK;
+ if (cd->mode == TCL_ZLIB_STREAM_DEFLATE) {
+ code = SetDeflateDictionary(&cd->outStream, compDictObj);
+ if (code != Z_OK) {
+ ConvertError(interp, code, cd->outStream.adler);
+ return TCL_ERROR;
+ }
+ } else if (cd->format == TCL_ZLIB_FORMAT_RAW) {
+ code = SetInflateDictionary(&cd->inStream, compDictObj);
+ if (code != Z_OK) {
+ ConvertError(interp, code, cd->inStream.adler);
+ return TCL_ERROR;
+ }
+ }
+ return TCL_OK;
+ }
- /*
- * Try to actually do the flush now.
- */
-
- cd->outStream.avail_in = 0;
- do {
- int e;
-
- cd->outStream.next_out = (Bytef *) cd->outBuffer;
- cd->outStream.avail_out = cd->outAllocated;
+ if (haveFlushOpt) {
+ if (optionName && strcmp(optionName, "-flush") == 0) {
+ int flushType;
- e = deflate(&cd->outStream, flushType);
- if (e != Z_OK) {
- ConvertError(interp, e);
+ if (value[0] == 'f' && strcmp(value, "full") == 0) {
+ flushType = Z_FULL_FLUSH;
+ } else if (value[0] == 's' && strcmp(value, "sync") == 0) {
+ flushType = Z_SYNC_FLUSH;
+ } else {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown -flush type \"%s\": must be full or sync",
+ value));
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "FLUSH", NULL);
return TCL_ERROR;
}
- if (cd->outStream.avail_out > 0) {
+ /*
+ * Try to actually do the flush now.
+ */
+
+ cd->outStream.avail_in = 0;
+ while (1) {
+ int e;
+
+ cd->outStream.next_out = (Bytef *) cd->outBuffer;
+ cd->outStream.avail_out = cd->outAllocated;
+
+ e = deflate(&cd->outStream, flushType);
+ if (e == Z_BUF_ERROR) {
+ break;
+ } else if (e != Z_OK) {
+ ConvertError(interp, e, cd->outStream.adler);
+ return TCL_ERROR;
+ } else if (cd->outStream.avail_out == 0) {
+ break;
+ }
+
if (Tcl_WriteRaw(cd->parent, cd->outBuffer,
- PTR2INT(cd->outStream.next_out)) < 0) {
- Tcl_AppendResult(interp, "problem flushing channel: ",
- Tcl_PosixError(interp), NULL);
+ cd->outStream.next_out - (Bytef *) cd->outBuffer)<0) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "problem flushing channel: %s",
+ Tcl_PosixError(interp)));
return TCL_ERROR;
}
}
- } while (cd->outStream.avail_out > 0);
- return TCL_OK;
+ return TCL_OK;
+ }
+ } else {
+ if (optionName && strcmp(optionName, "-limit") == 0) {
+ int newLimit;
+
+ if (Tcl_GetInt(interp, value, &newLimit) != TCL_OK) {
+ return TCL_ERROR;
+ } else if (newLimit < 1 || newLimit > MAX_BUFFER_SIZE) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "-limit must be between 1 and 65536", -1));
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "READLIMIT", NULL);
+ return TCL_ERROR;
+ }
+ }
}
if (setOptionProc == NULL) {
- return Tcl_BadChannelOption(interp, optionName, chanOptions);
+ if (cd->format == TCL_ZLIB_FORMAT_GZIP) {
+ return Tcl_BadChannelOption(interp, optionName,
+ (cd->mode == TCL_ZLIB_STREAM_DEFLATE)
+ ? gzipChanOptions : gunzipChanOptions);
+ } else {
+ return Tcl_BadChannelOption(interp, optionName,
+ (cd->mode == TCL_ZLIB_STREAM_DEFLATE)
+ ? compressChanOptions : decompressChanOptions);
+ }
}
+ /*
+ * Pass all unknown options down, to deeper transforms and/or the base
+ * channel.
+ */
+
return setOptionProc(Tcl_GetChannelInstanceData(cd->parent), interp,
optionName, value);
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformGetOption --
+ *
+ * Reading side of [fconfigure] on our channel.
+ *
+ *----------------------------------------------------------------------
+ */
static int
ZlibTransformGetOption(
@@ -2537,7 +3292,10 @@ ZlibTransformGetOption(
ZlibChannelData *cd = instanceData;
Tcl_DriverGetOptionProc *getOptionProc =
Tcl_ChannelGetOptionProc(Tcl_GetChannelType(cd->parent));
- static const char *chanOptions = "checksum header";
+ static const char *compressChanOptions = "checksum dictionary";
+ static const char *gzipChanOptions = "checksum";
+ static const char *decompressChanOptions = "checksum dictionary limit";
+ static const char *gunzipChanOptions = "checksum header limit";
/*
* The "crc" option reports the current CRC (calculated with the Adler32
@@ -2565,6 +3323,28 @@ ZlibTransformGetOption(
}
}
+ if ((cd->format != TCL_ZLIB_FORMAT_GZIP) &&
+ (optionName == NULL || strcmp(optionName, "-dictionary") == 0)) {
+ /*
+ * Embedded NUL bytes are ok; they'll be C080-encoded.
+ */
+
+ if (optionName == NULL) {
+ Tcl_DStringAppendElement(dsPtr, "-dictionary");
+ if (cd->compDictObj) {
+ Tcl_DStringAppendElement(dsPtr,
+ Tcl_GetString(cd->compDictObj));
+ } else {
+ Tcl_DStringAppendElement(dsPtr, "");
+ }
+ } else {
+ int len;
+ const char *str = Tcl_GetStringFromObj(cd->compDictObj, &len);
+
+ Tcl_DStringAppend(dsPtr, str, len);
+ }
+ }
+
/*
* The "header" option, which is only valid on inflating gzip channels,
* reports the header that has been read from the start of the stream.
@@ -2580,10 +3360,7 @@ ZlibTransformGetOption(
Tcl_DStringAppendElement(dsPtr, Tcl_GetString(tmpObj));
Tcl_DecrRefCount(tmpObj);
} else {
- int len;
- const char *str = Tcl_GetStringFromObj(tmpObj, &len);
-
- Tcl_DStringAppend(dsPtr, str, len);
+ TclDStringAppendObj(dsPtr, tmpObj);
Tcl_DecrRefCount(tmpObj);
return TCL_OK;
}
@@ -2600,8 +3377,27 @@ ZlibTransformGetOption(
if (optionName == NULL) {
return TCL_OK;
}
- return Tcl_BadChannelOption(interp, optionName, chanOptions);
+ if (cd->format == TCL_ZLIB_FORMAT_GZIP) {
+ return Tcl_BadChannelOption(interp, optionName,
+ (cd->mode == TCL_ZLIB_STREAM_DEFLATE)
+ ? gzipChanOptions : gunzipChanOptions);
+ } else {
+ return Tcl_BadChannelOption(interp, optionName,
+ (cd->mode == TCL_ZLIB_STREAM_DEFLATE)
+ ? compressChanOptions : decompressChanOptions);
+ }
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformWatch, ZlibTransformEventHandler --
+ *
+ * If we have data pending, trigger a readable event after a short time
+ * (in order to allow a real event to catch up).
+ *
+ *----------------------------------------------------------------------
+ */
static void
ZlibTransformWatch(
@@ -2617,63 +3413,28 @@ ZlibTransformWatch(
watchProc = Tcl_ChannelWatchProc(Tcl_GetChannelType(cd->parent));
watchProc(Tcl_GetChannelInstanceData(cd->parent), mask);
- if (!(mask & TCL_READABLE)
- || (cd->inStream.avail_in == (uInt) cd->inAllocated)) {
- ZlibTransformTimerKill(cd);
- } else {
- ZlibTransformTimerSetup(cd);
- }
-}
-static int
-ZlibTransformGetHandle(
- ClientData instanceData,
- int direction,
- ClientData *handlePtr)
-{
- ZlibChannelData *cd = instanceData;
-
- return Tcl_GetChannelHandle(cd->parent, direction, handlePtr);
-}
-
-static int
-ZlibTransformBlockMode(
- ClientData instanceData,
- int mode)
-{
- ZlibChannelData *cd = instanceData;
-
- if (mode == TCL_MODE_NONBLOCKING) {
- cd->flags |= ASYNC;
- } else {
- cd->flags &= ~ASYNC;
+ if (!(mask & TCL_READABLE) || Tcl_DStringLength(&cd->decompressed) == 0) {
+ ZlibTransformEventTimerKill(cd);
+ } else if (cd->timer == NULL) {
+ cd->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
+ ZlibTransformTimerRun, cd);
}
- return TCL_OK;
}
static int
-ZlibTransformHandler(
+ZlibTransformEventHandler(
ClientData instanceData,
int interestMask)
{
ZlibChannelData *cd = instanceData;
- ZlibTransformTimerKill(cd);
+ ZlibTransformEventTimerKill(cd);
return interestMask;
}
-static void
-ZlibTransformTimerSetup(
- ZlibChannelData *cd)
-{
- if (cd->timer == NULL) {
- cd->timer = Tcl_CreateTimerHandler(TRANSFORM_FLUSH_DELAY,
- ZlibTransformTimerRun, cd);
- }
-}
-
-static void
-ZlibTransformTimerKill(
+static inline void
+ZlibTransformEventTimerKill(
ZlibChannelData *cd)
{
if (cd->timer != NULL) {
@@ -2695,6 +3456,53 @@ ZlibTransformTimerRun(
/*
*----------------------------------------------------------------------
*
+ * ZlibTransformGetHandle --
+ *
+ * Anything that needs the OS handle is told to get it from what we are
+ * stacked on top of.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibTransformGetHandle(
+ ClientData instanceData,
+ int direction,
+ ClientData *handlePtr)
+{
+ ZlibChannelData *cd = instanceData;
+
+ return Tcl_GetChannelHandle(cd->parent, direction, handlePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformBlockMode --
+ *
+ * We need to keep track of the blocking mode; it changes our behavior.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibTransformBlockMode(
+ ClientData instanceData,
+ int mode)
+{
+ ZlibChannelData *cd = instanceData;
+
+ if (mode == TCL_MODE_NONBLOCKING) {
+ cd->flags |= ASYNC;
+ } else {
+ cd->flags &= ~ASYNC;
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* ZlibStackChannelTransform --
*
* Stacks either compression or decompression onto a channel.
@@ -2722,10 +3530,15 @@ ZlibStackChannelTransform(
* decompressing transforms. */
int level, /* What compression level to use. Ignored for
* decompressing transforms. */
+ int limit, /* The limit on the number of bytes to read
+ * ahead; always at least 1. */
Tcl_Channel channel, /* The channel to attach to. */
- Tcl_Obj *gzipHeaderDictPtr) /* A description of header to use, or NULL to
+ Tcl_Obj *gzipHeaderDictPtr, /* A description of header to use, or NULL to
* use a default. Ignored if not compressing
* to produce gzip-format data. */
+ Tcl_Obj *compDictObj) /* Byte-array object containing compression
+ * dictionary (not dictObj!) to use if
+ * necessary. */
{
ZlibChannelData *cd = ckalloc(sizeof(ZlibChannelData));
Tcl_Channel chan;
@@ -2738,15 +3551,15 @@ ZlibStackChannelTransform(
memset(cd, 0, sizeof(ZlibChannelData));
cd->mode = mode;
+ cd->format = format;
+ cd->readAheadLimit = limit;
if (format == TCL_ZLIB_FORMAT_GZIP || format == TCL_ZLIB_FORMAT_AUTO) {
if (mode == TCL_ZLIB_STREAM_DEFLATE) {
if (gzipHeaderDictPtr) {
- int dummy = 0;
-
cd->flags |= OUT_HEADER;
if (GenerateHeader(interp, gzipHeaderDictPtr, &cd->outHeader,
- &dummy) != TCL_OK) {
+ NULL) != TCL_OK) {
goto error;
}
}
@@ -2761,6 +3574,12 @@ ZlibStackChannelTransform(
}
}
+ if (compDictObj != NULL) {
+ cd->compDictObj = Tcl_DuplicateObj(compDictObj);
+ Tcl_IncrRefCount(cd->compDictObj);
+ Tcl_GetByteArrayFromObj(cd->compDictObj, NULL);
+ }
+
if (format == TCL_ZLIB_FORMAT_RAW) {
wbits = WBITS_RAW;
} else if (format == TCL_ZLIB_FORMAT_ZLIB) {
@@ -2790,6 +3609,14 @@ ZlibStackChannelTransform(
goto error;
}
}
+ if (cd->format == TCL_ZLIB_FORMAT_RAW && cd->compDictObj) {
+ e = SetInflateDictionary(&cd->inStream, cd->compDictObj);
+ if (e != Z_OK) {
+ goto error;
+ }
+ TclDecrRefCount(cd->compDictObj);
+ cd->compDictObj = NULL;
+ }
} else {
e = deflateInit2(&cd->outStream, level, Z_DEFLATED, wbits,
MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
@@ -2804,8 +3631,16 @@ ZlibStackChannelTransform(
goto error;
}
}
+ if (cd->compDictObj) {
+ e = SetDeflateDictionary(&cd->outStream, cd->compDictObj);
+ if (e != Z_OK) {
+ goto error;
+ }
+ }
}
+ Tcl_DStringInit(&cd->decompressed);
+
chan = Tcl_StackChannel(interp, &zlibChannelType, cd,
Tcl_GetChannelMode(channel), channel);
if (chan == NULL) {
@@ -2825,12 +3660,177 @@ ZlibStackChannelTransform(
ckfree(cd->outBuffer);
deflateEnd(&cd->outStream);
}
+ if (cd->compDictObj) {
+ Tcl_DecrRefCount(cd->compDictObj);
+ }
ckfree(cd);
return NULL;
}
/*
*----------------------------------------------------------------------
+ *
+ * ResultCopy --
+ *
+ * Copies the requested number of bytes from the buffer into the
+ * specified array and removes them from the buffer afterward. Copies
+ * less if there is not enough data in the buffer.
+ *
+ * Side effects:
+ * See above.
+ *
+ * Result:
+ * The number of actually copied bytes, possibly less than 'toRead'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline int
+ResultCopy(
+ ZlibChannelData *cd, /* The location of the buffer to read from. */
+ char *buf, /* The buffer to copy into */
+ int toRead) /* Number of requested bytes */
+{
+ int have = Tcl_DStringLength(&cd->decompressed);
+
+ if (have == 0) {
+ /*
+ * Nothing to copy in the case of an empty buffer.
+ */
+
+ return 0;
+ } else if (have > toRead) {
+ /*
+ * The internal buffer contains more than requested. Copy the
+ * requested subset to the caller, shift the remaining bytes down, and
+ * truncate.
+ */
+
+ char *src = Tcl_DStringValue(&cd->decompressed);
+
+ memcpy(buf, src, toRead);
+ memmove(src, src + toRead, have - toRead);
+
+ Tcl_DStringSetLength(&cd->decompressed, have - toRead);
+ return toRead;
+ } else /* have <= toRead */ {
+ /*
+ * There is just or not enough in the buffer to fully satisfy the
+ * caller, so take everything as best effort.
+ */
+
+ memcpy(buf, Tcl_DStringValue(&cd->decompressed), have);
+ TclDStringClear(&cd->decompressed);
+ return have;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ResultGenerate --
+ *
+ * Extract uncompressed bytes from the compression engine and store them
+ * in our working buffer.
+ *
+ * Result:
+ * TCL_OK/TCL_ERROR (with *errorCodePtr updated with reason).
+ *
+ * Side effects:
+ * See above.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ResultGenerate(
+ ZlibChannelData *cd,
+ int n,
+ int flush,
+ int *errorCodePtr)
+{
+#define MAXBUF 1024
+ unsigned char buf[MAXBUF];
+ int e, written;
+ Tcl_Obj *errObj;
+
+ cd->inStream.next_in = (Bytef *) cd->inBuffer;
+ cd->inStream.avail_in = n;
+
+ while (1) {
+ cd->inStream.next_out = (Bytef *) buf;
+ cd->inStream.avail_out = MAXBUF;
+
+ e = inflate(&cd->inStream, flush);
+ if (e == Z_NEED_DICT && cd->compDictObj) {
+ e = SetInflateDictionary(&cd->inStream, cd->compDictObj);
+ if (e == Z_OK) {
+ /*
+ * A repetition of Z_NEED_DICT is just an error.
+ */
+
+ cd->inStream.next_out = (Bytef *) buf;
+ cd->inStream.avail_out = MAXBUF;
+ e = inflate(&cd->inStream, flush);
+ }
+ }
+
+ /*
+ * avail_out is now the left over space in the output. Therefore
+ * "MAXBUF - avail_out" is the amount of bytes generated.
+ */
+
+ written = MAXBUF - cd->inStream.avail_out;
+ if (written) {
+ Tcl_DStringAppend(&cd->decompressed, (char *) buf, written);
+ }
+
+ /*
+ * The cases where we're definitely done.
+ */
+
+ if (((flush == Z_SYNC_FLUSH) && (e == Z_BUF_ERROR))
+ || (e == Z_STREAM_END)
+ || (e == Z_OK && cd->inStream.avail_out == 0)) {
+ return TCL_OK;
+ }
+
+ /*
+ * Z_BUF_ERROR can be ignored as per http://www.zlib.net/zlib_how.html
+ *
+ * Just indicates that the zlib couldn't consume input/produce output,
+ * and is fixed by supplying more input.
+ *
+ * Otherwise, we've got errors and need to report to higher-up.
+ */
+
+ if ((e != Z_OK) && (e != Z_BUF_ERROR)) {
+ goto handleError;
+ }
+
+ /*
+ * Check if the inflate stopped early.
+ */
+
+ if (cd->inStream.avail_in <= 0 && flush != Z_SYNC_FLUSH) {
+ return TCL_OK;
+ }
+ }
+
+ handleError:
+ errObj = Tcl_NewListObj(0, NULL);
+ Tcl_ListObjAppendElement(NULL, errObj, Tcl_NewStringObj("-errorcode",-1));
+ Tcl_ListObjAppendElement(NULL, errObj,
+ ConvertErrorToList(e, cd->inStream.adler));
+ Tcl_ListObjAppendElement(NULL, errObj,
+ Tcl_NewStringObj(cd->inStream.msg, -1));
+ Tcl_SetChannelError(cd->parent, errObj);
+ *errorCodePtr = EINVAL;
+ return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
* Finally, the TclZlibInit function. Used to install the zlib API.
*----------------------------------------------------------------------
*/
@@ -2839,6 +3839,8 @@ int
TclZlibInit(
Tcl_Interp *interp)
{
+ Tcl_Config cfg[2];
+
/*
* This does two things. It creates a counter used in the creation of
* stream commands, and it creates the namespace that will contain those
@@ -2852,7 +3854,24 @@ TclZlibInit(
*/
Tcl_CreateObjCommand(interp, "zlib", ZlibCmd, 0, 0);
- return TCL_OK;
+
+ /*
+ * Store the underlying configuration information.
+ *
+ * TODO: Describe whether we're using the system version of the library or
+ * a compatibility version built into Tcl?
+ */
+
+ cfg[0].key = "zlibVersion";
+ cfg[0].value = zlibVersion();
+ cfg[1].key = NULL;
+ Tcl_RegisterConfig(interp, "zlib", cfg, "iso8859-1");
+
+ /*
+ * Formally provide the package as a Tcl built-in.
+ */
+
+ return Tcl_PkgProvide(interp, "zlib", TCL_ZLIB_VERSION);
}
/*
@@ -2872,8 +3891,10 @@ Tcl_ZlibStreamInit(
Tcl_Obj *dictObj,
Tcl_ZlibStream *zshandle)
{
- Tcl_SetResult(interp, "unimplemented", TCL_STATIC);
- Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL);
+ if (interp) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1));
+ Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL);
+ }
return TCL_ERROR;
}
@@ -2938,8 +3959,10 @@ Tcl_ZlibDeflate(
int level,
Tcl_Obj *gzipHeaderDictObj)
{
- Tcl_SetResult(interp, "unimplemented", TCL_STATIC);
- Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL);
+ if (interp) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1));
+ Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL);
+ }
return TCL_ERROR;
}
@@ -2951,8 +3974,10 @@ Tcl_ZlibInflate(
int bufferSize,
Tcl_Obj *gzipHeaderDictObj)
{
- Tcl_SetResult(interp, "unimplemented", TCL_STATIC);
- Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL);
+ if (interp) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1));
+ Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL);
+ }
return TCL_ERROR;
}
@@ -2973,6 +3998,14 @@ Tcl_ZlibAdler32(
{
return 0;
}
+
+void
+Tcl_ZlibStreamSetCompressionDictionary(
+ Tcl_ZlibStream zshandle,
+ Tcl_Obj *compressionDictionaryObj)
+{
+ /* Do nothing. */
+}
#endif /* HAVE_ZLIB */
/*
diff --git a/library/auto.tcl b/library/auto.tcl
index 4bd860d..02edcc4 100644
--- a/library/auto.tcl
+++ b/library/auto.tcl
@@ -20,8 +20,9 @@
# None.
proc auto_reset {} {
- if {[array exists ::auto_index]} {
- foreach cmdName [array names ::auto_index] {
+ global auto_execs auto_index auto_path
+ if {[array exists auto_index]} {
+ foreach cmdName [array names auto_index] {
set fqcn [namespace which $cmdName]
if {$fqcn eq ""} {
continue
@@ -29,11 +30,11 @@ proc auto_reset {} {
rename $fqcn {}
}
}
- unset -nocomplain ::auto_execs ::auto_index ::tcl::auto_oldpath
- if {[catch {llength $::auto_path}]} {
- set ::auto_path [list [info library]]
- } elseif {[info library] ni $::auto_path} {
- lappend ::auto_path [info library]
+ unset -nocomplain auto_execs auto_index ::tcl::auto_oldpath
+ if {[catch {llength $auto_path}]} {
+ set auto_path [list [info library]]
+ } elseif {[info library] ni $auto_path} {
+ lappend auto_path [info library]
}
}
@@ -53,7 +54,7 @@ proc auto_reset {} {
proc tcl_findLibrary {basename version patch initScript enVarName varName} {
upvar #0 $varName the_library
- global env
+ global auto_path env tcl_platform
set dirs {}
set errors {}
@@ -83,12 +84,10 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} {
# 3. Relative to auto_path directories. This checks relative to the
# Tcl library as well as allowing loading of libraries added to the
# auto_path that is not relative to the core library or binary paths.
- foreach d $::auto_path {
+ foreach d $auto_path {
lappend dirs [file join $d $basename$version]
- if {
- $::tcl_platform(platform) eq "unix"
- && $::tcl_platform(os) eq "Darwin"
- } then {
+ if {$tcl_platform(platform) eq "unix"
+ && $tcl_platform(os) eq "Darwin"} {
# 4. On MacOSX, check the Resources/Scripts subdir too
lappend dirs [file join $d $basename$version Resources Scripts]
}
@@ -514,6 +513,32 @@ proc auto_mkindex_parser::fullname {name} {
return [string map [list \0 \$] $name]
}
+# auto_mkindex_parser::indexEntry --
+#
+# Used by commands like "proc" within the auto_mkindex parser to add a
+# correctly-quoted entry to the index. This is shared code so it is done
+# *right*, in one place.
+#
+# Arguments:
+# name - Name that is being added to index.
+
+proc auto_mkindex_parser::indexEntry {name} {
+ variable index
+ variable scriptFile
+
+ # We convert all metacharacters to their backslashed form, and pre-split
+ # the file name that we know about (which will be a proper list, and so
+ # correctly quoted).
+
+ set name [string range [list \}[fullname $name]] 2 end]
+ set filenameParts [file split $scriptFile]
+
+ append index [format \
+ {set auto_index(%s) [list source [file join $dir %s]]%s} \
+ $name $filenameParts \n]
+ return
+}
+
if {[llength $::auto_mkindex_parser::initCommands]} {
return
}
@@ -525,15 +550,7 @@ if {[llength $::auto_mkindex_parser::initCommands]} {
# Adds an entry to the auto index list for the given procedure name.
auto_mkindex_parser::command proc {name args} {
- variable index
- variable scriptFile
- # Do some fancy reformatting on the "source" call to handle platform
- # differences with respect to pathnames. Use format just so that the
- # command is a little easier to read (otherwise it'd be full of
- # backslashed dollar signs, etc.
- append index [list set auto_index([fullname $name])] \
- [format { [list source [file join $dir %s]]} \
- [file split $scriptFile]] "\n"
+ indexEntry $name
}
# Conditionally add support for Tcl byte code files. There are some tricky
@@ -560,14 +577,7 @@ auto_mkindex_parser::hook {
# procedure name.
auto_mkindex_parser::commandInit tbcload::bcproc {name args} {
- variable index
- variable scriptFile
- # Do some nice reformatting of the "source" call, to get around
- # path differences on different platforms. We use the format
- # command just so that the code is a little easier to read.
- append index [list set auto_index([fullname $name])] \
- [format { [list source [file join $dir %s]]} \
- [file split $scriptFile]] "\n"
+ indexEntry $name
}
}
}
@@ -606,6 +616,35 @@ auto_mkindex_parser::command namespace {op args} {
}
catch {$parser eval "_%@namespace import $args"}
}
+ ensemble {
+ variable parser
+ variable contextStack
+ if {[lindex $args 0] eq "create"} {
+ set name ::[join [lreverse $contextStack] ::]
+ catch {
+ set name [dict get [lrange $args 1 end] -command]
+ if {![string match ::* $name]} {
+ set name ::[join [lreverse $contextStack] ::]$name
+ }
+ regsub -all ::+ $name :: name
+ }
+ # create artifical proc to force an entry in the tclIndex
+ $parser eval [list ::proc $name {} {}]
+ }
+ }
+ }
+}
+
+# AUTO MKINDEX: oo::class create name ?definition?
+# Adds an entry to the auto index list for the given class name.
+auto_mkindex_parser::command oo::class {op name {body ""}} {
+ if {$op eq "create"} {
+ indexEntry $name
+ }
+}
+auto_mkindex_parser::command class {op name {body ""}} {
+ if {$op eq "create"} {
+ indexEntry $name
}
}
diff --git a/library/clock.tcl b/library/clock.tcl
index b6ff359..1e652b4 100644
--- a/library/clock.tcl
+++ b/library/clock.tcl
@@ -324,7 +324,7 @@ proc ::tcl::clock::Initialize {} {
{-10800 0 3600 0 2 0 2 2 0 0 0 0 10 0 3 2 0 0 0} :America/Sao_Paulo
{-10800 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Godthab
{-10800 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :America/Buenos_Aires
- {-10800 0 3600 0 2 0 5 2 0 0 0 0 11 0 1 2 0 0 0} :America/Brasilia
+ {-10800 0 3600 0 2 0 5 2 0 0 0 0 11 0 1 2 0 0 0} :America/Bahia
{-10800 0 3600 0 3 0 2 2 0 0 0 0 10 0 1 2 0 0 0} :America/Montevideo
{-7200 0 3600 0 9 0 5 2 0 0 0 0 3 0 5 2 0 0 0} :America/Noronha
{-3600 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Atlantic/Azores
@@ -3012,18 +3012,23 @@ proc ::tcl::clock::GetSystemTimeZone {} {
set timezone $result
} elseif {[set result [getenv TZ]] ne {}} {
set timezone $result
- } elseif { [info exists CachedSystemTimeZone] } {
- set timezone $CachedSystemTimeZone
- } elseif { $::tcl_platform(platform) eq {windows} } {
- set timezone [GuessWindowsTimeZone]
- } elseif { [file exists /etc/localtime]
- && ![catch {ReadZoneinfoFile \
- Tcl/Localtime /etc/localtime}] } {
- set timezone :Tcl/Localtime
- } else {
- set timezone :localtime
}
- set CachedSystemTimeZone $timezone
+ if {![info exists timezone]} {
+ # Cache the time zone only if it was detected by one of the
+ # expensive methods.
+ if { [info exists CachedSystemTimeZone] } {
+ set timezone $CachedSystemTimeZone
+ } elseif { $::tcl_platform(platform) eq {windows} } {
+ set timezone [GuessWindowsTimeZone]
+ } elseif { [file exists /etc/localtime]
+ && ![catch {ReadZoneinfoFile \
+ Tcl/Localtime /etc/localtime}] } {
+ set timezone :Tcl/Localtime
+ } else {
+ set timezone :localtime
+ }
+ set CachedSystemTimeZone $timezone
+ }
if { ![dict exists $TimeZoneBad $timezone] } {
dict set TimeZoneBad $timezone [catch {SetupTimeZone $timezone}]
}
@@ -3406,7 +3411,7 @@ proc ::tcl::clock::LoadZoneinfoFile { fileName } {
proc ::tcl::clock::ReadZoneinfoFile {fileName fname} {
variable MINWIDE
variable TZData
- if { ![info exists fname] } {
+ if { ![file exists $fname] } {
return -code error "$fileName not found"
}
@@ -3497,8 +3502,10 @@ proc ::tcl::clock::ReadZoneinfoFile {fileName fname} {
set i 0
set abbrevs {}
foreach a $abbrList {
- dict set abbrevs $i $a
- incr i [expr { [string length $a] + 1 }]
+ for {set j 0} {$j <= [string length $a]} {incr j} {
+ dict set abbrevs $i [string range $a $j end]
+ incr i
+ }
}
# Package up a list of tuples, each of which contains transition time,
@@ -3854,7 +3861,7 @@ proc ::tcl::clock::ProcessPosixTimeZone { z } {
# Put DST in effect in all years from 1916 to 2099.
- for { set y 1916 } { $y < 2099 } { incr y } {
+ for { set y 1916 } { $y < 2100 } { incr y } {
set startTime [DeterminePosixDSTTime $z start $y]
incr startTime [expr { - wide($stdOffset) }]
set endTime [DeterminePosixDSTTime $z end $y]
diff --git a/library/dde/pkgIndex.tcl b/library/dde/pkgIndex.tcl
index 3125ada..4cf73d0 100644
--- a/library/dde/pkgIndex.tcl
+++ b/library/dde/pkgIndex.tcl
@@ -1,7 +1,7 @@
-if {![package vsatisfies [package provide Tcl] 8]} {return}
-if {[string compare $::tcl_platform(platform) windows]} {return}
-if {[info exists ::tcl_platform(debug)]} {
- package ifneeded dde 1.3.2 [list load [file join $dir tcldde13g.dll] dde]
+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]
} else {
- package ifneeded dde 1.3.2 [list load [file join $dir tcldde13.dll] dde]
+ package ifneeded dde 1.4.0 [list load [file join $dir tcldde14.dll] dde]
}
diff --git a/library/encoding/tis-620.enc b/library/encoding/tis-620.enc
index c233be5..c233be5 100755..100644
--- a/library/encoding/tis-620.enc
+++ b/library/encoding/tis-620.enc
diff --git a/library/history.tcl b/library/history.tcl
index fb722c8..51d2404 100644
--- a/library/history.tcl
+++ b/library/history.tcl
@@ -53,7 +53,7 @@ proc ::history {args} {
}
# Tricky stuff needed to make stack and errors come out right!
- tailcall apply {args {tailcall history {*}$args} ::tcl} {*}$args
+ tailcall apply {arglist {tailcall history {*}$arglist} ::tcl} $args
}
# tcl::HistAdd --
diff --git a/library/http/http.tcl b/library/http/http.tcl
index c636458..a6b2bfd 100644
--- a/library/http/http.tcl
+++ b/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.2
+package provide http 2.8.8
namespace eval http {
# Allow resourcing to not clobber existing data
@@ -43,11 +43,11 @@ namespace eval http {
for {set i 0} {$i <= 256} {incr i} {
set c [format %c $i]
if {![string match {[-._~a-zA-Z0-9]} $c]} {
- set map($c) %[format %.2x $i]
+ set map($c) %[format %.2X $i]
}
}
# These are handled specially
- set map(\n) %0d%0a
+ set map(\n) %0D%0A
variable formMap [array get map]
# Create a map for HTTP/1.1 open sockets
@@ -113,7 +113,7 @@ if {[info command http::Log] eq {}} {proc http::Log {args} {}}
proc http::register {proto port command} {
variable urlTypes
- set urlTypes($proto) [list $port $command]
+ set urlTypes([string tolower $proto]) [list $port $command]
}
# http::unregister --
@@ -127,11 +127,12 @@ proc http::register {proto port command} {
proc http::unregister {proto} {
variable urlTypes
- if {![info exists urlTypes($proto)]} {
+ set lower [string tolower $proto]
+ if {![info exists urlTypes($lower)]} {
return -code error "unsupported url type \"$proto\""
}
- set old $urlTypes($proto)
- unset urlTypes($proto)
+ set old $urlTypes($lower)
+ unset urlTypes($lower)
return $old
}
@@ -205,15 +206,13 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} {
if {[info exists state(after)]} {
after cancel $state(after)
}
- if {[info exists state(-command)] && !$skipCB} {
- if {[catch {eval $state(-command) {$token}} err]} {
- if {$errormsg eq ""} {
- set state(error) [list $err $errorInfo $errorCode]
- set state(status) error
- }
+ 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
}
- # Command callback may already have unset our state
- unset -nocomplain state(-command)
}
}
@@ -396,13 +395,16 @@ proc http::geturl {url args} {
# First, before the colon, is the protocol scheme (e.g. http)
# Second, for HTTP-like protocols, is the authority
# The authority is preceded by // and lasts up to (but not including)
- # the following / and it identifies up to four parts, of which only one,
- # the host, is required (if an authority is present at all). All other
- # parts of the authority (user name, password, port number) are optional.
+ # the following / or ? and it identifies up to four parts, of which
+ # only one, the host, is required (if an authority is present at all).
+ # All other parts of the authority (user name, password, port number)
+ # are optional.
# Third is the resource name, which is split into two parts at a ?
# The first part (from the single "/" up to "?") is the path, and the
# second part (from that "?" up to "#") is the query. *HOWEVER*, we do
# not need to separate them; we send the whole lot to the server.
+ # Both, path and query are allowed to be missing, including their
+ # delimiting character.
# Fourth is the fragment identifier, which is everything after the first
# "#" in the URL. The fragment identifier MUST NOT be sent to the server
# and indeed, we don't bother to validate it (it could be an error to
@@ -419,7 +421,6 @@ proc http::geturl {url args} {
# Note that the RE actually combines the user and password parts, as
# recommended in RFC 3986. Indeed, that RFC states that putting passwords
# in URLs is a Really Bad Idea, something with which I would agree utterly.
- # Also note that we do not currently support IPv6 addresses.
#
# From a validation perspective, we need to ensure that the parts of the
# URL that are going to the server are correctly encoded. This is only
@@ -434,10 +435,13 @@ proc http::geturl {url args} {
[^@/\#?]+ # <userinfo part of authority>
) @
)?
- ( [^/:\#?]+ ) # <host part of authority>
+ ( # <host part of authority>
+ [^/:\#?]+ | # host name or IPv4 address
+ \[ [^/\#?]+ \] # IPv6 address in square brackets
+ )
(?: : (\d+) )? # <port part of authority>
)?
- ( / [^\#]*)? # <path> (including query)
+ ( [/\?] [^\#]*)? # <path> (including query)
(?: \# (.*) )? # <fragment>
$
}
@@ -448,6 +452,7 @@ proc http::geturl {url args} {
return -code error "Unsupported URL: $url"
}
# Phase two: validate
+ set host [string trim $host {[]}]; # strip square brackets from IPv6 address
if {$host eq ""} {
# Caller has to provide a host name; we do not have a "default host"
# that would enable us to handle relative URLs.
@@ -480,6 +485,12 @@ proc http::geturl {url args} {
}
}
if {$srvurl ne ""} {
+ # RFC 3986 allows empty paths (not even a /), but servers
+ # return 400 if the path in the HTTP request doesn't start
+ # with / , so add it here if needed.
+ if {[string index $srvurl 0] ne "/"} {
+ set srvurl /$srvurl
+ }
# Check for validity according to RFC 3986, Appendix A
set validityRE {(?xi)
^
@@ -504,12 +515,13 @@ proc http::geturl {url args} {
if {$proto eq ""} {
set proto http
}
- if {![info exists urlTypes($proto)]} {
+ set lower [string tolower $proto]
+ if {![info exists urlTypes($lower)]} {
unset $token
return -code error "Unsupported URL type \"$proto\""
}
- set defport [lindex $urlTypes($proto) 0]
- set defcmd [lindex $urlTypes($proto) 1]
+ set defport [lindex $urlTypes($lower) 0]
+ set defcmd [lindex $urlTypes($lower) 1]
if {$port eq ""} {
set port $defport
@@ -536,11 +548,10 @@ proc http::geturl {url args} {
# If a timeout is specified we set up the after event and arrange for an
# asynchronous socket connection.
- set sockopts [list]
+ set sockopts [list -async]
if {$state(-timeout) > 0} {
set state(after) [after $state(-timeout) \
[list http::reset $token timeout]]
- lappend sockopts -async
}
# If we are using the proxy, we must pass in the full URL that includes
@@ -596,10 +607,15 @@ proc http::geturl {url args} {
set socketmap($state(socketinfo)) $sock
}
- # Wait for the connection to complete.
+ if {![info exists phost]} {
+ set phost ""
+ }
+ fileevent $sock writable [list http::Connect $token $proto $phost $srvurl]
- if {$state(-timeout) > 0} {
- fileevent $sock writable [list http::Connect $token]
+ # Wait for the connection to complete.
+ if {![info exists state(-command)]} {
+ # geturl does EVERYTHING asynchronously, so if the user
+ # calls it synchronously, we just do a wait here.
http::wait $token
if {![info exists state]} {
@@ -615,13 +631,30 @@ proc http::geturl {url args} {
set err [lindex $state(error) 0]
cleanup $token
return -code error $err
- } elseif {$state(status) ne "connect"} {
- # Likely to be connection timeout
- return $token
}
- set state(status) ""
}
+ return $token
+}
+
+
+proc http::Connected { token proto phost srvurl} {
+ variable http
+ variable urlTypes
+
+ variable $token
+ upvar 0 $token state
+
+ # Set back the variables needed here
+ set sock $state(sock)
+ set isQueryChannel [info exists state(-querychannel)]
+ set isQuery [info exists state(-query)]
+ set host [lindex [split $state(socketinfo) :] 0]
+ set port [lindex [split $state(socketinfo) :] 1]
+
+ 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)
@@ -684,6 +717,7 @@ proc http::geturl {url args} {
puts $sock "Proxy-Connection: Keep-Alive"
}
set accept_encoding_seen 0
+ set content_type_seen 0
foreach {key value} $state(-headers) {
if {[string equal -nocase $key "host"]} {
continue
@@ -691,6 +725,9 @@ proc http::geturl {url args} {
if {[string equal -nocase $key "accept-encoding"]} {
set accept_encoding_seen 1
}
+ if {[string equal -nocase $key "content-type"]} {
+ set content_type_seen 1
+ }
set value [string map [list \n "" \r ""] $value]
set key [string trim $key]
if {[string equal -nocase $key "content-length"]} {
@@ -733,7 +770,9 @@ proc http::geturl {url args} {
# response.
if {$isQuery || $isQueryChannel} {
- puts $sock "Content-Type: $state(-type)"
+ if {!$content_type_seen} {
+ puts $sock "Content-Type: $state(-type)"
+ }
if {!$contDone} {
puts $sock "Content-Length: $state(querylength)"
}
@@ -746,35 +785,17 @@ proc http::geturl {url args} {
fileevent $sock readable [list http::Event $sock $token]
}
- if {![info exists state(-command)]} {
- # geturl does EVERYTHING asynchronously, so if the user calls it
- # synchronously, we just do a wait here.
-
- wait $token
- if {$state(status) eq "error"} {
- # Something went wrong, so throw the exception, and the
- # enclosing catch will do cleanup.
- return -code error [lindex $state(error) 0]
- }
- }
} err]} {
# The socket probably was never connected, or the connection dropped
# later.
- # Clean up after events and such, but DON'T call the command callback
- # (if available) because we're going to throw an exception from here
- # instead.
-
# if state(status) is error, it means someone's already called Finish
# to do the above-described clean up.
if {$state(status) ne "error"} {
- Finish $token $err 1
+ Finish $token $err
}
- cleanup $token
- return -code error $err
}
- return $token
}
# Data access functions:
@@ -858,18 +879,18 @@ proc http::cleanup {token} {
# Sets the status of the connection, which unblocks
# the waiting geturl call
-proc http::Connect {token} {
+proc http::Connect {token proto phost srvurl} {
variable $token
upvar 0 $token state
- global errorInfo errorCode
+ set err "due to unexpected EOF"
if {
[eof $state(sock)] ||
- [string length [fconfigure $state(sock) -error]]
+ [set err [fconfigure $state(sock) -error]] ne ""
} {
- Finish $token "connect failed [fconfigure $state(sock) -error]" 1
+ Finish $token "connect failed $err"
} else {
- set state(status) connect
fileevent $state(sock) writable {}
+ ::http::Connected $token $proto $phost $srvurl
}
return
}
@@ -974,7 +995,7 @@ proc http::Event {sock token} {
} elseif {$n == 0} {
# We have now read all headers
# We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3
- if {$state(http) == "" || [lindex $state(http) 1] == 100} {
+ if {$state(http) == "" || ([regexp {^\S+\s(\d+)} $state(http) {} x] && $x == 100)} {
return
}
@@ -1372,7 +1393,7 @@ proc http::mapReply {string} {
}
set converted [string map $formMap $string]
if {[string match "*\[\u0100-\uffff\]*" $converted]} {
- regexp {[\u0100-\uffff]} $converted badChar
+ regexp "\[\u0100-\uffff\]" $converted badChar
# Return this error message for maximum compatability... :^/
return -code error \
"can't read \"formMap($badChar)\": no such element in array"
diff --git a/library/http/pkgIndex.tcl b/library/http/pkgIndex.tcl
index 82b2e0b..27ba795 100644
--- a/library/http/pkgIndex.tcl
+++ b/library/http/pkgIndex.tcl
@@ -1,2 +1,2 @@
if {![package vsatisfies [package provide Tcl] 8.6]} {return}
-package ifneeded http 2.8.2 [list tclPkgSetup $dir http 2.8.2 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}]
+package ifneeded http 2.8.8 [list tclPkgSetup $dir http 2.8.8 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}]
diff --git a/library/init.tcl b/library/init.tcl
index 685fc7b..f63eedf 100644
--- a/library/init.tcl
+++ b/library/init.tcl
@@ -12,10 +12,11 @@
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
+# This test intentionally written in pre-7.5 Tcl
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.6b2
+package require -exact Tcl 8.6.1
# Compute the auto path to use in this interpreter.
# The values on the path come from several locations:
@@ -116,9 +117,10 @@ namespace eval tcl {
if {(![interp issafe]) && ($tcl_platform(platform) eq "windows")} {
namespace eval tcl {
proc EnvTraceProc {lo n1 n2 op} {
- set x $::env($n2)
- set ::env($lo) $x
- set ::env([string toupper $lo]) $x
+ global env
+ set x $env($n2)
+ set env($lo) $x
+ set env([string toupper $lo]) $x
}
proc InitWinEnv {} {
global env tcl_platform
@@ -128,9 +130,9 @@ if {(![interp issafe]) && ($tcl_platform(platform) eq "windows")} {
switch -- $u {
COMSPEC -
PATH {
- if {![info exists env($u)]} {
- set env($u) $env($p)
- }
+ set temp $env($p)
+ unset env($p)
+ set env($u) $temp
trace add variable env($p) write \
[namespace code [list EnvTraceProc $p]]
trace add variable env($u) write \
@@ -140,11 +142,7 @@ if {(![interp issafe]) && ($tcl_platform(platform) eq "windows")} {
}
}
if {![info exists env(COMSPEC)]} {
- if {$tcl_platform(os) eq "Windows NT"} {
- set env(COMSPEC) cmd.exe
- } else {
- set env(COMSPEC) command.com
- }
+ set env(COMSPEC) cmd.exe
}
}
InitWinEnv
@@ -159,8 +157,8 @@ if {[interp issafe]} {
} else {
# Set up search for Tcl Modules (TIP #189).
# and setup platform specific unknown package handlers
- if {$::tcl_platform(os) eq "Darwin"
- && $::tcl_platform(platform) eq "unix"} {
+ if {$tcl_platform(os) eq "Darwin"
+ && $tcl_platform(platform) eq "unix"} {
package unknown {::tcl::tm::UnknownHandler \
{::tcl::MacOSXPkgUnknown ::tclPkgUnknown}}
} else {
@@ -233,14 +231,13 @@ if {[namespace which -command tclLog] eq ""} {
proc unknown args {
variable ::tcl::UnknownPending
- global auto_noexec auto_noload env tcl_interactive
+ global auto_noexec auto_noload env tcl_interactive errorInfo errorCode
-
- if {[info exists ::errorInfo]} {
- set savedErrorInfo $::errorInfo
+ if {[info exists errorInfo]} {
+ set savedErrorInfo $errorInfo
}
- if {[info exists ::errorCode]} {
- set savedErrorCode $::errorCode
+ if {[info exists errorCode]} {
+ set savedErrorCode $errorCode
}
set name [lindex $args 0]
@@ -271,9 +268,9 @@ proc unknown args {
unset -nocomplain ::errorCode
}
if {[info exists savedErrorInfo]} {
- set ::errorInfo $savedErrorInfo
+ set errorInfo $savedErrorInfo
} else {
- unset -nocomplain ::errorInfo
+ unset -nocomplain errorInfo
}
set code [catch {uplevel 1 $args} msg opts]
if {$code == 1} {
@@ -282,8 +279,8 @@ proc unknown args {
# Note the dependence on how Tcl_AddErrorInfo, etc.
# construct the stack trace.
#
- set errorInfo [dict get $opts -errorinfo]
- set errorCode [dict get $opts -errorcode]
+ set errInfo [dict get $opts -errorinfo]
+ set errCode [dict get $opts -errorcode]
set cinfo $args
if {[string bytelength $cinfo] > 150} {
set cinfo [string range $cinfo 0 150]
@@ -300,7 +297,7 @@ proc unknown args {
# and trim the extra contribution from the matching case
#
set expect "$msg\n while executing\n\"$cinfo"
- if {$errorInfo eq $expect} {
+ if {$errInfo eq $expect} {
#
# The stack has only the eval from the expanded command
# Do not generate any stack trace here.
@@ -315,18 +312,18 @@ proc unknown args {
#
set expect "\n invoked from within\n\"$cinfo"
set exlen [string length $expect]
- set eilen [string length $errorInfo]
+ set eilen [string length $errInfo]
set i [expr {$eilen - $exlen - 1}]
- set einfo [string range $errorInfo 0 $i]
+ set einfo [string range $errInfo 0 $i]
#
- # For now verify that $errorInfo consists of what we are about
+ # For now verify that $errInfo consists of what we are about
# to return plus what we expected to trim off.
#
- if {$errorInfo ne "$einfo$expect"} {
+ if {$errInfo ne "$einfo$expect"} {
error "Tcl bug: unexpected stack trace in \"unknown\"" {} \
- [list CORE UNKNOWN BADTRACE $einfo $expect $errorInfo]
+ [list CORE UNKNOWN BADTRACE $einfo $expect $errInfo]
}
- return -code error -errorcode $errorCode \
+ return -code error -errorcode $errCode \
-errorinfo $einfo $msg
} else {
dict incr opts -level
@@ -335,7 +332,7 @@ proc unknown args {
}
}
- if {([info level] == 1) && ([info script] eq "") \
+ if {([info level] == 1) && ([info script] eq "")
&& [info exists tcl_interactive] && $tcl_interactive} {
if {![info exists auto_noexec]} {
set new [auto_execok $name]
@@ -651,7 +648,7 @@ proc auto_execok name {
set execExtensions [list {} .com .exe .bat .cmd]
}
- if {$name in $shellBuiltins} {
+ if {[string tolower $name] in $shellBuiltins} {
# When this is command.com for some reason on Win2K, Tcl won't
# exec it unless the case is right, which this corrects. COMSPEC
# may not point to a real file, so do the check.
@@ -689,13 +686,14 @@ proc auto_execok name {
}
}
- foreach dir [split $path {;}] {
- # Skip already checked directories
- if {[info exists checked($dir)] || ($dir eq "")} {
- continue
- }
- set checked($dir) {}
- foreach ext $execExtensions {
+ foreach ext $execExtensions {
+ unset -nocomplain checked
+ foreach dir [split $path {;}] {
+ # Skip already checked directories
+ if {[info exists checked($dir)] || ($dir eq "")} {
+ continue
+ }
+ set checked($dir) {}
set file [file join $dir ${name}${ext}]
if {[file exists $file] && ![file isdirectory $file]} {
return [set auto_execs($name) [list $file]]
@@ -787,7 +785,7 @@ proc tcl::CopyDirectory {action src dest} {
lappend existing {*}[glob -nocomplain -directory $dest \
-type hidden * .*]
foreach s $existing {
- if {([file tail $s] ne ".") && ([file tail $s] ne "..")} {
+ if {[file tail $s] ni {. ..}} {
return -code error "error $action \"$src\" to\
\"$dest\": file already exists"
}
@@ -795,7 +793,7 @@ proc tcl::CopyDirectory {action src dest} {
}
} else {
if {[string first $nsrc $ndest] != -1} {
- set srclen [expr {[llength [file split $nsrc]] -1}]
+ set srclen [expr {[llength [file split $nsrc]] - 1}]
set ndest [lindex [file split $ndest] $srclen]
if {$ndest eq [file tail $nsrc]} {
return -code error "error $action \"$src\" to\
@@ -815,37 +813,9 @@ proc tcl::CopyDirectory {action src dest} {
[glob -nocomplain -directory $src -types hidden *]]
foreach s [lsort -unique $filelist] {
- if {([file tail $s] ne ".") && ([file tail $s] ne "..")} {
- file copy -force $s [file join $dest [file tail $s]]
+ if {[file tail $s] ni {. ..}} {
+ file copy -force -- $s [file join $dest [file tail $s]]
}
}
return
}
-
-# TIP 131
-if 0 {
-proc tcl::rmmadwiw {} {
- set magic {
- 42 83 fe f6 ff f8 f1 e5 c6 f9 eb fd ff fb f1 e5 cc f5 ec f5 e3 fd fe
- ff f5 fa f3 e1 c7 f9 f2 fd ff f9 fe f9 ed f4 fa f6 e6 f9 f2 e6 fd f9
- ff f9 f6 e6 fa fd ff fc fb fc f9 f1 ed
- }
- foreach mystic [lassign $magic tragic] {
- set comic [expr (0x$mystic ^ 0x$tragic) - 255 + 0x$tragic]
- append logic [format %x $comic]
- set tragic $mystic
- }
- binary format H* $logic
-}
-
-proc tcl::mathfunc::rmmadwiw {} {
- set age [expr {9*6}]
- set mind ""
- while {$age} {
- lappend mind [expr {$age%13}]
- set age [expr {$age/13}]
- }
- set matter [lreverse $mind]
- return [join $matter ""]
-}
-}
diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl
index 369ed52..cf3b9d7 100644
--- a/library/msgcat/msgcat.tcl
+++ b/library/msgcat/msgcat.tcl
@@ -13,11 +13,11 @@
package require Tcl 8.5
# When the version number changes, be sure to update the pkgIndex.tcl file,
# and the installation directory in the Makefiles.
-package provide msgcat 1.4.4
+package provide msgcat 1.5.2
namespace eval msgcat {
namespace export mc mcload mclocale mcmax mcmset mcpreferences mcset \
- mcunknown
+ mcunknown mcflset mcflmset
# Records the current locale as passed to mclocale
variable Locale ""
@@ -25,6 +25,9 @@ namespace eval msgcat {
# Records the list of locales to search
variable Loclist {}
+ # Records the locale of the currently sourced message catalogue file
+ variable FileLocale
+
# Records the mapping between source strings and translated strings. The
# dict key is of the form "<locale> <namespace> <src>", where locale and
# namespace should be themselves dict values and the value is
@@ -32,7 +35,7 @@ namespace eval msgcat {
variable Msgs [dict create]
# Map of language codes used in Windows registry to those of ISO-639
- if { $::tcl_platform(platform) eq "windows" } {
+ if {[info sharedlibextension] eq ".dll"} {
variable WinRegToISO639 [dict create {*}{
01 ar 0401 ar_SA 0801 ar_IQ 0c01 ar_EG 1001 ar_LY 1401 ar_DZ
1801 ar_MA 1c01 ar_TN 2001 ar_OM 2401 ar_YE 2801 ar_SY
@@ -66,8 +69,8 @@ namespace eval msgcat {
15 pl 0415 pl_PL
16 pt 0416 pt_BR 0816 pt_PT
17 rm 0417 rm_CH
- 18 ro 0418 ro_RO
- 19 ru
+ 18 ro 0418 ro_RO 0818 ro_MO
+ 19 ru 0819 ru_MO
1a hr 041a hr_HR 081a sr_YU 0c1a sr_YU@cyrillic
1b sk 041b sk_SK
1c sq 041c sq_AL
@@ -92,6 +95,7 @@ namespace eval msgcat {
2f mk 042f mk_MK
30 bnt 0430 bnt_TZ
31 ts 0431 ts_ZA
+ 32 tn
33 ven 0433 ven_ZA
34 xh 0434 xh_ZA
35 zu 0435 zu_ZA
@@ -276,17 +280,30 @@ proc msgcat::mcpreferences {} {
# Returns the number of message catalogs that were loaded.
proc msgcat::mcload {langdir} {
+ variable FileLocale
+ # Save the file locale if we are recursively called
+ if {[info exists FileLocale]} {
+ set nestedFileLocale $FileLocale
+ }
set x 0
foreach p [mcpreferences] {
- if { $p eq {} } {
+ if {$p eq {}} {
set p ROOT
}
set langfile [file join $langdir $p.msg]
if {[file exists $langfile]} {
incr x
+ set FileLocale [string tolower [file tail [file rootname $langfile]]]
+ if {"root" eq $FileLocale} {
+ set FileLocale ""
+ }
uplevel 1 [list ::source -encoding utf-8 $langfile]
+ unset FileLocale
}
}
+ if {[info exists nestedFileLocale]} {
+ set FileLocale $nestedFileLocale
+ }
return $x
}
@@ -317,6 +334,35 @@ proc msgcat::mcset {locale src {dest ""}} {
return $dest
}
+# msgcat::mcflset --
+#
+# Set the translation for a given string in the current file locale.
+#
+# Arguments:
+# src The source string.
+# dest (Optional) The translated string. If omitted,
+# the source string is used.
+#
+# Results:
+# Returns the new locale.
+
+proc msgcat::mcflset {src {dest ""}} {
+ variable FileLocale
+ variable Msgs
+
+ if {![info exists FileLocale]} {
+ return -code error \
+ "must only be used inside a message catalog loaded with ::msgcat::mcload"
+ }
+ if {[llength [info level 0]] == 2} { ;# dest not specified
+ set dest $src
+ }
+
+ set ns [uplevel 1 [list ::namespace current]]
+ dict set Msgs $FileLocale $ns $src $dest
+ return $dest
+}
+
# msgcat::mcmset --
#
# Set the translation for multiple strings in a specified locale.
@@ -328,7 +374,7 @@ proc msgcat::mcset {locale src {dest ""}} {
# Results:
# Returns the number of pairs processed
-proc msgcat::mcmset {locale pairs } {
+proc msgcat::mcmset {locale pairs} {
variable Msgs
set length [llength $pairs]
@@ -341,10 +387,41 @@ proc msgcat::mcmset {locale pairs } {
set ns [uplevel 1 [list ::namespace current]]
foreach {src dest} $pairs {
- dict set Msgs $locale $ns $src $dest
+ dict set Msgs $locale $ns $src $dest
}
- return $length
+ return [expr {$length / 2}]
+}
+
+# msgcat::mcflmset --
+#
+# Set the translation for multiple strings in the mc file locale.
+#
+# Arguments:
+# pairs One or more src/dest pairs (must be even length)
+#
+# Results:
+# Returns the number of pairs processed
+
+proc msgcat::mcflmset {pairs} {
+ variable FileLocale
+ variable Msgs
+
+ if {![info exists FileLocale]} {
+ return -code error \
+ "must only be used inside a message catalog loaded with ::msgcat::mcload"
+ }
+ set length [llength $pairs]
+ if {$length % 2} {
+ return -code error "bad translation list:\
+ should be \"[lindex [info level 0] 0] locale {src dest ...}\""
+ }
+
+ set ns [uplevel 1 [list ::namespace current]]
+ foreach {src dest} $pairs {
+ dict set Msgs $FileLocale $ns $src $dest
+ }
+ return [expr {$length / 2}]
}
# msgcat::mcunknown --
@@ -387,10 +464,10 @@ proc msgcat::mcmax {args} {
set max 0
foreach string $args {
set translated [uplevel 1 [list [namespace origin mc] $string]]
- set len [string length $translated]
- if {$len>$max} {
+ set len [string length $translated]
+ if {$len>$max} {
set max $len
- }
+ }
}
return $max
}
@@ -426,7 +503,7 @@ proc msgcat::ConvertLocale {value} {
# Initialize the default locale
proc msgcat::Init {} {
- global env tcl_platform
+ global env
#
# set default locale, try to get from environment
@@ -451,23 +528,54 @@ proc msgcat::Init {} {
}
}
#
- # The rest of this routine is special processing for Windows;
- # all other platforms, get out now.
+ # The rest of this routine is special processing for Windows or
+ # Cygwin. All other platforms, get out now.
#
- if {$tcl_platform(platform) ne "windows"} {
+ if {([info sharedlibextension] ne ".dll")
+ || [catch {package require registry}]} {
mclocale C
return
}
#
- # On Windows, try to set locale depending on registry settings,
- # or fall back on locale of "C".
+ # On Windows or Cygwin, try to set locale depending on registry
+ # settings, or fall back on locale of "C".
#
+
+ # On Vista and later:
+ # HCU/Control Panel/Desktop : PreferredUILanguages is for language packs,
+ # HCU/Control Pannel/International : localName is the default locale.
+ #
+ # They contain the local string as RFC5646, composed of:
+ # [a-z]{2,3} : language
+ # -[a-z]{4} : script (optional, translated by table Latn->latin)
+ # -[a-z]{2}|[0-9]{3} : territory (optional, numerical region codes not used)
+ # (-.*)* : variant, extension, private use (optional, not used)
+ # Those are translated to local strings.
+ # Examples: de-CH -> de_ch, sr-Latn-CS -> sr_cs@latin, es-419 -> es
+ #
+ foreach key {{HKEY_CURRENT_USER\Control Panel\Desktop} {HKEY_CURRENT_USER\Control Panel\International}}\
+ value {PreferredUILanguages localeName} {
+ if {![catch {registry get $key $value} localeName]
+ && [regexp {^([a-z]{2,3})(?:-([a-z]{4}))?(?:-([a-z]{2}))?(?:-.+)?$}\
+ [string tolower $localeName] match locale script territory]} {
+ if {"" ne $territory} {
+ append locale _ $territory
+ }
+ set modifierDict [dict create latn latin cyrl cyrillic]
+ if {[dict exists $modifierDict $script]} {
+ append locale @ [dict get $modifierDict $script]
+ }
+ if {![catch {mclocale [ConvertLocale $locale]}]} {
+ return
+ }
+ }
+ }
+
+ # then check value locale which contains a numerical language ID
if {[catch {
- package require registry
- set key {HKEY_CURRENT_USER\Control Panel\International}
set locale [registry get $key "locale"]
}]} {
- mclocale C
+ mclocale C
return
}
#
diff --git a/library/msgcat/pkgIndex.tcl b/library/msgcat/pkgIndex.tcl
index 17ad5db..5fabfe3 100644
--- a/library/msgcat/pkgIndex.tcl
+++ b/library/msgcat/pkgIndex.tcl
@@ -1,2 +1,2 @@
if {![package vsatisfies [package provide Tcl] 8.5]} {return}
-package ifneeded msgcat 1.4.4 [list source [file join $dir msgcat.tcl]]
+package ifneeded msgcat 1.5.2 [list source [file join $dir msgcat.tcl]]
diff --git a/library/msgs/af.msg b/library/msgs/af.msg
index 0892615..0892615 100755..100644
--- a/library/msgs/af.msg
+++ b/library/msgs/af.msg
diff --git a/library/msgs/af_za.msg b/library/msgs/af_za.msg
index fef48ad..fef48ad 100755..100644
--- a/library/msgs/af_za.msg
+++ b/library/msgs/af_za.msg
diff --git a/library/msgs/ar.msg b/library/msgs/ar.msg
index 257157f..257157f 100755..100644
--- a/library/msgs/ar.msg
+++ b/library/msgs/ar.msg
diff --git a/library/msgs/ar_in.msg b/library/msgs/ar_in.msg
index 185e49c..185e49c 100755..100644
--- a/library/msgs/ar_in.msg
+++ b/library/msgs/ar_in.msg
diff --git a/library/msgs/ar_jo.msg b/library/msgs/ar_jo.msg
index 0f5e269..0f5e269 100755..100644
--- a/library/msgs/ar_jo.msg
+++ b/library/msgs/ar_jo.msg
diff --git a/library/msgs/ar_lb.msg b/library/msgs/ar_lb.msg
index e62acd3..e62acd3 100755..100644
--- a/library/msgs/ar_lb.msg
+++ b/library/msgs/ar_lb.msg
diff --git a/library/msgs/ar_sy.msg b/library/msgs/ar_sy.msg
index d5e1c87..d5e1c87 100755..100644
--- a/library/msgs/ar_sy.msg
+++ b/library/msgs/ar_sy.msg
diff --git a/library/msgs/be.msg b/library/msgs/be.msg
index 379a1d7..379a1d7 100755..100644
--- a/library/msgs/be.msg
+++ b/library/msgs/be.msg
diff --git a/library/msgs/bg.msg b/library/msgs/bg.msg
index ff17759..ff17759 100755..100644
--- a/library/msgs/bg.msg
+++ b/library/msgs/bg.msg
diff --git a/library/msgs/bn.msg b/library/msgs/bn.msg
index 664b9d8..664b9d8 100755..100644
--- a/library/msgs/bn.msg
+++ b/library/msgs/bn.msg
diff --git a/library/msgs/bn_in.msg b/library/msgs/bn_in.msg
index 28c000f..28c000f 100755..100644
--- a/library/msgs/bn_in.msg
+++ b/library/msgs/bn_in.msg
diff --git a/library/msgs/ca.msg b/library/msgs/ca.msg
index 36c9772..36c9772 100755..100644
--- a/library/msgs/ca.msg
+++ b/library/msgs/ca.msg
diff --git a/library/msgs/cs.msg b/library/msgs/cs.msg
index 8db8bdd..8db8bdd 100755..100644
--- a/library/msgs/cs.msg
+++ b/library/msgs/cs.msg
diff --git a/library/msgs/da.msg b/library/msgs/da.msg
index e4fec7f..e4fec7f 100755..100644
--- a/library/msgs/da.msg
+++ b/library/msgs/da.msg
diff --git a/library/msgs/de.msg b/library/msgs/de.msg
index 9eb3145..9eb3145 100755..100644
--- a/library/msgs/de.msg
+++ b/library/msgs/de.msg
diff --git a/library/msgs/de_at.msg b/library/msgs/de_at.msg
index 61bc266..61bc266 100755..100644
--- a/library/msgs/de_at.msg
+++ b/library/msgs/de_at.msg
diff --git a/library/msgs/de_be.msg b/library/msgs/de_be.msg
index 3614763..3614763 100755..100644
--- a/library/msgs/de_be.msg
+++ b/library/msgs/de_be.msg
diff --git a/library/msgs/el.msg b/library/msgs/el.msg
index ac19f62..ac19f62 100755..100644
--- a/library/msgs/el.msg
+++ b/library/msgs/el.msg
diff --git a/library/msgs/en_au.msg b/library/msgs/en_au.msg
index 7f9870c..7f9870c 100755..100644
--- a/library/msgs/en_au.msg
+++ b/library/msgs/en_au.msg
diff --git a/library/msgs/en_be.msg b/library/msgs/en_be.msg
index 5072986..5072986 100755..100644
--- a/library/msgs/en_be.msg
+++ b/library/msgs/en_be.msg
diff --git a/library/msgs/en_bw.msg b/library/msgs/en_bw.msg
index 8fd20c7..8fd20c7 100755..100644
--- a/library/msgs/en_bw.msg
+++ b/library/msgs/en_bw.msg
diff --git a/library/msgs/en_ca.msg b/library/msgs/en_ca.msg
index 278efe7..278efe7 100755..100644
--- a/library/msgs/en_ca.msg
+++ b/library/msgs/en_ca.msg
diff --git a/library/msgs/en_gb.msg b/library/msgs/en_gb.msg
index 5c61c43..5c61c43 100755..100644
--- a/library/msgs/en_gb.msg
+++ b/library/msgs/en_gb.msg
diff --git a/library/msgs/en_hk.msg b/library/msgs/en_hk.msg
index 8b33bc0..8b33bc0 100755..100644
--- a/library/msgs/en_hk.msg
+++ b/library/msgs/en_hk.msg
diff --git a/library/msgs/en_ie.msg b/library/msgs/en_ie.msg
index ba621cf..ba621cf 100755..100644
--- a/library/msgs/en_ie.msg
+++ b/library/msgs/en_ie.msg
diff --git a/library/msgs/en_in.msg b/library/msgs/en_in.msg
index a1f155d..a1f155d 100755..100644
--- a/library/msgs/en_in.msg
+++ b/library/msgs/en_in.msg
diff --git a/library/msgs/en_nz.msg b/library/msgs/en_nz.msg
index b419017..b419017 100755..100644
--- a/library/msgs/en_nz.msg
+++ b/library/msgs/en_nz.msg
diff --git a/library/msgs/en_ph.msg b/library/msgs/en_ph.msg
index 682666d..682666d 100755..100644
--- a/library/msgs/en_ph.msg
+++ b/library/msgs/en_ph.msg
diff --git a/library/msgs/en_sg.msg b/library/msgs/en_sg.msg
index 4dc5b1d..4dc5b1d 100755..100644
--- a/library/msgs/en_sg.msg
+++ b/library/msgs/en_sg.msg
diff --git a/library/msgs/en_za.msg b/library/msgs/en_za.msg
index fe43797..fe43797 100755..100644
--- a/library/msgs/en_za.msg
+++ b/library/msgs/en_za.msg
diff --git a/library/msgs/en_zw.msg b/library/msgs/en_zw.msg
index 2a5804f..2a5804f 100755..100644
--- a/library/msgs/en_zw.msg
+++ b/library/msgs/en_zw.msg
diff --git a/library/msgs/eo.msg b/library/msgs/eo.msg
index 1d2a24f..1d2a24f 100755..100644
--- a/library/msgs/eo.msg
+++ b/library/msgs/eo.msg
diff --git a/library/msgs/es.msg b/library/msgs/es.msg
index a24f0a1..a24f0a1 100755..100644
--- a/library/msgs/es.msg
+++ b/library/msgs/es.msg
diff --git a/library/msgs/es_ar.msg b/library/msgs/es_ar.msg
index 7d35027..7d35027 100755..100644
--- a/library/msgs/es_ar.msg
+++ b/library/msgs/es_ar.msg
diff --git a/library/msgs/es_bo.msg b/library/msgs/es_bo.msg
index 498ad0d..498ad0d 100755..100644
--- a/library/msgs/es_bo.msg
+++ b/library/msgs/es_bo.msg
diff --git a/library/msgs/es_cl.msg b/library/msgs/es_cl.msg
index 31d465c..31d465c 100755..100644
--- a/library/msgs/es_cl.msg
+++ b/library/msgs/es_cl.msg
diff --git a/library/msgs/es_co.msg b/library/msgs/es_co.msg
index 77e57f0..77e57f0 100755..100644
--- a/library/msgs/es_co.msg
+++ b/library/msgs/es_co.msg
diff --git a/library/msgs/es_cr.msg b/library/msgs/es_cr.msg
index 7a652fa..7a652fa 100755..100644
--- a/library/msgs/es_cr.msg
+++ b/library/msgs/es_cr.msg
diff --git a/library/msgs/es_do.msg b/library/msgs/es_do.msg
index 0e283da..0e283da 100755..100644
--- a/library/msgs/es_do.msg
+++ b/library/msgs/es_do.msg
diff --git a/library/msgs/es_ec.msg b/library/msgs/es_ec.msg
index 9e921e0..9e921e0 100755..100644
--- a/library/msgs/es_ec.msg
+++ b/library/msgs/es_ec.msg
diff --git a/library/msgs/es_gt.msg b/library/msgs/es_gt.msg
index ecd6faf..ecd6faf 100755..100644
--- a/library/msgs/es_gt.msg
+++ b/library/msgs/es_gt.msg
diff --git a/library/msgs/es_hn.msg b/library/msgs/es_hn.msg
index a758ca2..a758ca2 100755..100644
--- a/library/msgs/es_hn.msg
+++ b/library/msgs/es_hn.msg
diff --git a/library/msgs/es_mx.msg b/library/msgs/es_mx.msg
index 7cfb545..7cfb545 100755..100644
--- a/library/msgs/es_mx.msg
+++ b/library/msgs/es_mx.msg
diff --git a/library/msgs/es_ni.msg b/library/msgs/es_ni.msg
index 7c39495..7c39495 100755..100644
--- a/library/msgs/es_ni.msg
+++ b/library/msgs/es_ni.msg
diff --git a/library/msgs/es_pa.msg b/library/msgs/es_pa.msg
index cecacdc..cecacdc 100755..100644
--- a/library/msgs/es_pa.msg
+++ b/library/msgs/es_pa.msg
diff --git a/library/msgs/es_pe.msg b/library/msgs/es_pe.msg
index 9f90595..9f90595 100755..100644
--- a/library/msgs/es_pe.msg
+++ b/library/msgs/es_pe.msg
diff --git a/library/msgs/es_pr.msg b/library/msgs/es_pr.msg
index 8511b12..8511b12 100755..100644
--- a/library/msgs/es_pr.msg
+++ b/library/msgs/es_pr.msg
diff --git a/library/msgs/es_py.msg b/library/msgs/es_py.msg
index aa93d36..aa93d36 100755..100644
--- a/library/msgs/es_py.msg
+++ b/library/msgs/es_py.msg
diff --git a/library/msgs/es_sv.msg b/library/msgs/es_sv.msg
index fc7954d..fc7954d 100755..100644
--- a/library/msgs/es_sv.msg
+++ b/library/msgs/es_sv.msg
diff --git a/library/msgs/es_uy.msg b/library/msgs/es_uy.msg
index b33525c..b33525c 100755..100644
--- a/library/msgs/es_uy.msg
+++ b/library/msgs/es_uy.msg
diff --git a/library/msgs/es_ve.msg b/library/msgs/es_ve.msg
index 7c2a7b0..7c2a7b0 100755..100644
--- a/library/msgs/es_ve.msg
+++ b/library/msgs/es_ve.msg
diff --git a/library/msgs/et.msg b/library/msgs/et.msg
index 8d32e9e..8d32e9e 100755..100644
--- a/library/msgs/et.msg
+++ b/library/msgs/et.msg
diff --git a/library/msgs/eu.msg b/library/msgs/eu.msg
index cf708b6..cf708b6 100755..100644
--- a/library/msgs/eu.msg
+++ b/library/msgs/eu.msg
diff --git a/library/msgs/eu_es.msg b/library/msgs/eu_es.msg
index 2694418..2694418 100755..100644
--- a/library/msgs/eu_es.msg
+++ b/library/msgs/eu_es.msg
diff --git a/library/msgs/fa.msg b/library/msgs/fa.msg
index 89b2f90..89b2f90 100755..100644
--- a/library/msgs/fa.msg
+++ b/library/msgs/fa.msg
diff --git a/library/msgs/fa_in.msg b/library/msgs/fa_in.msg
index adc9e91..adc9e91 100755..100644
--- a/library/msgs/fa_in.msg
+++ b/library/msgs/fa_in.msg
diff --git a/library/msgs/fa_ir.msg b/library/msgs/fa_ir.msg
index 597ce9d..597ce9d 100755..100644
--- a/library/msgs/fa_ir.msg
+++ b/library/msgs/fa_ir.msg
diff --git a/library/msgs/fi.msg b/library/msgs/fi.msg
index acabba0..acabba0 100755..100644
--- a/library/msgs/fi.msg
+++ b/library/msgs/fi.msg
diff --git a/library/msgs/fo.msg b/library/msgs/fo.msg
index 4696e62..4696e62 100755..100644
--- a/library/msgs/fo.msg
+++ b/library/msgs/fo.msg
diff --git a/library/msgs/fo_fo.msg b/library/msgs/fo_fo.msg
index 2392b8e..2392b8e 100755..100644
--- a/library/msgs/fo_fo.msg
+++ b/library/msgs/fo_fo.msg
diff --git a/library/msgs/fr.msg b/library/msgs/fr.msg
index 55b19bf..55b19bf 100755..100644
--- a/library/msgs/fr.msg
+++ b/library/msgs/fr.msg
diff --git a/library/msgs/fr_be.msg b/library/msgs/fr_be.msg
index cdb13bd..cdb13bd 100755..100644
--- a/library/msgs/fr_be.msg
+++ b/library/msgs/fr_be.msg
diff --git a/library/msgs/fr_ca.msg b/library/msgs/fr_ca.msg
index 00ccfff..00ccfff 100755..100644
--- a/library/msgs/fr_ca.msg
+++ b/library/msgs/fr_ca.msg
diff --git a/library/msgs/fr_ch.msg b/library/msgs/fr_ch.msg
index 7e2bac7..7e2bac7 100755..100644
--- a/library/msgs/fr_ch.msg
+++ b/library/msgs/fr_ch.msg
diff --git a/library/msgs/ga.msg b/library/msgs/ga.msg
index 6edf13a..6edf13a 100755..100644
--- a/library/msgs/ga.msg
+++ b/library/msgs/ga.msg
diff --git a/library/msgs/ga_ie.msg b/library/msgs/ga_ie.msg
index b6acbbc..b6acbbc 100755..100644
--- a/library/msgs/ga_ie.msg
+++ b/library/msgs/ga_ie.msg
diff --git a/library/msgs/gl.msg b/library/msgs/gl.msg
index 4b869e8..4b869e8 100755..100644
--- a/library/msgs/gl.msg
+++ b/library/msgs/gl.msg
diff --git a/library/msgs/gl_es.msg b/library/msgs/gl_es.msg
index d4ed270..d4ed270 100755..100644
--- a/library/msgs/gl_es.msg
+++ b/library/msgs/gl_es.msg
diff --git a/library/msgs/gv.msg b/library/msgs/gv.msg
index 7d332ad..7d332ad 100755..100644
--- a/library/msgs/gv.msg
+++ b/library/msgs/gv.msg
diff --git a/library/msgs/gv_gb.msg b/library/msgs/gv_gb.msg
index 5e96e6f..5e96e6f 100755..100644
--- a/library/msgs/gv_gb.msg
+++ b/library/msgs/gv_gb.msg
diff --git a/library/msgs/he.msg b/library/msgs/he.msg
index 4fd921d..4fd921d 100755..100644
--- a/library/msgs/he.msg
+++ b/library/msgs/he.msg
diff --git a/library/msgs/hi.msg b/library/msgs/hi.msg
index 50c9fb8..50c9fb8 100755..100644
--- a/library/msgs/hi.msg
+++ b/library/msgs/hi.msg
diff --git a/library/msgs/hi_in.msg b/library/msgs/hi_in.msg
index 239793f..239793f 100755..100644
--- a/library/msgs/hi_in.msg
+++ b/library/msgs/hi_in.msg
diff --git a/library/msgs/hr.msg b/library/msgs/hr.msg
index cec145b..cec145b 100755..100644
--- a/library/msgs/hr.msg
+++ b/library/msgs/hr.msg
diff --git a/library/msgs/hu.msg b/library/msgs/hu.msg
index e5e68d9..e5e68d9 100755..100644
--- a/library/msgs/hu.msg
+++ b/library/msgs/hu.msg
diff --git a/library/msgs/id.msg b/library/msgs/id.msg
index 17c6bb5..17c6bb5 100755..100644
--- a/library/msgs/id.msg
+++ b/library/msgs/id.msg
diff --git a/library/msgs/id_id.msg b/library/msgs/id_id.msg
index bb672c1..bb672c1 100755..100644
--- a/library/msgs/id_id.msg
+++ b/library/msgs/id_id.msg
diff --git a/library/msgs/is.msg b/library/msgs/is.msg
index adc2d2a..adc2d2a 100755..100644
--- a/library/msgs/is.msg
+++ b/library/msgs/is.msg
diff --git a/library/msgs/it.msg b/library/msgs/it.msg
index b641cde..b641cde 100755..100644
--- a/library/msgs/it.msg
+++ b/library/msgs/it.msg
diff --git a/library/msgs/it_ch.msg b/library/msgs/it_ch.msg
index b36ed36..b36ed36 100755..100644
--- a/library/msgs/it_ch.msg
+++ b/library/msgs/it_ch.msg
diff --git a/library/msgs/ja.msg b/library/msgs/ja.msg
index 2767665..2767665 100755..100644
--- a/library/msgs/ja.msg
+++ b/library/msgs/ja.msg
diff --git a/library/msgs/kl.msg b/library/msgs/kl.msg
index d877bfe..d877bfe 100755..100644
--- a/library/msgs/kl.msg
+++ b/library/msgs/kl.msg
diff --git a/library/msgs/kl_gl.msg b/library/msgs/kl_gl.msg
index 403aa10..403aa10 100755..100644
--- a/library/msgs/kl_gl.msg
+++ b/library/msgs/kl_gl.msg
diff --git a/library/msgs/ko.msg b/library/msgs/ko.msg
index 0cd17a1..0cd17a1 100755..100644
--- a/library/msgs/ko.msg
+++ b/library/msgs/ko.msg
diff --git a/library/msgs/ko_kr.msg b/library/msgs/ko_kr.msg
index ea5bbd7..ea5bbd7 100755..100644
--- a/library/msgs/ko_kr.msg
+++ b/library/msgs/ko_kr.msg
diff --git a/library/msgs/kok.msg b/library/msgs/kok.msg
index 0869f20..0869f20 100755..100644
--- a/library/msgs/kok.msg
+++ b/library/msgs/kok.msg
diff --git a/library/msgs/kok_in.msg b/library/msgs/kok_in.msg
index abcb1ff..abcb1ff 100755..100644
--- a/library/msgs/kok_in.msg
+++ b/library/msgs/kok_in.msg
diff --git a/library/msgs/kw.msg b/library/msgs/kw.msg
index aaf79b3..aaf79b3 100755..100644
--- a/library/msgs/kw.msg
+++ b/library/msgs/kw.msg
diff --git a/library/msgs/kw_gb.msg b/library/msgs/kw_gb.msg
index 2967680..2967680 100755..100644
--- a/library/msgs/kw_gb.msg
+++ b/library/msgs/kw_gb.msg
diff --git a/library/msgs/lt.msg b/library/msgs/lt.msg
index 27b0985..27b0985 100755..100644
--- a/library/msgs/lt.msg
+++ b/library/msgs/lt.msg
diff --git a/library/msgs/lv.msg b/library/msgs/lv.msg
index a037b15..a037b15 100755..100644
--- a/library/msgs/lv.msg
+++ b/library/msgs/lv.msg
diff --git a/library/msgs/mk.msg b/library/msgs/mk.msg
index 41cf60d..41cf60d 100755..100644
--- a/library/msgs/mk.msg
+++ b/library/msgs/mk.msg
diff --git a/library/msgs/mr.msg b/library/msgs/mr.msg
index cea427a..cea427a 100755..100644
--- a/library/msgs/mr.msg
+++ b/library/msgs/mr.msg
diff --git a/library/msgs/mr_in.msg b/library/msgs/mr_in.msg
index 1889da5..1889da5 100755..100644
--- a/library/msgs/mr_in.msg
+++ b/library/msgs/mr_in.msg
diff --git a/library/msgs/ms.msg b/library/msgs/ms.msg
index e954431..e954431 100755..100644
--- a/library/msgs/ms.msg
+++ b/library/msgs/ms.msg
diff --git a/library/msgs/ms_my.msg b/library/msgs/ms_my.msg
index c1f93d4..c1f93d4 100755..100644
--- a/library/msgs/ms_my.msg
+++ b/library/msgs/ms_my.msg
diff --git a/library/msgs/mt.msg b/library/msgs/mt.msg
index ddd5446..ddd5446 100755..100644
--- a/library/msgs/mt.msg
+++ b/library/msgs/mt.msg
diff --git a/library/msgs/nb.msg b/library/msgs/nb.msg
index 90d49a3..90d49a3 100755..100644
--- a/library/msgs/nb.msg
+++ b/library/msgs/nb.msg
diff --git a/library/msgs/nl.msg b/library/msgs/nl.msg
index 4c5c675..4c5c675 100755..100644
--- a/library/msgs/nl.msg
+++ b/library/msgs/nl.msg
diff --git a/library/msgs/nl_be.msg b/library/msgs/nl_be.msg
index 4b19670..4b19670 100755..100644
--- a/library/msgs/nl_be.msg
+++ b/library/msgs/nl_be.msg
diff --git a/library/msgs/nn.msg b/library/msgs/nn.msg
index bd61ac9..bd61ac9 100755..100644
--- a/library/msgs/nn.msg
+++ b/library/msgs/nn.msg
diff --git a/library/msgs/pl.msg b/library/msgs/pl.msg
index d206f4b..d206f4b 100755..100644
--- a/library/msgs/pl.msg
+++ b/library/msgs/pl.msg
diff --git a/library/msgs/pt.msg b/library/msgs/pt.msg
index 96fdb35..96fdb35 100755..100644
--- a/library/msgs/pt.msg
+++ b/library/msgs/pt.msg
diff --git a/library/msgs/pt_br.msg b/library/msgs/pt_br.msg
index 8684327..8684327 100755..100644
--- a/library/msgs/pt_br.msg
+++ b/library/msgs/pt_br.msg
diff --git a/library/msgs/ro.msg b/library/msgs/ro.msg
index bdd7c61..bdd7c61 100755..100644
--- a/library/msgs/ro.msg
+++ b/library/msgs/ro.msg
diff --git a/library/msgs/ru.msg b/library/msgs/ru.msg
index 65b075d..65b075d 100755..100644
--- a/library/msgs/ru.msg
+++ b/library/msgs/ru.msg
diff --git a/library/msgs/ru_ua.msg b/library/msgs/ru_ua.msg
index 6e1f8a8..6e1f8a8 100755..100644
--- a/library/msgs/ru_ua.msg
+++ b/library/msgs/ru_ua.msg
diff --git a/library/msgs/sh.msg b/library/msgs/sh.msg
index 6ee0fc7..6ee0fc7 100755..100644
--- a/library/msgs/sh.msg
+++ b/library/msgs/sh.msg
diff --git a/library/msgs/sk.msg b/library/msgs/sk.msg
index 9b2f0aa..9b2f0aa 100755..100644
--- a/library/msgs/sk.msg
+++ b/library/msgs/sk.msg
diff --git a/library/msgs/sl.msg b/library/msgs/sl.msg
index 42bc509..42bc509 100755..100644
--- a/library/msgs/sl.msg
+++ b/library/msgs/sl.msg
diff --git a/library/msgs/sq.msg b/library/msgs/sq.msg
index 8fb1fce..8fb1fce 100755..100644
--- a/library/msgs/sq.msg
+++ b/library/msgs/sq.msg
diff --git a/library/msgs/sr.msg b/library/msgs/sr.msg
index 7576668..7576668 100755..100644
--- a/library/msgs/sr.msg
+++ b/library/msgs/sr.msg
diff --git a/library/msgs/sv.msg b/library/msgs/sv.msg
index f7a67c6..f7a67c6 100755..100644
--- a/library/msgs/sv.msg
+++ b/library/msgs/sv.msg
diff --git a/library/msgs/sw.msg b/library/msgs/sw.msg
index b888b43..b888b43 100755..100644
--- a/library/msgs/sw.msg
+++ b/library/msgs/sw.msg
diff --git a/library/msgs/ta.msg b/library/msgs/ta.msg
index 4abb90c..4abb90c 100755..100644
--- a/library/msgs/ta.msg
+++ b/library/msgs/ta.msg
diff --git a/library/msgs/ta_in.msg b/library/msgs/ta_in.msg
index 24590ac..24590ac 100755..100644
--- a/library/msgs/ta_in.msg
+++ b/library/msgs/ta_in.msg
diff --git a/library/msgs/te.msg b/library/msgs/te.msg
index 6111473..6111473 100755..100644
--- a/library/msgs/te.msg
+++ b/library/msgs/te.msg
diff --git a/library/msgs/te_in.msg b/library/msgs/te_in.msg
index 61638b5..61638b5 100755..100644
--- a/library/msgs/te_in.msg
+++ b/library/msgs/te_in.msg
diff --git a/library/msgs/th.msg b/library/msgs/th.msg
index 7486c35..7486c35 100755..100644
--- a/library/msgs/th.msg
+++ b/library/msgs/th.msg
diff --git a/library/msgs/tr.msg b/library/msgs/tr.msg
index 7b2ecf9..7b2ecf9 100755..100644
--- a/library/msgs/tr.msg
+++ b/library/msgs/tr.msg
diff --git a/library/msgs/uk.msg b/library/msgs/uk.msg
index 3e24f86..7d4c64a 100755..100644
--- a/library/msgs/uk.msg
+++ b/library/msgs/uk.msg
@@ -33,7 +33,7 @@ namespace eval ::tcl::clock {
::msgcat::mcset uk MONTHS_FULL [list \
"\u0441\u0456\u0447\u043d\u044f"\
"\u043b\u044e\u0442\u043e\u0433\u043e"\
- "\u0431\u0435\u0440\u0435\u0436\u043d\u044f"\
+ "\u0431\u0435\u0440\u0435\u0437\u043d\u044f"\
"\u043a\u0432\u0456\u0442\u043d\u044f"\
"\u0442\u0440\u0430\u0432\u043d\u044f"\
"\u0447\u0435\u0440\u0432\u043d\u044f"\
diff --git a/library/msgs/vi.msg b/library/msgs/vi.msg
index c98b2a6..c98b2a6 100755..100644
--- a/library/msgs/vi.msg
+++ b/library/msgs/vi.msg
diff --git a/library/msgs/zh.msg b/library/msgs/zh.msg
index b799a32..b799a32 100755..100644
--- a/library/msgs/zh.msg
+++ b/library/msgs/zh.msg
diff --git a/library/msgs/zh_cn.msg b/library/msgs/zh_cn.msg
index d62ce77..d62ce77 100755..100644
--- a/library/msgs/zh_cn.msg
+++ b/library/msgs/zh_cn.msg
diff --git a/library/msgs/zh_hk.msg b/library/msgs/zh_hk.msg
index badb1dd..badb1dd 100755..100644
--- a/library/msgs/zh_hk.msg
+++ b/library/msgs/zh_hk.msg
diff --git a/library/msgs/zh_sg.msg b/library/msgs/zh_sg.msg
index a2f3e39..a2f3e39 100755..100644
--- a/library/msgs/zh_sg.msg
+++ b/library/msgs/zh_sg.msg
diff --git a/library/msgs/zh_tw.msg b/library/msgs/zh_tw.msg
index e0796b1..e0796b1 100755..100644
--- a/library/msgs/zh_tw.msg
+++ b/library/msgs/zh_tw.msg
diff --git a/library/package.tcl b/library/package.tcl
index 52801e6..52daa0e 100644
--- a/library/package.tcl
+++ b/library/package.tcl
@@ -395,11 +395,9 @@ proc pkg_mkIndex {args} {
foreach pkg [lsort [array names files]] {
set cmd {}
- foreach {name version} $pkg {
- break
- }
+ lassign $pkg name version
lappend cmd ::tcl::Pkg::Create -name $name -version $version
- foreach spec $files($pkg) {
+ foreach spec [lsort -index 0 $files($pkg)] {
foreach {file type procs} $spec {
if {$direct} {
set procs {}
@@ -544,8 +542,7 @@ proc tclPkgUnknown {name args} {
# Don't add directories we've already seen, or ones already on the
# $use_path.
foreach dir [lrange $auto_path $index end] {
- if {![info exists tclSeenPath($dir)]
- && ([lsearch -exact $use_path $dir] == -1) } {
+ if {![info exists tclSeenPath($dir)] && ($dir ni $use_path)} {
lappend use_path $dir
}
}
@@ -628,8 +625,7 @@ proc tcl::MacOSXPkgUnknown {original name args} {
# Don't add directories we've already seen, or ones already on the
# $use_path.
foreach dir [lrange $auto_path $index end] {
- if {![info exists tclSeenPath($dir)]
- && ([lsearch -exact $use_path $dir] == -1) } {
+ if {![info exists tclSeenPath($dir)] && ($dir ni $use_path)} {
lappend use_path $dir
}
}
@@ -681,10 +677,7 @@ proc ::tcl::Pkg::Create {args} {
}
# Initialize parameters
- set opts(-name) {}
- set opts(-version) {}
- set opts(-source) {}
- set opts(-load) {}
+ array set opts {-name {} -version {} -source {} -load {}}
# process parameters
for {set i 0} {$i < $len} {incr i} {
@@ -732,14 +725,9 @@ proc ::tcl::Pkg::Create {args} {
# Handle -load and -source specs
foreach key {load source} {
foreach filespec $opts(-$key) {
- foreach {filename proclist} {{} {}} {
- break
- }
- foreach {filename proclist} $filespec {
- break
- }
-
- if {![llength $proclist]} {
+ lassign $filespec filename proclist
+
+ if { [llength $proclist] == 0 } {
set cmd "\[list $key \[file join \$dir [list $filename]\]\]"
lappend cmdList $cmd
} else {
diff --git a/library/parray.tcl b/library/parray.tcl
index 3ce9817..a9c2cb1 100644
--- a/library/parray.tcl
+++ b/library/parray.tcl
@@ -11,7 +11,7 @@
proc parray {a {pattern *}} {
upvar 1 $a array
if {![array exists array]} {
- error "\"$a\" isn't an array"
+ return -code error "\"$a\" isn't an array"
}
set maxl 0
set names [lsort [array names array $pattern]]
diff --git a/library/platform/pkgIndex.tcl b/library/platform/pkgIndex.tcl
index 220a67b..23a3408 100644
--- a/library/platform/pkgIndex.tcl
+++ b/library/platform/pkgIndex.tcl
@@ -1,3 +1,3 @@
-package ifneeded platform 1.0.10 [list source [file join $dir platform.tcl]]
+package ifneeded platform 1.0.12 [list source [file join $dir platform.tcl]]
package ifneeded platform::shell 1.1.4 [list source [file join $dir shell.tcl]]
diff --git a/library/platform/platform.tcl b/library/platform/platform.tcl
index dd2e66b..5698425 100644
--- a/library/platform/platform.tcl
+++ b/library/platform/platform.tcl
@@ -256,7 +256,7 @@ proc ::platform::LibcVersion {base _->_ vv} {
if {![catch {
set vdata [lindex [split [exec $libc] \n] 0]
}]} {
- regexp {([0-9]+(\.[0-9]+)*)} $vdata -> v
+ regexp {version ([0-9]+(\.[0-9]+)*)} $vdata -> v
foreach {major minor} [split $v .] break
set v glibc${major}.${minor}
return 1
@@ -368,7 +368,7 @@ proc ::platform::patterns {id} {
# ### ### ### ######### ######### #########
## Ready
-package provide platform 1.0.10
+package provide platform 1.0.12
# ### ### ### ######### ######### #########
## Demo application
diff --git a/library/platform/shell.tcl b/library/platform/shell.tcl
index e0a129a..d37cdcd 100644
--- a/library/platform/shell.tcl
+++ b/library/platform/shell.tcl
@@ -187,7 +187,7 @@ proc ::platform::shell::TEMP {} {
}
}
}
- if {[string compare $channel ""]} {
+ if {$channel != ""} {
return -code error "Failed to open a temporary file: $channel"
} else {
return -code error "Failed to find an unused temporary file name"
diff --git a/library/reg/pkgIndex.tcl b/library/reg/pkgIndex.tcl
index f07dee4..55af4b3 100755
--- a/library/reg/pkgIndex.tcl
+++ b/library/reg/pkgIndex.tcl
@@ -1,9 +1,9 @@
-if {![package vsatisfies [package provide Tcl] 8]} {return}
-if {[string compare $::tcl_platform(platform) windows]} {return}
-if {[info exists ::tcl_platform(debug)]} {
- package ifneeded registry 1.3 \
+if {([info commands ::tcl::pkgconfig] eq "")
+ || ([info sharedlibextension] ne ".dll")} return
+if {[::tcl::pkgconfig get debug]} {
+ package ifneeded registry 1.3.0 \
[list load [file join $dir tclreg13g.dll] registry]
} else {
- package ifneeded registry 1.3 \
+ package ifneeded registry 1.3.0 \
[list load [file join $dir tclreg13.dll] registry]
}
diff --git a/library/safe.tcl b/library/safe.tcl
index 95db3b2..394aa97 100644
--- a/library/safe.tcl
+++ b/library/safe.tcl
@@ -465,8 +465,19 @@ proc ::safe::InterpInit {
# This alias lets the slave have access to a subset of the 'file'
# command functionality.
- AliasSubset $slave file \
- file dir.* join root.* ext.* tail path.* split
+ ::interp expose $slave file
+ foreach subcommand {dirname extension rootname tail} {
+ ::interp alias $slave ::tcl::file::$subcommand {} \
+ ::safe::AliasFileSubcommand $slave $subcommand
+ }
+ foreach subcommand {
+ atime attributes copy delete executable exists isdirectory isfile
+ link lstat mtime mkdir nativename normalize owned readable readlink
+ rename size stat tempfile type volumes writable
+ } {
+ ::interp alias $slave ::tcl::file::$subcommand {} \
+ ::safe::BadSubcommand $slave file $subcommand
+ }
# Subcommands of info
foreach {subcommand alias} {
@@ -483,23 +494,24 @@ proc ::safe::InterpInit {
if {[catch {::interp eval $slave {
source [file join $tcl_library init.tcl]
- }} msg]} {
+ }} msg opt]} {
Log $slave "can't source init.tcl ($msg)"
- return -code error "can't source init.tcl into slave $slave ($msg)"
+ return -options $opt "can't source init.tcl into slave $slave ($msg)"
}
if {[catch {::interp eval $slave {
source [file join $tcl_library tm.tcl]
- }} msg]} {
+ }} msg opt]} {
Log $slave "can't source tm.tcl ($msg)"
- return -code error "can't source tm.tcl into slave $slave ($msg)"
+ return -options $opt "can't source tm.tcl into slave $slave ($msg)"
}
# Sync the paths used to search for Tcl modules. This can be done only
# now, after tm.tcl was loaded.
namespace upvar ::safe S$slave state
if {[llength $state(tm_path_slave)] > 0} {
- ::interp eval $slave [list ::tcl::tm::add {*}$state(tm_path_slave)]
+ ::interp eval $slave [list \
+ ::tcl::tm::add {*}[lreverse $state(tm_path_slave)]]
}
return $slave
}
@@ -664,6 +676,17 @@ proc ::safe::CheckFileName {slave file} {
}
}
+# AliasFileSubcommand handles selected subcommands of [file] in safe
+# interpreters that are *almost* safe. In particular, it just acts to
+# prevent discovery of what home directories exist.
+
+proc ::safe::AliasFileSubcommand {slave subcommand name} {
+ if {[string match ~* $name]} {
+ set name ./$name
+ }
+ tailcall ::interp invokehidden $slave tcl:file:$subcommand $name
+}
+
# AliasGlob is the target of the "glob" alias in safe interpreters.
proc ::safe::AliasGlob {slave args} {
@@ -679,9 +702,9 @@ proc ::safe::AliasGlob {slave args} {
}
if {$::tcl_platform(platform) eq "windows"} {
- set dirPartRE {^(.*)[\\/]}
+ set dirPartRE {^(.*)[\\/]([^\\/]*)$}
} else {
- set dirPartRE {^(.*)/}
+ set dirPartRE {^(.*)/([^/]*)$}
}
set dir {}
@@ -734,9 +757,7 @@ proc ::safe::AliasGlob {slave args} {
DirInAccessPath $slave $dir
} on error msg {
Log $slave $msg
- if {$got(-nocomplain)} {
- return
- }
+ if {$got(-nocomplain)} return
return -code error "permission denied"
}
lappend cmd -directory $dir
@@ -749,20 +770,33 @@ proc ::safe::AliasGlob {slave args} {
# Process remaining pattern arguments
set firstPattern [llength $cmd]
- while {$at < [llength $args]} {
- set opt [lindex $args $at]
- incr at
- if {[regexp $dirPartRE $opt -> thedir]} {
- try {
- set thedir [file join $virtualdir $thedir]
- DirInAccessPath $slave [TranslatePath $slave $thedir]
- } on error msg {
- Log $slave $msg
- if {$got(-nocomplain)} {
- continue
+ foreach opt [lrange $args $at end] {
+ if {![regexp $dirPartRE $opt -> thedir thefile]} {
+ set thedir .
+ } elseif {[string match ~* $thedir]} {
+ set thedir ./$thedir
+ }
+ if {$thedir eq "*" &&
+ ($thefile eq "pkgIndex.tcl" || $thefile eq "*.tm")} {
+ set mapped 0
+ foreach d [glob -directory [TranslatePath $slave $virtualdir] \
+ -types d -tails *] {
+ catch {
+ DirInAccessPath $slave \
+ [TranslatePath $slave [file join $virtualdir $d]]
+ lappend cmd [file join $d $thefile]
+ set mapped 1
}
- return -code error "permission denied"
}
+ if {$mapped} continue
+ }
+ try {
+ DirInAccessPath $slave [TranslatePath $slave \
+ [file join $virtualdir $thedir]]
+ } on error msg {
+ Log $slave $msg
+ if {$got(-nocomplain)} continue
+ return -code error "permission denied"
}
lappend cmd $opt
}
@@ -779,7 +813,7 @@ proc ::safe::AliasGlob {slave args} {
return -code error "script error"
}
- Log $slave "GLOB @ $entries" NOTICE
+ Log $slave "GLOB < $entries" NOTICE
# Translate path back to what the slave should see.
set res {}
@@ -791,7 +825,7 @@ proc ::safe::AliasGlob {slave args} {
lappend res $p
}
- Log $slave "GLOB @ $res" NOTICE
+ Log $slave "GLOB > $res" NOTICE
return $res
}
@@ -848,6 +882,7 @@ proc ::safe::AliasSource {slave args} {
# because we want to control [info script] in the slave so information
# doesn't leak so much. [Bug 2913625]
set old [::interp eval $slave {info script}]
+ set replacementMsg "script error"
set code [catch {
set f [open $realfile]
fconfigure $f -eofchar \032
@@ -857,14 +892,17 @@ proc ::safe::AliasSource {slave args} {
set contents [read $f]
close $f
::interp eval $slave [list info script $file]
- ::interp eval $slave $contents
} msg opt]
+ if {$code == 0} {
+ set code [catch {::interp eval $slave $contents} msg opt]
+ set replacementMsg $msg
+ }
catch {interp eval $slave [list info script $old]}
# Note that all non-errors are fine result codes from [source], so we must
# take a little care to do it properly. [Bug 2923613]
if {$code == 1} {
Log $slave $msg
- return -code error "script error"
+ return -code error $replacementMsg
}
return -code $code -options $opt $msg
}
@@ -980,58 +1018,33 @@ proc ::safe::DirInAccessPath {slave dir} {
}
}
-# This procedure enables access from a safe interpreter to only a subset
-# of the subcommands of a command:
+# This procedure is used to report an attempt to use an unsafe member of an
+# ensemble command.
-proc ::safe::Subset {slave command okpat args} {
- set subcommand [lindex $args 0]
- if {[regexp $okpat $subcommand]} {
- return [$command {*}$args]
- }
+proc ::safe::BadSubcommand {slave command subcommand args} {
set msg "not allowed to invoke subcommand $subcommand of $command"
Log $slave $msg
- return -code error $msg
-}
-
-# This procedure installs an alias in a slave that invokes "safesubset" in
-# the master to execute allowed subcommands. It precomputes the pattern of
-# allowed subcommands; you can use wildcards in the pattern if you wish to
-# allow subcommand abbreviation.
-#
-# Syntax is: AliasSubset slave alias target subcommand1 subcommand2...
-
-proc ::safe::AliasSubset {slave alias target args} {
- set pat "^([join $args |])\$"
- ::interp alias $slave $alias {}\
- [namespace current]::Subset $slave $target $pat
+ return -code error -errorcode {TCL SAFE SUBCOMMAND} $msg
}
# AliasEncoding is the target of the "encoding" alias in safe interpreters.
proc ::safe::AliasEncoding {slave option args} {
- # Careful; do not want empty option to get through to the [string equal]
- if {[regexp {^(name.*|convert.*|)$} $option]} {
- return [::interp invokehidden $slave encoding $option {*}$args]
- }
-
- if {[string equal -length [string length $option] $option "system"]} {
- if {![llength $args]} {
- # passed all the tests , lets source it:
- try {
- return [::interp invokehidden $slave encoding system]
- } on error msg {
- Log $slave $msg
- return -code error "script error"
- }
+ # Note that [encoding dirs] is not supported in safe slaves at all
+ set subcommands {convertfrom convertto names system}
+ try {
+ set option [tcl::prefix match -error [list -level 1 -errorcode \
+ [list TCL LOOKUP INDEX option $option]] $subcommands $option]
+ # Special case: [encoding system] ok, but [encoding system foo] not
+ if {$option eq "system" && [llength $args]} {
+ return -code error -errorcode {TCL WRONGARGS} \
+ "wrong # args: should be \"encoding system\""
}
- set msg "wrong # args: should be \"encoding system\""
- set code {TCL WRONGARGS}
- } else {
- set msg "bad option \"$option\": must be convertfrom, convertto, names, or system"
- set code [list TCL LOOKUP INDEX option $option]
+ } on error {msg options} {
+ Log $slave $msg
+ return -options $options $msg
}
- Log $slave $msg
- return -code error -errorcode $code $msg
+ tailcall ::interp invokehidden $slave encoding $option {*}$args
}
# Various minor hiding of platform features. [Bug 2913625]
diff --git a/library/tcltest/pkgIndex.tcl b/library/tcltest/pkgIndex.tcl
index 2eb43a6..c99ad2a 100644
--- a/library/tcltest/pkgIndex.tcl
+++ b/library/tcltest/pkgIndex.tcl
@@ -9,4 +9,4 @@
# full path name of this file's directory.
if {![package vsatisfies [package provide Tcl] 8.5]} {return}
-package ifneeded tcltest 2.3.3 [list source [file join $dir tcltest.tcl]]
+package ifneeded tcltest 2.3.7 [list source [file join $dir tcltest.tcl]]
diff --git a/library/tcltest/tcltest.tcl b/library/tcltest/tcltest.tcl
index af809f6..4b94312 100644
--- a/library/tcltest/tcltest.tcl
+++ b/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.3.3
+ variable Version 2.3.7
# Compatibility support for dumb variables defined in tcltest 1
# Do not use these. Call [package provide Tcl] and [info patchlevel]
@@ -84,7 +84,7 @@ namespace eval tcltest {
# None.
#
proc normalizePath {pathVar} {
- upvar $pathVar path
+ upvar 1 $pathVar path
set oldpwd [pwd]
catch {cd $path}
set path [pwd]
@@ -247,15 +247,15 @@ namespace eval tcltest {
# Kept only for compatibility
Default constraintsSpecified {} AcceptList
- trace variable constraintsSpecified r {set ::tcltest::constraintsSpecified \
- [array names ::tcltest::testConstraints] ;# }
+ trace add variable constraintsSpecified read [namespace code {
+ set constraintsSpecified [array names testConstraints] ;#}]
# tests that use threads need to know which is the main thread
Default mainThread 1
variable mainThread
- if {[info commands thread::id] != {}} {
+ if {[info commands thread::id] ne {}} {
set mainThread [thread::id]
- } elseif {[info commands testthread] != {}} {
+ } elseif {[info commands testthread] ne {}} {
set mainThread [testthread id]
}
@@ -263,7 +263,7 @@ namespace eval tcltest {
# Tcl tests is the working directory. Whenever this value changes
# change to that directory.
variable workingDirectory
- trace variable workingDirectory w \
+ trace add variable workingDirectory write \
[namespace code {cd $workingDirectory ;#}]
Default workingDirectory [pwd] AcceptAbsolutePath
@@ -277,7 +277,7 @@ namespace eval tcltest {
# Set the location of the execuatble
Default tcltest [info nameofexecutable]
- trace variable tcltest w [namespace code {testConstraint stdio \
+ trace add variable tcltest write [namespace code {testConstraint stdio \
[eval [ConstraintInitializer stdio]] ;#}]
# save the platform information so it can be restored later
@@ -404,11 +404,11 @@ namespace eval tcltest {
# already there.
set outdir [normalizePath [file dirname \
[file join [pwd] $filename]]]
- if {[string equal $outdir [temporaryDirectory]]} {
+ if {$outdir eq [temporaryDirectory]} {
variable filesExisted
FillFilesExisted
set filename [file tail $filename]
- if {[lsearch -exact $filesExisted $filename] == -1} {
+ if {$filename ni $filesExisted} {
lappend filesExisted $filename
}
}
@@ -448,11 +448,11 @@ namespace eval tcltest {
# already there.
set outdir [normalizePath [file dirname \
[file join [pwd] $filename]]]
- if {[string equal $outdir [temporaryDirectory]]} {
+ if {$outdir eq [temporaryDirectory]} {
variable filesExisted
FillFilesExisted
set filename [file tail $filename]
- if {[lsearch -exact $filesExisted $filename] == -1} {
+ if {$filename ni $filesExisted} {
lappend filesExisted $filename
}
}
@@ -483,8 +483,10 @@ namespace eval tcltest {
variable Verify
variable Usage
variable OptionControlledVariables
+ variable DefaultValue
set Usage($option) $usage
set Verify($option) $verify
+ set DefaultValue($option) $value
if {[catch {$verify $value} msg]} {
return -code error $msg
} else {
@@ -532,7 +534,7 @@ namespace eval tcltest {
}
default {
# Exact match trumps ambiguity
- if {[lsearch -exact $match $option] >= 0} {
+ if {$option in $match} {
return $option
}
set values [join [lrange $match 0 end-1] ", "]
@@ -547,7 +549,8 @@ namespace eval tcltest {
variable OptionControlledVariables
foreach varName [concat $OptionControlledVariables Option] {
variable $varName
- trace variable $varName r [namespace code {ProcessCmdLineArgs ;#}]
+ trace add variable $varName read [namespace code {
+ ProcessCmdLineArgs ;#}]
}
}
@@ -555,11 +558,11 @@ namespace eval tcltest {
variable OptionControlledVariables
foreach varName [concat $OptionControlledVariables Option] {
variable $varName
- foreach pair [trace vinfo $varName] {
- foreach {op cmd} $pair break
- if {[string equal r $op]
- && [string match *ProcessCmdLineArgs* $cmd]} {
- trace vdelete $varName $op $cmd
+ foreach pair [trace info variable $varName] {
+ lassign $pair op cmd
+ if {($op eq "read") &&
+ [string match *ProcessCmdLineArgs* $cmd]} {
+ trace remove variable $varName $op $cmd
}
}
}
@@ -599,7 +602,9 @@ namespace eval tcltest {
}
}
proc configure args {
- RemoveAutoConfigureTraces
+ if {[llength $args] > 1} {
+ RemoveAutoConfigureTraces
+ }
set code [catch {Configure {*}$args} msg]
return -code $code $msg
}
@@ -694,7 +699,7 @@ namespace eval tcltest {
Option -constraints {} {
Do not skip the listed constraints listed in -constraints.
} AcceptList
- trace variable Option(-constraints) w \
+ trace add variable Option(-constraints) write \
[namespace code {SetSelectedConstraints ;#}]
# Don't run only the "-constraint" specified tests by default
@@ -703,15 +708,15 @@ namespace eval tcltest {
variable testConstraints
if {!$Option(-limitconstraints)} {return}
foreach c [array names testConstraints] {
- if {[lsearch -exact $Option(-constraints) $c] == -1} {
+ if {$c ni $Option(-constraints)} {
testConstraint $c 0
}
}
}
- Option -limitconstraints false {
+ Option -limitconstraints 0 {
whether to run only tests with the constraints
} AcceptBoolean limitConstraints
- trace variable Option(-limitconstraints) w \
+ trace add variable Option(-limitconstraints) write \
[namespace code {ClearUnselectedConstraints ;#}]
# A test application has to know how to load the tested commands
@@ -732,7 +737,7 @@ namespace eval tcltest {
}
set directory [AcceptDirectory $directory]
if {![file writable $directory]} {
- if {[string equal [workingDirectory] $directory]} {
+ if {[workingDirectory] eq $directory} {
# Special exception: accept the default value
# even if the directory is not writable
return $directory
@@ -746,7 +751,7 @@ namespace eval tcltest {
Option -tmpdir [workingDirectory] {
Save temporary files in the specified directory.
} AcceptTemporaryDirectory temporaryDirectory
- trace variable Option(-tmpdir) w \
+ trace add variable Option(-tmpdir) write \
[namespace code {normalizePath Option(-tmpdir) ;#}]
# Tests should not rely on the current working directory.
@@ -755,17 +760,17 @@ namespace eval tcltest {
Option -testdir [workingDirectory] {
Search tests in the specified directory.
} AcceptDirectory testsDirectory
- trace variable Option(-testdir) w \
+ trace add variable Option(-testdir) write \
[namespace code {normalizePath Option(-testdir) ;#}]
proc AcceptLoadFile { file } {
- if {[string equal "" $file]} {return $file}
+ if {$file eq {}} {return $file}
set file [file join [temporaryDirectory] $file]
return [AcceptReadable $file]
}
proc ReadLoadScript {args} {
variable Option
- if {[string equal "" $Option(-loadfile)]} {return}
+ if {$Option(-loadfile) eq {}} {return}
set tmp [open $Option(-loadfile) r]
loadScript [read $tmp]
close $tmp
@@ -773,7 +778,7 @@ namespace eval tcltest {
Option -loadfile {} {
Read the script to load the tested commands from the specified file.
} AcceptLoadFile loadFile
- trace variable Option(-loadfile) w [namespace code ReadLoadScript]
+ trace add variable Option(-loadfile) write [namespace code ReadLoadScript]
proc AcceptOutFile { file } {
if {[string equal stderr $file]} {return $file}
@@ -785,14 +790,14 @@ namespace eval tcltest {
Option -outfile stdout {
Send output from test runs to the specified file.
} AcceptOutFile outputFile
- trace variable Option(-outfile) w \
+ trace add variable Option(-outfile) write \
[namespace code {outputChannel $Option(-outfile) ;#}]
# errors go to stderr by default
Option -errfile stderr {
Send errors from test runs to the specified file.
} AcceptOutFile errorFile
- trace variable Option(-errfile) w \
+ trace add variable Option(-errfile) write \
[namespace code {errorChannel $Option(-errfile) ;#}]
proc loadIntoSlaveInterpreter {slave args} {
@@ -873,7 +878,7 @@ proc tcltest::DebugPArray {level arrayvar} {
variable debug
if {$debug >= $level} {
- catch {upvar $arrayvar $arrayvar}
+ catch {upvar 1 $arrayvar $arrayvar}
parray $arrayvar
}
return
@@ -957,8 +962,7 @@ proc tcltest::testConstraint {constraint {value ""}} {
if {[catch {expr {$value && $value}} msg]} {
return -code error $msg
}
- if {[limitConstraints]
- && [lsearch -exact $Option(-constraints) $constraint] == -1} {
+ if {[limitConstraints] && ($constraint ni $Option(-constraints))} {
set value 0
}
set testConstraints($constraint) $value
@@ -982,11 +986,7 @@ proc tcltest::interpreter { {interp ""} } {
if {[llength [info level 0]] == 1} {
return $tcltest
}
- if {[string equal {} $interp]} {
- set tcltest {}
- } else {
- set tcltest $interp
- }
+ set tcltest $interp
}
#####################################################################
@@ -1051,7 +1051,7 @@ proc tcltest::PrintError {errorMsg} {
[expr {80 - $InitialMsgLen}]]]
puts [errorChannel] [string range $errorMsg 0 $beginningIndex]
- while {![string equal end $beginningIndex]} {
+ while {$beginningIndex ne "end"} {
puts -nonewline [errorChannel] \
[string repeat " " $InitialMsgLen]
if {($endingIndex - $beginningIndex)
@@ -1104,7 +1104,7 @@ proc tcltest::PrintError {errorMsg} {
proc tcltest::SafeFetch {n1 n2 op} {
variable testConstraints
DebugPuts 3 "entering SafeFetch $n1 $n2 $op"
- if {[string equal {} $n2]} {return}
+ if {$n2 eq {}} {return}
if {![info exists testConstraints($n2)]} {
if {[catch {testConstraint $n2 [eval [ConstraintInitializer $n2]]}]} {
testConstraint $n2 0
@@ -1249,9 +1249,8 @@ proc tcltest::DefineConstraintInitializers {} {
# are running as root on Unix.
ConstraintInitializer root {expr \
- {[string equal unix $::tcl_platform(platform)]
- && ([string equal root $::tcl_platform(user)]
- || [string equal "" $::tcl_platform(user)])}}
+ {($::tcl_platform(platform) eq "unix") &&
+ ($::tcl_platform(user) in {root {}})}}
ConstraintInitializer notRoot {expr {![testConstraint root]}}
# Set nonBlockFiles constraint: 1 means this platform supports
@@ -1259,7 +1258,7 @@ proc tcltest::DefineConstraintInitializers {} {
ConstraintInitializer nonBlockFiles {
set code [expr {[catch {set f [open defs r]}]
- || [catch {fconfigure $f -blocking off}]}]
+ || [catch {chan configure $f -blocking off}]}]
catch {close $f}
set code
}
@@ -1285,10 +1284,10 @@ proc tcltest::DefineConstraintInitializers {} {
ConstraintInitializer unixExecs {
set code 1
- if {[string equal macintosh $::tcl_platform(platform)]} {
+ if {$::tcl_platform(platform) eq "macintosh"} {
set code 0
}
- if {[string equal windows $::tcl_platform(platform)]} {
+ if {$::tcl_platform(platform) eq "windows"} {
if {[catch {
set file _tcl_test_remove_me.txt
makeFile {hello} $file
@@ -1382,7 +1381,7 @@ proc tcltest::Usage { {option ""} } {
set allOpts [concat -help [Configure]]
foreach opt $allOpts {
set foo [Usage $opt]
- foreach [list x type($opt) usage($opt)] $foo break
+ lassign $foo x type($opt) usage($opt)
set line($opt) " $opt $type($opt) "
set length($opt) [string length $line($opt)]
if {$length($opt) > $max} {set max $length($opt)}
@@ -1406,7 +1405,7 @@ proc tcltest::Usage { {option ""} } {
append msg $u
}
return $msg\n
- } elseif {[string equal -help $option]} {
+ } elseif {$option eq "-help"} {
return [list -help "" "Display this usage information."]
} else {
set type [lindex [info args $Verify($option)] 0]
@@ -1432,7 +1431,7 @@ proc tcltest::Usage { {option ""} } {
proc tcltest::ProcessFlags {flagArray} {
# Process -help first
- if {[lsearch -exact $flagArray {-help}] != -1} {
+ if {"-help" in $flagArray} {
PrintUsageInfo
exit 1
}
@@ -1441,14 +1440,14 @@ proc tcltest::ProcessFlags {flagArray} {
RemoveAutoConfigureTraces
} else {
set args $flagArray
- while {[llength $args]>1 && [catch {configure {*}$args} msg]} {
+ while {[llength $args] > 1 && [catch {configure {*}$args} msg]} {
# Something went wrong parsing $args for tcltest options
# Check whether the problem is "unknown option"
if {[regexp {^unknown option (\S+):} $msg -> option]} {
# Could be this is an option the Hook knows about
set moreOptions [processCmdLineArgsAddFlagsHook]
- if {[lsearch -exact $moreOptions $option] == -1} {
+ if {$option ni $moreOptions} {
# Nope. Report the error, including additional options,
# but keep going
if {[llength $moreOptions]} {
@@ -1467,7 +1466,7 @@ proc tcltest::ProcessFlags {flagArray} {
# To recover, find that unknown option and remove up to it.
# then retry
- while {![string equal [lindex $args 0] $option]} {
+ while {[lindex $args 0] ne $option} {
set args [lrange $args 2 end]
}
set args [lrange $args 2 end]
@@ -1573,7 +1572,7 @@ proc tcltest::Replace::puts {args} {
}
2 {
# Either -nonewline or channelId has been specified
- if {[string equal -nonewline [lindex $args 0]]} {
+ if {[lindex $args 0] eq "-nonewline"} {
append outData [lindex $args end]
return
# return [Puts -nonewline [lindex $args end]]
@@ -1583,7 +1582,7 @@ proc tcltest::Replace::puts {args} {
}
}
3 {
- if {[string equal -nonewline [lindex $args 0]]} {
+ if {[lindex $args 0] eq "-nonewline"} {
# Both -nonewline and channelId are specified, unless
# it's an error. -nonewline is supposed to be argv[0].
set channel [lindex $args 1]
@@ -1593,12 +1592,10 @@ proc tcltest::Replace::puts {args} {
}
if {[info exists channel]} {
- if {[string equal $channel [[namespace parent]::outputChannel]]
- || [string equal $channel stdout]} {
+ if {$channel in [list [[namespace parent]::outputChannel] stdout]} {
append outData [lindex $args end]$newline
return
- } elseif {[string equal $channel [[namespace parent]::errorChannel]]
- || [string equal $channel stderr]} {
+ } elseif {$channel in [list [[namespace parent]::errorChannel] stderr]} {
append errData [lindex $args end]$newline
return
}
@@ -1767,7 +1764,7 @@ proc tcltest::SubstArguments {argList} {
set argList {}
}
- if {$token != {}} {
+ if {$token ne {}} {
# If we saw a word with quote before, then there is a
# multi-word token starting with that word. In this case,
# add the text and the current word to this token.
@@ -1874,10 +1871,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.
- foreach item {constraints setup cleanup body result returnCodes
- match} {
- set $item {}
- }
+ lassign {} constraints setup cleanup body result returnCodes match
# Set the default match mode
set match exact
@@ -1889,8 +1883,7 @@ proc tcltest::test {name description args} {
# 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)} {
+ if {[string match -* [lindex $args 0]] || ([llength $args] <= 1)} {
if {[llength $args] == 1} {
set list [SubstArguments [lindex $args 0]]
foreach {element value} $list {
@@ -1911,7 +1904,7 @@ proc tcltest::test {name description args} {
-match -output -errorOutput -constraints}
foreach flag [array names testAttributes] {
- if {[lsearch -exact $validFlags $flag] == -1} {
+ if {$flag ni $validFlags} {
incr testLevel -1
set sorted [lsort $validFlags]
set options [join [lrange $sorted 0 end-1] ", "]
@@ -1927,7 +1920,7 @@ proc tcltest::test {name description args} {
# Check the values supplied for -match
variable CustomMatch
- if {[lsearch [array names CustomMatch] $match] == -1} {
+ if {$match ni [array names CustomMatch]} {
incr testLevel -1
set sorted [lsort [array names CustomMatch]]
set values [join [lrange $sorted 0 end-1] ", "]
@@ -1991,7 +1984,7 @@ proc tcltest::test {name description args} {
} else {
set testResult [uplevel 1 [list [namespace origin Eval] $command 1]]
}
- foreach {actualAnswer returnCode} $testResult break
+ lassign $testResult actualAnswer returnCode
if {$returnCode == 1} {
set errorInfo(body) $::errorInfo
set errorCode(body) $::errorCode
@@ -2027,11 +2020,11 @@ proc tcltest::test {name description args} {
if {([preserveCore] > 1) && ($coreFailure)} {
append coreMsg "\nMoving file to:\
[file join [temporaryDirectory] core-$name]"
- catch {file rename -force \
+ catch {file rename -force -- \
[file join [workingDirectory] core] \
[file join [temporaryDirectory] core-$name]
} msg
- if {[string length $msg] > 0} {
+ if {$msg ne {}} {
append coreMsg "\nError:\
Problem renaming core file: $msg"
}
@@ -2041,7 +2034,7 @@ proc tcltest::test {name description args} {
# check if the return code matched the expected return code
set codeFailure 0
- if {!$setupFailure && [lsearch -exact $returnCodes $returnCode] == -1} {
+ if {!$setupFailure && ($returnCode ni $returnCodes)} {
set codeFailure 1
}
@@ -2120,7 +2113,7 @@ proc tcltest::test {name description args} {
set testFd [open $testFile r]
set testLine [expr {[lsearch -regexp \
[split [read $testFd] "\n"] \
- "^\[ \t\]*test [string map {. \\.} $name] "]+1}]
+ "^\[ \t\]*test [string map {. \\.} $name] "] + 1}]
close $testFd
}
}
@@ -2165,7 +2158,7 @@ proc tcltest::test {name description args} {
puts [outputChannel] "---- Return code should have been\
one of: $returnCodes"
if {[IsVerbose error]} {
- if {[info exists errorInfo(body)] && ([lsearch $returnCodes 1]<0)} {
+ if {[info exists errorInfo(body)] && (1 ni $returnCodes)} {
puts [outputChannel] "---- errorInfo: $errorInfo(body)"
puts [outputChannel] "---- errorCode: $errorCode(body)"
}
@@ -2246,7 +2239,7 @@ proc tcltest::Skipped {name constraints} {
}
return 1
}
- if {[string equal {} $constraints]} {
+ if {$constraints eq {}} {
# If we're limited to the listed constraints and there aren't
# any listed, then we shouldn't run the test.
if {[limitConstraints]} {
@@ -2397,7 +2390,7 @@ proc tcltest::cleanupTests {{calledFromAllFile 0}} {
foreach file $filesMade {
if {[file exists $file]} {
DebugDo 1 {Warn "cleanupTests deleting $file..."}
- catch {file delete -force $file}
+ catch {file delete -force -- $file}
}
}
set currentFiles {}
@@ -2407,7 +2400,7 @@ proc tcltest::cleanupTests {{calledFromAllFile 0}} {
}
set newFiles {}
foreach file $currentFiles {
- if {[lsearch -exact $filesExisted $file] == -1} {
+ if {$file ni $filesExisted} {
lappend newFiles $file
}
}
@@ -2490,8 +2483,7 @@ proc tcltest::cleanupTests {{calledFromAllFile 0}} {
# then add current file to failFile list if any tests in this
# file failed
- if {$currentFailure \
- && ([lsearch -exact $failFiles $testFileName] == -1)} {
+ if {$currentFailure && ($testFileName ni $failFiles)} {
lappend failFiles $testFileName
}
set currentFailure false
@@ -2506,17 +2498,15 @@ proc tcltest::cleanupTests {{calledFromAllFile 0}} {
if {![info exists originalEnv($index)]} {
lappend newEnv $index
unset ::env($index)
- } else {
- if {$::env($index) != $originalEnv($index)} {
- lappend changedEnv $index
- set ::env($index) $originalEnv($index)
- }
}
}
foreach index [array names originalEnv] {
if {![info exists ::env($index)]} {
lappend removedEnv $index
set ::env($index) $originalEnv($index)
+ } elseif {$::env($index) ne $originalEnv($index)} {
+ lappend changedEnv $index
+ set ::env($index) $originalEnv($index)
}
}
if {[llength $newEnv] > 0} {
@@ -2551,11 +2541,11 @@ proc tcltest::cleanupTests {{calledFromAllFile 0}} {
puts [outputChannel] "produced core file! \
Moving file to: \
[file join [temporaryDirectory] core-$testFileName]"
- catch {file rename -force \
+ catch {file rename -force -- \
[file join [workingDirectory] core] \
[file join [temporaryDirectory] core-$testFileName]
} msg
- if {[string length $msg] > 0} {
+ if {$msg ne {}} {
PrintError "Problem renaming file: $msg"
}
} else {
@@ -2633,7 +2623,7 @@ proc tcltest::GetMatchingFiles { args } {
# Add to result list all files in match list and not in skip list
foreach file $matchFileList {
- if {[lsearch -exact $skipFileList $file] == -1} {
+ if {$file ni $skipFileList} {
lappend matchingFiles $file
}
}
@@ -2680,7 +2670,7 @@ proc tcltest::GetMatchingDirectories {rootdir} {
foreach pattern [matchDirectories] {
foreach path [glob -directory $rootdir -types d -nocomplain -- \
$pattern] {
- if {[lsearch -exact $skipDirs $path] == -1} {
+ if {$path ni $skipDirs} {
set matchDirs [concat $matchDirs [GetMatchingDirectories $path]]
if {[file exists [file join $path all.tcl]]} {
lappend matchDirs $path
@@ -2716,6 +2706,7 @@ proc tcltest::runAllTests { {shell ""} } {
variable numTestFiles
variable numTests
variable failFiles
+ variable DefaultValue
FillFilesExisted
if {[llength [info level 0]] == 1} {
@@ -2732,7 +2723,7 @@ proc tcltest::runAllTests { {shell ""} } {
# [file system] first available in Tcl 8.4
if {![catch {file system [testsDirectory]} result]
- && ![string equal native [lindex $result 0]]} {
+ && ([lindex $result 0] ne "native")} {
# If we aren't running in the native filesystem, then we must
# run the tests in a single process (via 'source'), because
# trying to run then via a pipe will fail since the files don't
@@ -2779,8 +2770,13 @@ proc tcltest::runAllTests { {shell ""} } {
# needs to read and process output of children.
set childargv [list]
foreach opt [Configure] {
- if {[string equal $opt -outfile]} {continue}
- lappend childargv $opt [Configure $opt]
+ if {$opt eq "-outfile"} {continue}
+ set value [Configure $opt]
+ # Don't bother passing default configuration options
+ if {$value eq $DefaultValue($opt)} {
+ continue
+ }
+ lappend childargv $opt $value
}
set cmd [linsert $childargv 0 | $shell $file]
if {[catch {
@@ -2870,11 +2866,6 @@ proc tcltest::runAllTests { {shell ""} } {
# none.
proc tcltest::loadTestedCommands {} {
- variable l
- if {[string equal {} [loadScript]]} {
- return
- }
-
return [uplevel 1 [loadScript]]
}
@@ -2917,16 +2908,15 @@ proc tcltest::saveState {} {
proc tcltest::restoreState {} {
variable saveState
foreach p [uplevel 1 {::info procs}] {
- if {([lsearch [lindex $saveState 0] $p] < 0)
- && ![string equal [namespace current]::$p \
- [uplevel 1 [list ::namespace origin $p]]]} {
+ if {($p ni [lindex $saveState 0]) && ("[namespace current]::$p" ne
+ [uplevel 1 [list ::namespace origin $p]])} {
DebugPuts 2 "[lindex [info level 0] 0]: Removing proc $p"
uplevel 1 [list ::catch [list ::rename $p {}]]
}
}
foreach p [uplevel 1 {::info vars}] {
- if {[lsearch [lindex $saveState 1] $p] < 0} {
+ if {$p ni [lindex $saveState 1]} {
DebugPuts 2 "[lindex [info level 0] 0]:\
Removing variable $p"
uplevel 1 [list ::catch [list ::unset $p]]
@@ -2987,15 +2977,15 @@ proc tcltest::makeFile {contents name {directory ""}} {
putting ``$contents'' into $fullName"
set fd [open $fullName w]
- fconfigure $fd -translation lf
- if {[string equal [string index $contents end] \n]} {
+ chan configure $fd -translation lf
+ if {[string index $contents end] eq "\n"} {
puts -nonewline $fd $contents
} else {
puts $fd $contents
}
close $fd
- if {[lsearch -exact $filesMade $fullName] == -1} {
+ if {$fullName ni $filesMade} {
lappend filesMade $fullName
}
return $fullName
@@ -3035,7 +3025,7 @@ proc tcltest::removeFile {name {directory ""}} {
Warn "removeFile removing \"$fullName\":\n not a file"
}
}
- return [file delete $fullName]
+ return [file delete -- $fullName]
}
# tcltest::makeDirectory --
@@ -3065,7 +3055,7 @@ proc tcltest::makeDirectory {name {directory ""}} {
set fullName [file join $directory $name]
DebugPuts 3 "[lindex [info level 0] 0]: creating $fullName"
file mkdir $fullName
- if {[lsearch -exact $filesMade $fullName] == -1} {
+ if {$fullName ni $filesMade} {
lappend filesMade $fullName
}
return $fullName
@@ -3106,7 +3096,7 @@ proc tcltest::removeDirectory {name {directory ""}} {
Warn "removeDirectory removing \"$fullName\":\n not a directory"
}
}
- return [file delete -force $fullName]
+ return [file delete -force -- $fullName]
}
# tcltest::viewFile --
@@ -3203,7 +3193,7 @@ proc tcltest::LeakFiles {old} {
}
set leak {}
foreach p $new {
- if {[lsearch $old $p] < 0} {
+ if {$p ni $old} {
lappend leak $p
}
}
@@ -3274,7 +3264,7 @@ proc tcltest::RestoreLocale {} {
#
proc tcltest::threadReap {} {
- if {[info commands testthread] != {}} {
+ if {[info commands testthread] ne {}} {
# testthread built into tcltest
@@ -3294,7 +3284,7 @@ proc tcltest::threadReap {} {
}
testthread errorproc ThreadError
return [llength [testthread names]]
- } elseif {[info commands thread::id] != {}} {
+ } elseif {[info commands thread::id] ne {}} {
# Thread extension
@@ -3326,15 +3316,15 @@ namespace eval tcltest {
# Set up the constraints in the testConstraints array to be lazily
# initialized by a registered initializer, or by "false" if no
# initializer is registered.
- trace variable testConstraints r [namespace code SafeFetch]
+ trace add variable testConstraints read [namespace code SafeFetch]
# Only initialize constraints at package load time if an
# [initConstraintsHook] has been pre-defined. This is only
# for compatibility support. The modern way to add a custom
# test constraint is to just call the [testConstraint] command
# straight away, without all this "hook" nonsense.
- if {[string equal [namespace current] \
- [namespace qualifiers [namespace which initConstraintsHook]]]} {
+ if {[namespace current] eq
+ [namespace qualifiers [namespace which initConstraintsHook]]} {
InitConstraints
} else {
proc initConstraintsHook {} {}
@@ -3371,15 +3361,15 @@ namespace eval tcltest {
proc LoadTimeCmdLineArgParsingRequired {} {
set required false
- if {[info exists ::argv] && [lsearch -exact $::argv -help] != -1} {
+ if {[info exists ::argv] && ("-help" in $::argv)} {
# The command line asks for -help, so give it (and exit)
# right now. ([configure] does not process -help)
set required true
}
foreach hook { PrintUsageInfoHook processCmdLineArgsHook
processCmdLineArgsAddFlagsHook } {
- if {[string equal [namespace current] [namespace qualifiers \
- [namespace which $hook]]]} {
+ if {[namespace current] eq
+ [namespace qualifiers [namespace which $hook]]} {
set required true
} else {
proc $hook args {}
diff --git a/library/tm.tcl b/library/tm.tcl
index ce8a013..55efda6 100644
--- a/library/tm.tcl
+++ b/library/tm.tcl
@@ -54,7 +54,7 @@ namespace eval ::tcl::tm {
# Export the public API
namespace export path
- namespace ensemble create -command path -subcommand {add remove list}
+ namespace ensemble create -command path -subcommands {add remove list}
}
# ::tcl::tm::path implementations --
@@ -238,6 +238,15 @@ proc ::tcl::tm::UnknownHandler {original name args} {
continue
}
+ if {[package ifneeded $pkgname $pkgversion] ne {}} {
+ # There's already a provide script registered for
+ # this version of this package. Since all units of
+ # code claiming to be the same version of the same
+ # package ought to be identical, just stick with
+ # the one we already have.
+ continue
+ }
+
# We have found a candidate, generate a "provide script"
# for it, and remember it. Note that we are using ::list
# to do this; locally [list] means something else without
@@ -260,10 +269,8 @@ proc ::tcl::tm::UnknownHandler {original name args} {
# Otherwise we still have to fallback to the regular
# package search to complete the processing.
- if {
- ($pkgname eq $name) &&
- [package vsatisfies $pkgversion {*}$args]
- } then {
+ if {($pkgname eq $name)
+ && [package vsatisfies $pkgversion {*}$args]} {
set satisfied 1
# We do not abort the loop, and keep adding provide
@@ -347,7 +354,7 @@ proc ::tcl::tm::Defaults {} {
# Calls 'path add' to paths to the list of module search paths.
proc ::tcl::tm::roots {paths} {
- foreach {major minor} [split [info tclversion] .] break
+ lassign [split [package present Tcl] .] major minor
foreach pa $paths {
set p [file join $pa tcl$major]
for {set n $minor} {$n >= 0} {incr n -1} {
diff --git a/library/tzdata/Africa/Asmara b/library/tzdata/Africa/Asmara
index 1f0f13e..1f0f13e 100755..100644
--- a/library/tzdata/Africa/Asmara
+++ b/library/tzdata/Africa/Asmara
diff --git a/library/tzdata/Africa/Cairo b/library/tzdata/Africa/Cairo
index 165d8c4..842b7b2 100644
--- a/library/tzdata/Africa/Cairo
+++ b/library/tzdata/Africa/Cairo
@@ -1,8 +1,8 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Africa/Cairo) {
- {-9223372036854775808 7500 0 LMT}
- {-2185409100 7200 0 EET}
+ {-9223372036854775808 7509 0 LMT}
+ {-2185409109 7200 0 EET}
{-929844000 10800 1 EEST}
{-923108400 7200 0 EET}
{-906170400 10800 1 EEST}
diff --git a/library/tzdata/Africa/Casablanca b/library/tzdata/Africa/Casablanca
index 0eef1ac..dec2778 100644
--- a/library/tzdata/Africa/Casablanca
+++ b/library/tzdata/Africa/Casablanca
@@ -29,4 +29,140 @@ set TZData(:Africa/Casablanca) {
{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}
+ {1404007200 0 0 WET}
+ {1406599200 3600 1 WEST}
+ {1414288800 0 0 WET}
+ {1427594400 3600 1 WEST}
+ {1434592800 0 0 WET}
+ {1437184800 3600 1 WEST}
+ {1445738400 0 0 WET}
+ {1459044000 3600 1 WEST}
+ {1465264800 0 0 WET}
+ {1467856800 3600 1 WEST}
+ {1477792800 0 0 WET}
+ {1490493600 3600 1 WEST}
+ {1495850400 0 0 WET}
+ {1498442400 3600 1 WEST}
+ {1509242400 0 0 WET}
+ {1521943200 3600 1 WEST}
+ {1526436000 0 0 WET}
+ {1529028000 3600 1 WEST}
+ {1540692000 0 0 WET}
+ {1553997600 3600 1 WEST}
+ {1557108000 0 0 WET}
+ {1559700000 3600 1 WEST}
+ {1572141600 0 0 WET}
+ {1585447200 3600 1 WEST}
+ {1587693600 0 0 WET}
+ {1590285600 3600 1 WEST}
+ {1603591200 0 0 WET}
+ {1616896800 3600 1 WEST}
+ {1618279200 0 0 WET}
+ {1620871200 3600 1 WEST}
+ {1635645600 0 0 WET}
+ {1648346400 3600 1 WEST}
+ {1648951200 0 0 WET}
+ {1651543200 3600 1 WEST}
+ {1667095200 0 0 WET}
+ {1682128800 3600 1 WEST}
+ {1698544800 0 0 WET}
+ {1712714400 3600 1 WEST}
+ {1729994400 0 0 WET}
+ {1743386400 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}
+ {2108167200 0 0 WET}
+ {2121904800 3600 1 WEST}
+ {2138839200 0 0 WET}
+ {2153354400 3600 1 WEST}
+ {2184800400 3600 1 WEST}
+ {2216250000 3600 1 WEST}
+ {2248304400 3600 1 WEST}
+ {2279754000 3600 1 WEST}
+ {2311203600 3600 1 WEST}
+ {2342653200 3600 1 WEST}
+ {2374102800 3600 1 WEST}
+ {2405552400 3600 1 WEST}
+ {2437606800 3600 1 WEST}
+ {2469056400 3600 1 WEST}
+ {2500506000 3600 1 WEST}
+ {2531955600 3600 1 WEST}
+ {2563405200 3600 1 WEST}
+ {2595459600 3600 1 WEST}
+ {2626909200 3600 1 WEST}
+ {2658358800 3600 1 WEST}
+ {2689808400 3600 1 WEST}
+ {2721258000 3600 1 WEST}
+ {2752707600 3600 1 WEST}
+ {2784762000 3600 1 WEST}
+ {2816211600 3600 1 WEST}
+ {2847661200 3600 1 WEST}
+ {2879110800 3600 1 WEST}
+ {2910560400 3600 1 WEST}
+ {2942010000 3600 1 WEST}
+ {2974064400 3600 1 WEST}
+ {3005514000 3600 1 WEST}
+ {3036963600 3600 1 WEST}
+ {3068413200 3600 1 WEST}
+ {3099862800 3600 1 WEST}
+ {3131917200 3600 1 WEST}
+ {3163366800 3600 1 WEST}
+ {3194816400 3600 1 WEST}
+ {3226266000 3600 1 WEST}
+ {3257715600 3600 1 WEST}
+ {3289165200 3600 1 WEST}
+ {3321219600 3600 1 WEST}
+ {3352669200 3600 1 WEST}
+ {3384118800 3600 1 WEST}
+ {3415568400 3600 1 WEST}
+ {3447018000 3600 1 WEST}
+ {3479072400 3600 1 WEST}
+ {3510522000 3600 1 WEST}
+ {3541971600 3600 1 WEST}
+ {3573421200 3600 1 WEST}
+ {3604870800 3600 1 WEST}
+ {3636320400 3600 1 WEST}
+ {3668374800 3600 1 WEST}
+ {3699824400 3600 1 WEST}
+ {3731274000 3600 1 WEST}
+ {3762723600 3600 1 WEST}
+ {3794173200 3600 1 WEST}
+ {3825622800 3600 1 WEST}
+ {3857677200 3600 1 WEST}
+ {3889126800 3600 1 WEST}
+ {3920576400 3600 1 WEST}
+ {3952026000 3600 1 WEST}
+ {3983475600 3600 1 WEST}
+ {4015530000 3600 1 WEST}
+ {4046979600 3600 1 WEST}
+ {4078429200 3600 1 WEST}
}
diff --git a/library/tzdata/Africa/Dar_es_Salaam b/library/tzdata/Africa/Dar_es_Salaam
index e427b9c..98151ec 100644
--- a/library/tzdata/Africa/Dar_es_Salaam
+++ b/library/tzdata/Africa/Dar_es_Salaam
@@ -3,6 +3,6 @@
set TZData(:Africa/Dar_es_Salaam) {
{-9223372036854775808 9428 0 LMT}
{-1230777428 10800 0 EAT}
- {-694321200 9885 0 BEAUT}
- {-284006685 10800 0 EAT}
+ {-694321200 9900 0 BEAUT}
+ {-284006700 10800 0 EAT}
}
diff --git a/library/tzdata/Africa/Gaborone b/library/tzdata/Africa/Gaborone
index 7753ba0..bd38673 100644
--- a/library/tzdata/Africa/Gaborone
+++ b/library/tzdata/Africa/Gaborone
@@ -2,7 +2,8 @@
set TZData(:Africa/Gaborone) {
{-9223372036854775808 6220 0 LMT}
- {-2682294220 7200 0 CAT}
+ {-2682294220 5400 0 SAST}
+ {-2109288600 7200 0 CAT}
{-829526400 10800 1 CAST}
{-813805200 7200 0 CAT}
}
diff --git a/library/tzdata/Africa/Juba b/library/tzdata/Africa/Juba
new file mode 100644
index 0000000..40551f2
--- /dev/null
+++ b/library/tzdata/Africa/Juba
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Khartoum)]} {
+ LoadTimeZoneFile Africa/Khartoum
+}
+set TZData(:Africa/Juba) $TZData(:Africa/Khartoum)
diff --git a/library/tzdata/Africa/Kampala b/library/tzdata/Africa/Kampala
index ab3f085..4cc9be1 100644
--- a/library/tzdata/Africa/Kampala
+++ b/library/tzdata/Africa/Kampala
@@ -4,6 +4,6 @@ set TZData(:Africa/Kampala) {
{-9223372036854775808 7780 0 LMT}
{-1309745380 10800 0 EAT}
{-1262314800 9000 0 BEAT}
- {-694319400 9885 0 BEAUT}
- {-410237085 10800 0 EAT}
+ {-694319400 9900 0 BEAUT}
+ {-410237100 10800 0 EAT}
}
diff --git a/library/tzdata/Africa/Nairobi b/library/tzdata/Africa/Nairobi
index 99b0d70..6846069 100644
--- a/library/tzdata/Africa/Nairobi
+++ b/library/tzdata/Africa/Nairobi
@@ -4,6 +4,6 @@ set TZData(:Africa/Nairobi) {
{-9223372036854775808 8836 0 LMT}
{-1309746436 10800 0 EAT}
{-1262314800 9000 0 BEAT}
- {-946780200 9885 0 BEAUT}
- {-315629085 10800 0 EAT}
+ {-946780200 9900 0 BEAUT}
+ {-315629100 10800 0 EAT}
}
diff --git a/library/tzdata/Africa/Tripoli b/library/tzdata/Africa/Tripoli
index e993249..ac78218 100644
--- a/library/tzdata/Africa/Tripoli
+++ b/library/tzdata/Africa/Tripoli
@@ -27,5 +27,180 @@ set TZData(:Africa/Tripoli) {
{641775600 7200 0 EET}
{844034400 3600 0 CET}
{860108400 7200 1 CEST}
- {875916000 7200 0 EET}
+ {875919600 7200 0 EET}
+ {1352505600 3600 0 CET}
+ {1364515200 7200 1 CEST}
+ {1382659200 3600 0 CET}
+ {1395964800 7200 1 CEST}
+ {1414713600 3600 0 CET}
+ {1427414400 7200 1 CEST}
+ {1446163200 3600 0 CET}
+ {1458864000 7200 1 CEST}
+ {1477612800 3600 0 CET}
+ {1490918400 7200 1 CEST}
+ {1509062400 3600 0 CET}
+ {1522368000 7200 1 CEST}
+ {1540512000 3600 0 CET}
+ {1553817600 7200 1 CEST}
+ {1571961600 3600 0 CET}
+ {1585267200 7200 1 CEST}
+ {1604016000 3600 0 CET}
+ {1616716800 7200 1 CEST}
+ {1635465600 3600 0 CET}
+ {1648166400 7200 1 CEST}
+ {1666915200 3600 0 CET}
+ {1680220800 7200 1 CEST}
+ {1698364800 3600 0 CET}
+ {1711670400 7200 1 CEST}
+ {1729814400 3600 0 CET}
+ {1743120000 7200 1 CEST}
+ {1761868800 3600 0 CET}
+ {1774569600 7200 1 CEST}
+ {1793318400 3600 0 CET}
+ {1806019200 7200 1 CEST}
+ {1824768000 3600 0 CET}
+ {1838073600 7200 1 CEST}
+ {1856217600 3600 0 CET}
+ {1869523200 7200 1 CEST}
+ {1887667200 3600 0 CET}
+ {1900972800 7200 1 CEST}
+ {1919116800 3600 0 CET}
+ {1932422400 7200 1 CEST}
+ {1951171200 3600 0 CET}
+ {1963872000 7200 1 CEST}
+ {1982620800 3600 0 CET}
+ {1995321600 7200 1 CEST}
+ {2014070400 3600 0 CET}
+ {2027376000 7200 1 CEST}
+ {2045520000 3600 0 CET}
+ {2058825600 7200 1 CEST}
+ {2076969600 3600 0 CET}
+ {2090275200 7200 1 CEST}
+ {2109024000 3600 0 CET}
+ {2121724800 7200 1 CEST}
+ {2140473600 3600 0 CET}
+ {2153174400 7200 1 CEST}
+ {2171923200 3600 0 CET}
+ {2184624000 7200 1 CEST}
+ {2203372800 3600 0 CET}
+ {2216678400 7200 1 CEST}
+ {2234822400 3600 0 CET}
+ {2248128000 7200 1 CEST}
+ {2266272000 3600 0 CET}
+ {2279577600 7200 1 CEST}
+ {2298326400 3600 0 CET}
+ {2311027200 7200 1 CEST}
+ {2329776000 3600 0 CET}
+ {2342476800 7200 1 CEST}
+ {2361225600 3600 0 CET}
+ {2374531200 7200 1 CEST}
+ {2392675200 3600 0 CET}
+ {2405980800 7200 1 CEST}
+ {2424124800 3600 0 CET}
+ {2437430400 7200 1 CEST}
+ {2455574400 3600 0 CET}
+ {2468880000 7200 1 CEST}
+ {2487628800 3600 0 CET}
+ {2500329600 7200 1 CEST}
+ {2519078400 3600 0 CET}
+ {2531779200 7200 1 CEST}
+ {2550528000 3600 0 CET}
+ {2563833600 7200 1 CEST}
+ {2581977600 3600 0 CET}
+ {2595283200 7200 1 CEST}
+ {2613427200 3600 0 CET}
+ {2626732800 7200 1 CEST}
+ {2645481600 3600 0 CET}
+ {2658182400 7200 1 CEST}
+ {2676931200 3600 0 CET}
+ {2689632000 7200 1 CEST}
+ {2708380800 3600 0 CET}
+ {2721686400 7200 1 CEST}
+ {2739830400 3600 0 CET}
+ {2753136000 7200 1 CEST}
+ {2771280000 3600 0 CET}
+ {2784585600 7200 1 CEST}
+ {2802729600 3600 0 CET}
+ {2816035200 7200 1 CEST}
+ {2834784000 3600 0 CET}
+ {2847484800 7200 1 CEST}
+ {2866233600 3600 0 CET}
+ {2878934400 7200 1 CEST}
+ {2897683200 3600 0 CET}
+ {2910988800 7200 1 CEST}
+ {2929132800 3600 0 CET}
+ {2942438400 7200 1 CEST}
+ {2960582400 3600 0 CET}
+ {2973888000 7200 1 CEST}
+ {2992636800 3600 0 CET}
+ {3005337600 7200 1 CEST}
+ {3024086400 3600 0 CET}
+ {3036787200 7200 1 CEST}
+ {3055536000 3600 0 CET}
+ {3068236800 7200 1 CEST}
+ {3086985600 3600 0 CET}
+ {3100291200 7200 1 CEST}
+ {3118435200 3600 0 CET}
+ {3131740800 7200 1 CEST}
+ {3149884800 3600 0 CET}
+ {3163190400 7200 1 CEST}
+ {3181939200 3600 0 CET}
+ {3194640000 7200 1 CEST}
+ {3213388800 3600 0 CET}
+ {3226089600 7200 1 CEST}
+ {3244838400 3600 0 CET}
+ {3258144000 7200 1 CEST}
+ {3276288000 3600 0 CET}
+ {3289593600 7200 1 CEST}
+ {3307737600 3600 0 CET}
+ {3321043200 7200 1 CEST}
+ {3339187200 3600 0 CET}
+ {3352492800 7200 1 CEST}
+ {3371241600 3600 0 CET}
+ {3383942400 7200 1 CEST}
+ {3402691200 3600 0 CET}
+ {3415392000 7200 1 CEST}
+ {3434140800 3600 0 CET}
+ {3447446400 7200 1 CEST}
+ {3465590400 3600 0 CET}
+ {3478896000 7200 1 CEST}
+ {3497040000 3600 0 CET}
+ {3510345600 7200 1 CEST}
+ {3529094400 3600 0 CET}
+ {3541795200 7200 1 CEST}
+ {3560544000 3600 0 CET}
+ {3573244800 7200 1 CEST}
+ {3591993600 3600 0 CET}
+ {3605299200 7200 1 CEST}
+ {3623443200 3600 0 CET}
+ {3636748800 7200 1 CEST}
+ {3654892800 3600 0 CET}
+ {3668198400 7200 1 CEST}
+ {3686342400 3600 0 CET}
+ {3699648000 7200 1 CEST}
+ {3718396800 3600 0 CET}
+ {3731097600 7200 1 CEST}
+ {3749846400 3600 0 CET}
+ {3762547200 7200 1 CEST}
+ {3781296000 3600 0 CET}
+ {3794601600 7200 1 CEST}
+ {3812745600 3600 0 CET}
+ {3826051200 7200 1 CEST}
+ {3844195200 3600 0 CET}
+ {3857500800 7200 1 CEST}
+ {3876249600 3600 0 CET}
+ {3888950400 7200 1 CEST}
+ {3907699200 3600 0 CET}
+ {3920400000 7200 1 CEST}
+ {3939148800 3600 0 CET}
+ {3951849600 7200 1 CEST}
+ {3970598400 3600 0 CET}
+ {3983904000 7200 1 CEST}
+ {4002048000 3600 0 CET}
+ {4015353600 7200 1 CEST}
+ {4033497600 3600 0 CET}
+ {4046803200 7200 1 CEST}
+ {4065552000 3600 0 CET}
+ {4078252800 7200 1 CEST}
+ {4097001600 3600 0 CET}
}
diff --git a/library/tzdata/America/Anguilla b/library/tzdata/America/Anguilla
index cfe7483..39a0d18 100644
--- a/library/tzdata/America/Anguilla
+++ b/library/tzdata/America/Anguilla
@@ -1,6 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-
-set TZData(:America/Anguilla) {
- {-9223372036854775808 -15136 0 LMT}
- {-1825098464 -14400 0 AST}
+if {![info exists TZData(America/Port_of_Spain)]} {
+ LoadTimeZoneFile America/Port_of_Spain
}
+set TZData(:America/Anguilla) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Araguaina b/library/tzdata/America/Araguaina
index 5073c56..e4a0d52 100644
--- a/library/tzdata/America/Araguaina
+++ b/library/tzdata/America/Araguaina
@@ -54,4 +54,7 @@ set TZData(:America/Araguaina) {
{1036292400 -7200 1 BRST}
{1045360800 -10800 0 BRT}
{1064368800 -10800 0 BRT}
+ {1350788400 -7200 0 BRST}
+ {1361066400 -10800 0 BRT}
+ {1378000800 -10800 0 BRT}
}
diff --git a/library/tzdata/America/Argentina/San_Luis b/library/tzdata/America/Argentina/San_Luis
index bec1554..8ca55d7 100644
--- a/library/tzdata/America/Argentina/San_Luis
+++ b/library/tzdata/America/Argentina/San_Luis
@@ -64,5 +64,5 @@ set TZData(:America/Argentina/San_Luis) {
{1205031600 -14400 0 WART}
{1223784000 -10800 1 WARST}
{1236481200 -14400 0 WART}
- {1255233600 -10800 1 WARST}
+ {1255233600 -10800 0 ART}
}
diff --git a/library/tzdata/America/Aruba b/library/tzdata/America/Aruba
index 92f182d..e02d5fc 100644
--- a/library/tzdata/America/Aruba
+++ b/library/tzdata/America/Aruba
@@ -1,7 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-
-set TZData(:America/Aruba) {
- {-9223372036854775808 -16824 0 LMT}
- {-1826738376 -16200 0 ANT}
- {-157750200 -14400 0 AST}
+if {![info exists TZData(America/Curacao)]} {
+ LoadTimeZoneFile America/Curacao
}
+set TZData(:America/Aruba) $TZData(:America/Curacao)
diff --git a/library/tzdata/America/Asuncion b/library/tzdata/America/Asuncion
index 14bbab2..9ea30da 100644
--- a/library/tzdata/America/Asuncion
+++ b/library/tzdata/America/Asuncion
@@ -82,178 +82,178 @@ set TZData(:America/Asuncion) {
{1317528000 -10800 1 PYST}
{1333854000 -14400 0 PYT}
{1349582400 -10800 1 PYST}
- {1365908400 -14400 0 PYT}
+ {1364094000 -14400 0 PYT}
{1381032000 -10800 1 PYST}
- {1397358000 -14400 0 PYT}
+ {1395543600 -14400 0 PYT}
{1412481600 -10800 1 PYST}
- {1428807600 -14400 0 PYT}
+ {1426993200 -14400 0 PYT}
{1443931200 -10800 1 PYST}
- {1460257200 -14400 0 PYT}
+ {1459047600 -14400 0 PYT}
{1475380800 -10800 1 PYST}
- {1491706800 -14400 0 PYT}
+ {1490497200 -14400 0 PYT}
{1506830400 -10800 1 PYST}
- {1523156400 -14400 0 PYT}
+ {1521946800 -14400 0 PYT}
{1538884800 -10800 1 PYST}
- {1555210800 -14400 0 PYT}
+ {1553396400 -14400 0 PYT}
{1570334400 -10800 1 PYST}
- {1586660400 -14400 0 PYT}
+ {1584846000 -14400 0 PYT}
{1601784000 -10800 1 PYST}
- {1618110000 -14400 0 PYT}
+ {1616900400 -14400 0 PYT}
{1633233600 -10800 1 PYST}
- {1649559600 -14400 0 PYT}
+ {1648350000 -14400 0 PYT}
{1664683200 -10800 1 PYST}
- {1681009200 -14400 0 PYT}
+ {1679799600 -14400 0 PYT}
{1696132800 -10800 1 PYST}
- {1713063600 -14400 0 PYT}
+ {1711249200 -14400 0 PYT}
{1728187200 -10800 1 PYST}
- {1744513200 -14400 0 PYT}
+ {1742698800 -14400 0 PYT}
{1759636800 -10800 1 PYST}
- {1775962800 -14400 0 PYT}
+ {1774148400 -14400 0 PYT}
{1791086400 -10800 1 PYST}
- {1807412400 -14400 0 PYT}
+ {1806202800 -14400 0 PYT}
{1822536000 -10800 1 PYST}
- {1838862000 -14400 0 PYT}
+ {1837652400 -14400 0 PYT}
{1853985600 -10800 1 PYST}
- {1870311600 -14400 0 PYT}
+ {1869102000 -14400 0 PYT}
{1886040000 -10800 1 PYST}
- {1902366000 -14400 0 PYT}
+ {1900551600 -14400 0 PYT}
{1917489600 -10800 1 PYST}
- {1933815600 -14400 0 PYT}
+ {1932001200 -14400 0 PYT}
{1948939200 -10800 1 PYST}
- {1965265200 -14400 0 PYT}
+ {1964055600 -14400 0 PYT}
{1980388800 -10800 1 PYST}
- {1996714800 -14400 0 PYT}
+ {1995505200 -14400 0 PYT}
{2011838400 -10800 1 PYST}
- {2028164400 -14400 0 PYT}
+ {2026954800 -14400 0 PYT}
{2043288000 -10800 1 PYST}
- {2059614000 -14400 0 PYT}
+ {2058404400 -14400 0 PYT}
{2075342400 -10800 1 PYST}
- {2091668400 -14400 0 PYT}
+ {2089854000 -14400 0 PYT}
{2106792000 -10800 1 PYST}
- {2123118000 -14400 0 PYT}
+ {2121303600 -14400 0 PYT}
{2138241600 -10800 1 PYST}
- {2154567600 -14400 0 PYT}
+ {2153358000 -14400 0 PYT}
{2169691200 -10800 1 PYST}
- {2186017200 -14400 0 PYT}
+ {2184807600 -14400 0 PYT}
{2201140800 -10800 1 PYST}
- {2217466800 -14400 0 PYT}
+ {2216257200 -14400 0 PYT}
{2233195200 -10800 1 PYST}
- {2249521200 -14400 0 PYT}
+ {2247706800 -14400 0 PYT}
{2264644800 -10800 1 PYST}
- {2280970800 -14400 0 PYT}
+ {2279156400 -14400 0 PYT}
{2296094400 -10800 1 PYST}
- {2312420400 -14400 0 PYT}
+ {2310606000 -14400 0 PYT}
{2327544000 -10800 1 PYST}
- {2343870000 -14400 0 PYT}
+ {2342660400 -14400 0 PYT}
{2358993600 -10800 1 PYST}
- {2375319600 -14400 0 PYT}
+ {2374110000 -14400 0 PYT}
{2390443200 -10800 1 PYST}
- {2406769200 -14400 0 PYT}
+ {2405559600 -14400 0 PYT}
{2422497600 -10800 1 PYST}
- {2438823600 -14400 0 PYT}
+ {2437009200 -14400 0 PYT}
{2453947200 -10800 1 PYST}
- {2470273200 -14400 0 PYT}
+ {2468458800 -14400 0 PYT}
{2485396800 -10800 1 PYST}
- {2501722800 -14400 0 PYT}
+ {2500513200 -14400 0 PYT}
{2516846400 -10800 1 PYST}
- {2533172400 -14400 0 PYT}
+ {2531962800 -14400 0 PYT}
{2548296000 -10800 1 PYST}
- {2564622000 -14400 0 PYT}
+ {2563412400 -14400 0 PYT}
{2579745600 -10800 1 PYST}
- {2596676400 -14400 0 PYT}
+ {2594862000 -14400 0 PYT}
{2611800000 -10800 1 PYST}
- {2628126000 -14400 0 PYT}
+ {2626311600 -14400 0 PYT}
{2643249600 -10800 1 PYST}
- {2659575600 -14400 0 PYT}
+ {2657761200 -14400 0 PYT}
{2674699200 -10800 1 PYST}
- {2691025200 -14400 0 PYT}
+ {2689815600 -14400 0 PYT}
{2706148800 -10800 1 PYST}
- {2722474800 -14400 0 PYT}
+ {2721265200 -14400 0 PYT}
{2737598400 -10800 1 PYST}
- {2753924400 -14400 0 PYT}
+ {2752714800 -14400 0 PYT}
{2769652800 -10800 1 PYST}
- {2785978800 -14400 0 PYT}
+ {2784164400 -14400 0 PYT}
{2801102400 -10800 1 PYST}
- {2817428400 -14400 0 PYT}
+ {2815614000 -14400 0 PYT}
{2832552000 -10800 1 PYST}
- {2848878000 -14400 0 PYT}
+ {2847668400 -14400 0 PYT}
{2864001600 -10800 1 PYST}
- {2880327600 -14400 0 PYT}
+ {2879118000 -14400 0 PYT}
{2895451200 -10800 1 PYST}
- {2911777200 -14400 0 PYT}
+ {2910567600 -14400 0 PYT}
{2926900800 -10800 1 PYST}
- {2943226800 -14400 0 PYT}
+ {2942017200 -14400 0 PYT}
{2958955200 -10800 1 PYST}
- {2975281200 -14400 0 PYT}
+ {2973466800 -14400 0 PYT}
{2990404800 -10800 1 PYST}
- {3006730800 -14400 0 PYT}
+ {3004916400 -14400 0 PYT}
{3021854400 -10800 1 PYST}
- {3038180400 -14400 0 PYT}
+ {3036970800 -14400 0 PYT}
{3053304000 -10800 1 PYST}
- {3069630000 -14400 0 PYT}
+ {3068420400 -14400 0 PYT}
{3084753600 -10800 1 PYST}
- {3101079600 -14400 0 PYT}
+ {3099870000 -14400 0 PYT}
{3116808000 -10800 1 PYST}
- {3133134000 -14400 0 PYT}
+ {3131319600 -14400 0 PYT}
{3148257600 -10800 1 PYST}
- {3164583600 -14400 0 PYT}
+ {3162769200 -14400 0 PYT}
{3179707200 -10800 1 PYST}
- {3196033200 -14400 0 PYT}
+ {3194218800 -14400 0 PYT}
{3211156800 -10800 1 PYST}
- {3227482800 -14400 0 PYT}
+ {3226273200 -14400 0 PYT}
{3242606400 -10800 1 PYST}
- {3258932400 -14400 0 PYT}
+ {3257722800 -14400 0 PYT}
{3274056000 -10800 1 PYST}
- {3290382000 -14400 0 PYT}
+ {3289172400 -14400 0 PYT}
{3306110400 -10800 1 PYST}
- {3322436400 -14400 0 PYT}
+ {3320622000 -14400 0 PYT}
{3337560000 -10800 1 PYST}
- {3353886000 -14400 0 PYT}
+ {3352071600 -14400 0 PYT}
{3369009600 -10800 1 PYST}
- {3385335600 -14400 0 PYT}
+ {3384126000 -14400 0 PYT}
{3400459200 -10800 1 PYST}
- {3416785200 -14400 0 PYT}
+ {3415575600 -14400 0 PYT}
{3431908800 -10800 1 PYST}
- {3448234800 -14400 0 PYT}
+ {3447025200 -14400 0 PYT}
{3463358400 -10800 1 PYST}
- {3480289200 -14400 0 PYT}
+ {3478474800 -14400 0 PYT}
{3495412800 -10800 1 PYST}
- {3511738800 -14400 0 PYT}
+ {3509924400 -14400 0 PYT}
{3526862400 -10800 1 PYST}
- {3543188400 -14400 0 PYT}
+ {3541374000 -14400 0 PYT}
{3558312000 -10800 1 PYST}
- {3574638000 -14400 0 PYT}
+ {3573428400 -14400 0 PYT}
{3589761600 -10800 1 PYST}
- {3606087600 -14400 0 PYT}
+ {3604878000 -14400 0 PYT}
{3621211200 -10800 1 PYST}
- {3637537200 -14400 0 PYT}
+ {3636327600 -14400 0 PYT}
{3653265600 -10800 1 PYST}
- {3669591600 -14400 0 PYT}
+ {3667777200 -14400 0 PYT}
{3684715200 -10800 1 PYST}
- {3701041200 -14400 0 PYT}
+ {3699226800 -14400 0 PYT}
{3716164800 -10800 1 PYST}
- {3732490800 -14400 0 PYT}
+ {3731281200 -14400 0 PYT}
{3747614400 -10800 1 PYST}
- {3763940400 -14400 0 PYT}
+ {3762730800 -14400 0 PYT}
{3779064000 -10800 1 PYST}
- {3795390000 -14400 0 PYT}
+ {3794180400 -14400 0 PYT}
{3810513600 -10800 1 PYST}
- {3826839600 -14400 0 PYT}
+ {3825630000 -14400 0 PYT}
{3842568000 -10800 1 PYST}
- {3858894000 -14400 0 PYT}
+ {3857079600 -14400 0 PYT}
{3874017600 -10800 1 PYST}
- {3890343600 -14400 0 PYT}
+ {3888529200 -14400 0 PYT}
{3905467200 -10800 1 PYST}
- {3921793200 -14400 0 PYT}
+ {3920583600 -14400 0 PYT}
{3936916800 -10800 1 PYST}
- {3953242800 -14400 0 PYT}
+ {3952033200 -14400 0 PYT}
{3968366400 -10800 1 PYST}
- {3984692400 -14400 0 PYT}
+ {3983482800 -14400 0 PYT}
{4000420800 -10800 1 PYST}
- {4016746800 -14400 0 PYT}
+ {4014932400 -14400 0 PYT}
{4031870400 -10800 1 PYST}
- {4048196400 -14400 0 PYT}
+ {4046382000 -14400 0 PYT}
{4063320000 -10800 1 PYST}
- {4079646000 -14400 0 PYT}
+ {4077831600 -14400 0 PYT}
{4094769600 -10800 1 PYST}
}
diff --git a/library/tzdata/America/Atikokan b/library/tzdata/America/Atikokan
index ca0ac1c..e72b04f 100755..100644
--- a/library/tzdata/America/Atikokan
+++ b/library/tzdata/America/Atikokan
@@ -4,7 +4,7 @@ set TZData(:America/Atikokan) {
{-9223372036854775808 -21988 0 LMT}
{-2366733212 -21600 0 CST}
{-1632067200 -18000 1 CDT}
- {-1614790800 -21600 0 CST}
+ {-1615136400 -21600 0 CST}
{-923248800 -18000 1 CDT}
{-880214400 -18000 0 CWT}
{-769395600 -18000 1 CPT}
diff --git a/library/tzdata/America/Bahia b/library/tzdata/America/Bahia
index b10a939..ac67b71 100644
--- a/library/tzdata/America/Bahia
+++ b/library/tzdata/America/Bahia
@@ -62,4 +62,7 @@ set TZData(:America/Bahia) {
{1036292400 -7200 1 BRST}
{1045360800 -10800 0 BRT}
{1064368800 -10800 0 BRT}
+ {1318734000 -7200 0 BRST}
+ {1330221600 -10800 0 BRT}
+ {1350784800 -10800 0 BRT}
}
diff --git a/library/tzdata/America/Barbados b/library/tzdata/America/Barbados
index 5c06408..ea17073 100644
--- a/library/tzdata/America/Barbados
+++ b/library/tzdata/America/Barbados
@@ -1,9 +1,9 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:America/Barbados) {
- {-9223372036854775808 -14308 0 LMT}
- {-1451678492 -14308 0 BMT}
- {-1199217692 -14400 0 AST}
+ {-9223372036854775808 -14309 0 LMT}
+ {-1451678491 -14309 0 BMT}
+ {-1199217691 -14400 0 AST}
{234943200 -10800 1 ADT}
{244616400 -14400 0 AST}
{261554400 -10800 1 ADT}
diff --git a/library/tzdata/America/Blanc-Sablon b/library/tzdata/America/Blanc-Sablon
index 47f161a..d5485e8 100755..100644
--- a/library/tzdata/America/Blanc-Sablon
+++ b/library/tzdata/America/Blanc-Sablon
@@ -4,7 +4,7 @@ set TZData(:America/Blanc-Sablon) {
{-9223372036854775808 -13708 0 LMT}
{-2713896692 -14400 0 AST}
{-1632074400 -10800 1 ADT}
- {-1614798000 -14400 0 AST}
+ {-1615143600 -14400 0 AST}
{-880221600 -10800 1 AWT}
{-769395600 -10800 1 APT}
{-765399600 -14400 0 AST}
diff --git a/library/tzdata/America/Bogota b/library/tzdata/America/Bogota
index f727d17..b28abc1 100644
--- a/library/tzdata/America/Bogota
+++ b/library/tzdata/America/Bogota
@@ -1,9 +1,9 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:America/Bogota) {
- {-9223372036854775808 -17780 0 LMT}
- {-2707671820 -17780 0 BMT}
- {-1739041420 -18000 0 COT}
+ {-9223372036854775808 -17776 0 LMT}
+ {-2707671824 -17776 0 BMT}
+ {-1739041424 -18000 0 COT}
{704869200 -14400 1 COST}
{733896000 -18000 0 COT}
}
diff --git a/library/tzdata/America/Cayman b/library/tzdata/America/Cayman
index ab5d12b..3e2e3cc 100644
--- a/library/tzdata/America/Cayman
+++ b/library/tzdata/America/Cayman
@@ -2,6 +2,6 @@
set TZData(:America/Cayman) {
{-9223372036854775808 -19532 0 LMT}
- {-2524502068 -18432 0 KMT}
- {-1827687168 -18000 0 EST}
+ {-2524502068 -18431 0 KMT}
+ {-1827687169 -18000 0 EST}
}
diff --git a/library/tzdata/America/Costa_Rica b/library/tzdata/America/Costa_Rica
index 04420a4..8fc9343 100644
--- a/library/tzdata/America/Costa_Rica
+++ b/library/tzdata/America/Costa_Rica
@@ -1,9 +1,9 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:America/Costa_Rica) {
- {-9223372036854775808 -20180 0 LMT}
- {-2524501420 -20180 0 SJMT}
- {-1545071020 -21600 0 CST}
+ {-9223372036854775808 -20173 0 LMT}
+ {-2524501427 -20173 0 SJMT}
+ {-1545071027 -21600 0 CST}
{288770400 -18000 1 CDT}
{297234000 -21600 0 CST}
{320220000 -18000 1 CDT}
diff --git a/library/tzdata/America/Creston b/library/tzdata/America/Creston
new file mode 100644
index 0000000..30369a9
--- /dev/null
+++ b/library/tzdata/America/Creston
@@ -0,0 +1,8 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Creston) {
+ {-9223372036854775808 -27964 0 LMT}
+ {-2713882436 -25200 0 MST}
+ {-1680454800 -28800 0 PST}
+ {-1627833600 -25200 0 MST}
+}
diff --git a/library/tzdata/America/Curacao b/library/tzdata/America/Curacao
index 443a319..5189e9c 100644
--- a/library/tzdata/America/Curacao
+++ b/library/tzdata/America/Curacao
@@ -1,7 +1,7 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:America/Curacao) {
- {-9223372036854775808 -16544 0 LMT}
- {-1826738656 -16200 0 ANT}
+ {-9223372036854775808 -16547 0 LMT}
+ {-1826738653 -16200 0 ANT}
{-157750200 -14400 0 AST}
}
diff --git a/library/tzdata/America/Dawson_Creek b/library/tzdata/America/Dawson_Creek
index 9f8c921..a0b5c44 100644
--- a/library/tzdata/America/Dawson_Creek
+++ b/library/tzdata/America/Dawson_Creek
@@ -4,7 +4,7 @@ set TZData(:America/Dawson_Creek) {
{-9223372036854775808 -28856 0 LMT}
{-2713881544 -28800 0 PST}
{-1632060000 -25200 1 PDT}
- {-1614783600 -28800 0 PST}
+ {-1615129200 -28800 0 PST}
{-880207200 -25200 1 PWT}
{-769395600 -25200 1 PPT}
{-765385200 -28800 0 PST}
diff --git a/library/tzdata/America/Dominica b/library/tzdata/America/Dominica
index 3503a65..b97cb0e 100644
--- a/library/tzdata/America/Dominica
+++ b/library/tzdata/America/Dominica
@@ -1,6 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-
-set TZData(:America/Dominica) {
- {-9223372036854775808 -14736 0 LMT}
- {-1846266804 -14400 0 AST}
+if {![info exists TZData(America/Port_of_Spain)]} {
+ LoadTimeZoneFile America/Port_of_Spain
}
+set TZData(:America/Dominica) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Edmonton b/library/tzdata/America/Edmonton
index c4252f8..1ed38be 100644
--- a/library/tzdata/America/Edmonton
+++ b/library/tzdata/America/Edmonton
@@ -4,7 +4,7 @@ set TZData(:America/Edmonton) {
{-9223372036854775808 -27232 0 LMT}
{-1998663968 -25200 0 MST}
{-1632063600 -21600 1 MDT}
- {-1614787200 -25200 0 MST}
+ {-1615132800 -25200 0 MST}
{-1600614000 -21600 1 MDT}
{-1596816000 -25200 0 MST}
{-1567954800 -21600 1 MDT}
diff --git a/library/tzdata/America/Glace_Bay b/library/tzdata/America/Glace_Bay
index 84b4822..8ee9eec 100644
--- a/library/tzdata/America/Glace_Bay
+++ b/library/tzdata/America/Glace_Bay
@@ -4,7 +4,7 @@ set TZData(:America/Glace_Bay) {
{-9223372036854775808 -14388 0 LMT}
{-2131646412 -14400 0 AST}
{-1632074400 -10800 1 ADT}
- {-1614798000 -14400 0 AST}
+ {-1615143600 -14400 0 AST}
{-880221600 -10800 1 AWT}
{-769395600 -10800 1 APT}
{-765399600 -14400 0 AST}
diff --git a/library/tzdata/America/Goose_Bay b/library/tzdata/America/Goose_Bay
index f93b612..7b7b3d8 100644
--- a/library/tzdata/America/Goose_Bay
+++ b/library/tzdata/America/Goose_Bay
@@ -5,7 +5,7 @@ set TZData(:America/Goose_Bay) {
{-2713895900 -12652 0 NST}
{-1640982548 -12652 0 NST}
{-1632076148 -9052 1 NDT}
- {-1614799748 -12652 0 NST}
+ {-1615145348 -12652 0 NST}
{-1609446548 -12652 0 NST}
{-1096921748 -12600 0 NST}
{-1072989000 -12600 0 NST}
@@ -157,181 +157,182 @@ set TZData(:America/Goose_Bay) {
{1268539260 -10800 1 ADT}
{1289098860 -14400 0 AST}
{1299988860 -10800 1 ADT}
- {1320548460 -14400 0 AST}
- {1331438460 -10800 1 ADT}
- {1351998060 -14400 0 AST}
- {1362888060 -10800 1 ADT}
- {1383447660 -14400 0 AST}
- {1394337660 -10800 1 ADT}
- {1414897260 -14400 0 AST}
- {1425787260 -10800 1 ADT}
- {1446346860 -14400 0 AST}
- {1457841660 -10800 1 ADT}
- {1478401260 -14400 0 AST}
- {1489291260 -10800 1 ADT}
- {1509850860 -14400 0 AST}
- {1520740860 -10800 1 ADT}
- {1541300460 -14400 0 AST}
- {1552190460 -10800 1 ADT}
- {1572750060 -14400 0 AST}
- {1583640060 -10800 1 ADT}
- {1604199660 -14400 0 AST}
- {1615694460 -10800 1 ADT}
- {1636254060 -14400 0 AST}
- {1647144060 -10800 1 ADT}
- {1667703660 -14400 0 AST}
- {1678593660 -10800 1 ADT}
- {1699153260 -14400 0 AST}
- {1710043260 -10800 1 ADT}
- {1730602860 -14400 0 AST}
- {1741492860 -10800 1 ADT}
- {1762052460 -14400 0 AST}
- {1772942460 -10800 1 ADT}
- {1793502060 -14400 0 AST}
- {1804996860 -10800 1 ADT}
- {1825556460 -14400 0 AST}
- {1836446460 -10800 1 ADT}
- {1857006060 -14400 0 AST}
- {1867896060 -10800 1 ADT}
- {1888455660 -14400 0 AST}
- {1899345660 -10800 1 ADT}
- {1919905260 -14400 0 AST}
- {1930795260 -10800 1 ADT}
- {1951354860 -14400 0 AST}
- {1962849660 -10800 1 ADT}
- {1983409260 -14400 0 AST}
- {1994299260 -10800 1 ADT}
- {2014858860 -14400 0 AST}
- {2025748860 -10800 1 ADT}
- {2046308460 -14400 0 AST}
- {2057198460 -10800 1 ADT}
- {2077758060 -14400 0 AST}
- {2088648060 -10800 1 ADT}
- {2109207660 -14400 0 AST}
- {2120097660 -10800 1 ADT}
- {2140657260 -14400 0 AST}
- {2152152060 -10800 1 ADT}
- {2172711660 -14400 0 AST}
- {2183601660 -10800 1 ADT}
- {2204161260 -14400 0 AST}
- {2215051260 -10800 1 ADT}
- {2235610860 -14400 0 AST}
- {2246500860 -10800 1 ADT}
- {2267060460 -14400 0 AST}
- {2277950460 -10800 1 ADT}
- {2298510060 -14400 0 AST}
- {2309400060 -10800 1 ADT}
- {2329959660 -14400 0 AST}
- {2341454460 -10800 1 ADT}
- {2362014060 -14400 0 AST}
- {2372904060 -10800 1 ADT}
- {2393463660 -14400 0 AST}
- {2404353660 -10800 1 ADT}
- {2424913260 -14400 0 AST}
- {2435803260 -10800 1 ADT}
- {2456362860 -14400 0 AST}
- {2467252860 -10800 1 ADT}
- {2487812460 -14400 0 AST}
- {2499307260 -10800 1 ADT}
- {2519866860 -14400 0 AST}
- {2530756860 -10800 1 ADT}
- {2551316460 -14400 0 AST}
- {2562206460 -10800 1 ADT}
- {2582766060 -14400 0 AST}
- {2593656060 -10800 1 ADT}
- {2614215660 -14400 0 AST}
- {2625105660 -10800 1 ADT}
- {2645665260 -14400 0 AST}
- {2656555260 -10800 1 ADT}
- {2677114860 -14400 0 AST}
- {2688609660 -10800 1 ADT}
- {2709169260 -14400 0 AST}
- {2720059260 -10800 1 ADT}
- {2740618860 -14400 0 AST}
- {2751508860 -10800 1 ADT}
- {2772068460 -14400 0 AST}
- {2782958460 -10800 1 ADT}
- {2803518060 -14400 0 AST}
- {2814408060 -10800 1 ADT}
- {2834967660 -14400 0 AST}
- {2846462460 -10800 1 ADT}
- {2867022060 -14400 0 AST}
- {2877912060 -10800 1 ADT}
- {2898471660 -14400 0 AST}
- {2909361660 -10800 1 ADT}
- {2929921260 -14400 0 AST}
- {2940811260 -10800 1 ADT}
- {2961370860 -14400 0 AST}
- {2972260860 -10800 1 ADT}
- {2992820460 -14400 0 AST}
- {3003710460 -10800 1 ADT}
- {3024270060 -14400 0 AST}
- {3035764860 -10800 1 ADT}
- {3056324460 -14400 0 AST}
- {3067214460 -10800 1 ADT}
- {3087774060 -14400 0 AST}
- {3098664060 -10800 1 ADT}
- {3119223660 -14400 0 AST}
- {3130113660 -10800 1 ADT}
- {3150673260 -14400 0 AST}
- {3161563260 -10800 1 ADT}
- {3182122860 -14400 0 AST}
- {3193012860 -10800 1 ADT}
- {3213572460 -14400 0 AST}
- {3225067260 -10800 1 ADT}
- {3245626860 -14400 0 AST}
- {3256516860 -10800 1 ADT}
- {3277076460 -14400 0 AST}
- {3287966460 -10800 1 ADT}
- {3308526060 -14400 0 AST}
- {3319416060 -10800 1 ADT}
- {3339975660 -14400 0 AST}
- {3350865660 -10800 1 ADT}
- {3371425260 -14400 0 AST}
- {3382920060 -10800 1 ADT}
- {3403479660 -14400 0 AST}
- {3414369660 -10800 1 ADT}
- {3434929260 -14400 0 AST}
- {3445819260 -10800 1 ADT}
- {3466378860 -14400 0 AST}
- {3477268860 -10800 1 ADT}
- {3497828460 -14400 0 AST}
- {3508718460 -10800 1 ADT}
- {3529278060 -14400 0 AST}
- {3540168060 -10800 1 ADT}
- {3560727660 -14400 0 AST}
- {3572222460 -10800 1 ADT}
- {3592782060 -14400 0 AST}
- {3603672060 -10800 1 ADT}
- {3624231660 -14400 0 AST}
- {3635121660 -10800 1 ADT}
- {3655681260 -14400 0 AST}
- {3666571260 -10800 1 ADT}
- {3687130860 -14400 0 AST}
- {3698020860 -10800 1 ADT}
- {3718580460 -14400 0 AST}
- {3730075260 -10800 1 ADT}
- {3750634860 -14400 0 AST}
- {3761524860 -10800 1 ADT}
- {3782084460 -14400 0 AST}
- {3792974460 -10800 1 ADT}
- {3813534060 -14400 0 AST}
- {3824424060 -10800 1 ADT}
- {3844983660 -14400 0 AST}
- {3855873660 -10800 1 ADT}
- {3876433260 -14400 0 AST}
- {3887323260 -10800 1 ADT}
- {3907882860 -14400 0 AST}
- {3919377660 -10800 1 ADT}
- {3939937260 -14400 0 AST}
- {3950827260 -10800 1 ADT}
- {3971386860 -14400 0 AST}
- {3982276860 -10800 1 ADT}
- {4002836460 -14400 0 AST}
- {4013726460 -10800 1 ADT}
- {4034286060 -14400 0 AST}
- {4045176060 -10800 1 ADT}
- {4065735660 -14400 0 AST}
- {4076625660 -10800 1 ADT}
- {4097185260 -14400 0 AST}
+ {1320116400 -10800 0 ADT}
+ {1320555600 -14400 0 AST}
+ {1331445600 -10800 1 ADT}
+ {1352005200 -14400 0 AST}
+ {1362895200 -10800 1 ADT}
+ {1383454800 -14400 0 AST}
+ {1394344800 -10800 1 ADT}
+ {1414904400 -14400 0 AST}
+ {1425794400 -10800 1 ADT}
+ {1446354000 -14400 0 AST}
+ {1457848800 -10800 1 ADT}
+ {1478408400 -14400 0 AST}
+ {1489298400 -10800 1 ADT}
+ {1509858000 -14400 0 AST}
+ {1520748000 -10800 1 ADT}
+ {1541307600 -14400 0 AST}
+ {1552197600 -10800 1 ADT}
+ {1572757200 -14400 0 AST}
+ {1583647200 -10800 1 ADT}
+ {1604206800 -14400 0 AST}
+ {1615701600 -10800 1 ADT}
+ {1636261200 -14400 0 AST}
+ {1647151200 -10800 1 ADT}
+ {1667710800 -14400 0 AST}
+ {1678600800 -10800 1 ADT}
+ {1699160400 -14400 0 AST}
+ {1710050400 -10800 1 ADT}
+ {1730610000 -14400 0 AST}
+ {1741500000 -10800 1 ADT}
+ {1762059600 -14400 0 AST}
+ {1772949600 -10800 1 ADT}
+ {1793509200 -14400 0 AST}
+ {1805004000 -10800 1 ADT}
+ {1825563600 -14400 0 AST}
+ {1836453600 -10800 1 ADT}
+ {1857013200 -14400 0 AST}
+ {1867903200 -10800 1 ADT}
+ {1888462800 -14400 0 AST}
+ {1899352800 -10800 1 ADT}
+ {1919912400 -14400 0 AST}
+ {1930802400 -10800 1 ADT}
+ {1951362000 -14400 0 AST}
+ {1962856800 -10800 1 ADT}
+ {1983416400 -14400 0 AST}
+ {1994306400 -10800 1 ADT}
+ {2014866000 -14400 0 AST}
+ {2025756000 -10800 1 ADT}
+ {2046315600 -14400 0 AST}
+ {2057205600 -10800 1 ADT}
+ {2077765200 -14400 0 AST}
+ {2088655200 -10800 1 ADT}
+ {2109214800 -14400 0 AST}
+ {2120104800 -10800 1 ADT}
+ {2140664400 -14400 0 AST}
+ {2152159200 -10800 1 ADT}
+ {2172718800 -14400 0 AST}
+ {2183608800 -10800 1 ADT}
+ {2204168400 -14400 0 AST}
+ {2215058400 -10800 1 ADT}
+ {2235618000 -14400 0 AST}
+ {2246508000 -10800 1 ADT}
+ {2267067600 -14400 0 AST}
+ {2277957600 -10800 1 ADT}
+ {2298517200 -14400 0 AST}
+ {2309407200 -10800 1 ADT}
+ {2329966800 -14400 0 AST}
+ {2341461600 -10800 1 ADT}
+ {2362021200 -14400 0 AST}
+ {2372911200 -10800 1 ADT}
+ {2393470800 -14400 0 AST}
+ {2404360800 -10800 1 ADT}
+ {2424920400 -14400 0 AST}
+ {2435810400 -10800 1 ADT}
+ {2456370000 -14400 0 AST}
+ {2467260000 -10800 1 ADT}
+ {2487819600 -14400 0 AST}
+ {2499314400 -10800 1 ADT}
+ {2519874000 -14400 0 AST}
+ {2530764000 -10800 1 ADT}
+ {2551323600 -14400 0 AST}
+ {2562213600 -10800 1 ADT}
+ {2582773200 -14400 0 AST}
+ {2593663200 -10800 1 ADT}
+ {2614222800 -14400 0 AST}
+ {2625112800 -10800 1 ADT}
+ {2645672400 -14400 0 AST}
+ {2656562400 -10800 1 ADT}
+ {2677122000 -14400 0 AST}
+ {2688616800 -10800 1 ADT}
+ {2709176400 -14400 0 AST}
+ {2720066400 -10800 1 ADT}
+ {2740626000 -14400 0 AST}
+ {2751516000 -10800 1 ADT}
+ {2772075600 -14400 0 AST}
+ {2782965600 -10800 1 ADT}
+ {2803525200 -14400 0 AST}
+ {2814415200 -10800 1 ADT}
+ {2834974800 -14400 0 AST}
+ {2846469600 -10800 1 ADT}
+ {2867029200 -14400 0 AST}
+ {2877919200 -10800 1 ADT}
+ {2898478800 -14400 0 AST}
+ {2909368800 -10800 1 ADT}
+ {2929928400 -14400 0 AST}
+ {2940818400 -10800 1 ADT}
+ {2961378000 -14400 0 AST}
+ {2972268000 -10800 1 ADT}
+ {2992827600 -14400 0 AST}
+ {3003717600 -10800 1 ADT}
+ {3024277200 -14400 0 AST}
+ {3035772000 -10800 1 ADT}
+ {3056331600 -14400 0 AST}
+ {3067221600 -10800 1 ADT}
+ {3087781200 -14400 0 AST}
+ {3098671200 -10800 1 ADT}
+ {3119230800 -14400 0 AST}
+ {3130120800 -10800 1 ADT}
+ {3150680400 -14400 0 AST}
+ {3161570400 -10800 1 ADT}
+ {3182130000 -14400 0 AST}
+ {3193020000 -10800 1 ADT}
+ {3213579600 -14400 0 AST}
+ {3225074400 -10800 1 ADT}
+ {3245634000 -14400 0 AST}
+ {3256524000 -10800 1 ADT}
+ {3277083600 -14400 0 AST}
+ {3287973600 -10800 1 ADT}
+ {3308533200 -14400 0 AST}
+ {3319423200 -10800 1 ADT}
+ {3339982800 -14400 0 AST}
+ {3350872800 -10800 1 ADT}
+ {3371432400 -14400 0 AST}
+ {3382927200 -10800 1 ADT}
+ {3403486800 -14400 0 AST}
+ {3414376800 -10800 1 ADT}
+ {3434936400 -14400 0 AST}
+ {3445826400 -10800 1 ADT}
+ {3466386000 -14400 0 AST}
+ {3477276000 -10800 1 ADT}
+ {3497835600 -14400 0 AST}
+ {3508725600 -10800 1 ADT}
+ {3529285200 -14400 0 AST}
+ {3540175200 -10800 1 ADT}
+ {3560734800 -14400 0 AST}
+ {3572229600 -10800 1 ADT}
+ {3592789200 -14400 0 AST}
+ {3603679200 -10800 1 ADT}
+ {3624238800 -14400 0 AST}
+ {3635128800 -10800 1 ADT}
+ {3655688400 -14400 0 AST}
+ {3666578400 -10800 1 ADT}
+ {3687138000 -14400 0 AST}
+ {3698028000 -10800 1 ADT}
+ {3718587600 -14400 0 AST}
+ {3730082400 -10800 1 ADT}
+ {3750642000 -14400 0 AST}
+ {3761532000 -10800 1 ADT}
+ {3782091600 -14400 0 AST}
+ {3792981600 -10800 1 ADT}
+ {3813541200 -14400 0 AST}
+ {3824431200 -10800 1 ADT}
+ {3844990800 -14400 0 AST}
+ {3855880800 -10800 1 ADT}
+ {3876440400 -14400 0 AST}
+ {3887330400 -10800 1 ADT}
+ {3907890000 -14400 0 AST}
+ {3919384800 -10800 1 ADT}
+ {3939944400 -14400 0 AST}
+ {3950834400 -10800 1 ADT}
+ {3971394000 -14400 0 AST}
+ {3982284000 -10800 1 ADT}
+ {4002843600 -14400 0 AST}
+ {4013733600 -10800 1 ADT}
+ {4034293200 -14400 0 AST}
+ {4045183200 -10800 1 ADT}
+ {4065742800 -14400 0 AST}
+ {4076632800 -10800 1 ADT}
+ {4097192400 -14400 0 AST}
}
diff --git a/library/tzdata/America/Grand_Turk b/library/tzdata/America/Grand_Turk
index a455dd5..6c8ea4a 100644
--- a/library/tzdata/America/Grand_Turk
+++ b/library/tzdata/America/Grand_Turk
@@ -2,8 +2,8 @@
set TZData(:America/Grand_Turk) {
{-9223372036854775808 -17072 0 LMT}
- {-2524504528 -18432 0 KMT}
- {-1827687168 -18000 0 EST}
+ {-2524504528 -18431 0 KMT}
+ {-1827687169 -18000 0 EST}
{294217200 -14400 1 EDT}
{309938400 -18000 0 EST}
{325666800 -14400 1 EDT}
diff --git a/library/tzdata/America/Grenada b/library/tzdata/America/Grenada
index 3c2919b..92300c3 100644
--- a/library/tzdata/America/Grenada
+++ b/library/tzdata/America/Grenada
@@ -1,6 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-
-set TZData(:America/Grenada) {
- {-9223372036854775808 -14820 0 LMT}
- {-1846266780 -14400 0 AST}
+if {![info exists TZData(America/Port_of_Spain)]} {
+ LoadTimeZoneFile America/Port_of_Spain
}
+set TZData(:America/Grenada) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Guadeloupe b/library/tzdata/America/Guadeloupe
index b1987ce..aba6bd7 100644
--- a/library/tzdata/America/Guadeloupe
+++ b/library/tzdata/America/Guadeloupe
@@ -1,6 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-
-set TZData(:America/Guadeloupe) {
- {-9223372036854775808 -14768 0 LMT}
- {-1848254032 -14400 0 AST}
+if {![info exists TZData(America/Port_of_Spain)]} {
+ LoadTimeZoneFile America/Port_of_Spain
}
+set TZData(:America/Guadeloupe) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Halifax b/library/tzdata/America/Halifax
index 76f016a..08e3754 100644
--- a/library/tzdata/America/Halifax
+++ b/library/tzdata/America/Halifax
@@ -7,7 +7,7 @@ set TZData(:America/Halifax) {
{-1680469200 -14400 0 AST}
{-1640980800 -14400 0 AST}
{-1632074400 -10800 1 ADT}
- {-1614798000 -14400 0 AST}
+ {-1615143600 -14400 0 AST}
{-1609444800 -14400 0 AST}
{-1566763200 -10800 1 ADT}
{-1557090000 -14400 0 AST}
diff --git a/library/tzdata/America/Havana b/library/tzdata/America/Havana
index f37b98e..89cbc9a 100644
--- a/library/tzdata/America/Havana
+++ b/library/tzdata/America/Havana
@@ -105,181 +105,181 @@ set TZData(:America/Havana) {
{1268542800 -14400 1 CDT}
{1288501200 -18000 0 CST}
{1300597200 -14400 1 CDT}
- {1319950800 -18000 0 CST}
- {1331442000 -14400 1 CDT}
- {1351400400 -18000 0 CST}
+ {1321160400 -18000 0 CST}
+ {1333256400 -14400 1 CDT}
+ {1352005200 -18000 0 CST}
{1362891600 -14400 1 CDT}
- {1382850000 -18000 0 CST}
+ {1383454800 -18000 0 CST}
{1394341200 -14400 1 CDT}
- {1414299600 -18000 0 CST}
+ {1414904400 -18000 0 CST}
{1425790800 -14400 1 CDT}
- {1445749200 -18000 0 CST}
+ {1446354000 -18000 0 CST}
{1457845200 -14400 1 CDT}
- {1477803600 -18000 0 CST}
+ {1478408400 -18000 0 CST}
{1489294800 -14400 1 CDT}
- {1509253200 -18000 0 CST}
+ {1509858000 -18000 0 CST}
{1520744400 -14400 1 CDT}
- {1540702800 -18000 0 CST}
+ {1541307600 -18000 0 CST}
{1552194000 -14400 1 CDT}
- {1572152400 -18000 0 CST}
+ {1572757200 -18000 0 CST}
{1583643600 -14400 1 CDT}
- {1603602000 -18000 0 CST}
+ {1604206800 -18000 0 CST}
{1615698000 -14400 1 CDT}
- {1635656400 -18000 0 CST}
+ {1636261200 -18000 0 CST}
{1647147600 -14400 1 CDT}
- {1667106000 -18000 0 CST}
+ {1667710800 -18000 0 CST}
{1678597200 -14400 1 CDT}
- {1698555600 -18000 0 CST}
+ {1699160400 -18000 0 CST}
{1710046800 -14400 1 CDT}
- {1730005200 -18000 0 CST}
+ {1730610000 -18000 0 CST}
{1741496400 -14400 1 CDT}
- {1761454800 -18000 0 CST}
+ {1762059600 -18000 0 CST}
{1772946000 -14400 1 CDT}
- {1792904400 -18000 0 CST}
+ {1793509200 -18000 0 CST}
{1805000400 -14400 1 CDT}
- {1824958800 -18000 0 CST}
+ {1825563600 -18000 0 CST}
{1836450000 -14400 1 CDT}
- {1856408400 -18000 0 CST}
+ {1857013200 -18000 0 CST}
{1867899600 -14400 1 CDT}
- {1887858000 -18000 0 CST}
+ {1888462800 -18000 0 CST}
{1899349200 -14400 1 CDT}
- {1919307600 -18000 0 CST}
+ {1919912400 -18000 0 CST}
{1930798800 -14400 1 CDT}
- {1950757200 -18000 0 CST}
+ {1951362000 -18000 0 CST}
{1962853200 -14400 1 CDT}
- {1982811600 -18000 0 CST}
+ {1983416400 -18000 0 CST}
{1994302800 -14400 1 CDT}
- {2014261200 -18000 0 CST}
+ {2014866000 -18000 0 CST}
{2025752400 -14400 1 CDT}
- {2045710800 -18000 0 CST}
+ {2046315600 -18000 0 CST}
{2057202000 -14400 1 CDT}
- {2077160400 -18000 0 CST}
+ {2077765200 -18000 0 CST}
{2088651600 -14400 1 CDT}
- {2108610000 -18000 0 CST}
+ {2109214800 -18000 0 CST}
{2120101200 -14400 1 CDT}
- {2140059600 -18000 0 CST}
+ {2140664400 -18000 0 CST}
{2152155600 -14400 1 CDT}
- {2172114000 -18000 0 CST}
+ {2172718800 -18000 0 CST}
{2183605200 -14400 1 CDT}
- {2203563600 -18000 0 CST}
+ {2204168400 -18000 0 CST}
{2215054800 -14400 1 CDT}
- {2235013200 -18000 0 CST}
+ {2235618000 -18000 0 CST}
{2246504400 -14400 1 CDT}
- {2266462800 -18000 0 CST}
+ {2267067600 -18000 0 CST}
{2277954000 -14400 1 CDT}
- {2297912400 -18000 0 CST}
+ {2298517200 -18000 0 CST}
{2309403600 -14400 1 CDT}
- {2329362000 -18000 0 CST}
+ {2329966800 -18000 0 CST}
{2341458000 -14400 1 CDT}
- {2361416400 -18000 0 CST}
+ {2362021200 -18000 0 CST}
{2372907600 -14400 1 CDT}
- {2392866000 -18000 0 CST}
+ {2393470800 -18000 0 CST}
{2404357200 -14400 1 CDT}
- {2424315600 -18000 0 CST}
+ {2424920400 -18000 0 CST}
{2435806800 -14400 1 CDT}
- {2455765200 -18000 0 CST}
+ {2456370000 -18000 0 CST}
{2467256400 -14400 1 CDT}
- {2487214800 -18000 0 CST}
+ {2487819600 -18000 0 CST}
{2499310800 -14400 1 CDT}
- {2519269200 -18000 0 CST}
+ {2519874000 -18000 0 CST}
{2530760400 -14400 1 CDT}
- {2550718800 -18000 0 CST}
+ {2551323600 -18000 0 CST}
{2562210000 -14400 1 CDT}
- {2582168400 -18000 0 CST}
+ {2582773200 -18000 0 CST}
{2593659600 -14400 1 CDT}
- {2613618000 -18000 0 CST}
+ {2614222800 -18000 0 CST}
{2625109200 -14400 1 CDT}
- {2645067600 -18000 0 CST}
+ {2645672400 -18000 0 CST}
{2656558800 -14400 1 CDT}
- {2676517200 -18000 0 CST}
+ {2677122000 -18000 0 CST}
{2688613200 -14400 1 CDT}
- {2708571600 -18000 0 CST}
+ {2709176400 -18000 0 CST}
{2720062800 -14400 1 CDT}
- {2740021200 -18000 0 CST}
+ {2740626000 -18000 0 CST}
{2751512400 -14400 1 CDT}
- {2771470800 -18000 0 CST}
+ {2772075600 -18000 0 CST}
{2782962000 -14400 1 CDT}
- {2802920400 -18000 0 CST}
+ {2803525200 -18000 0 CST}
{2814411600 -14400 1 CDT}
- {2834370000 -18000 0 CST}
+ {2834974800 -18000 0 CST}
{2846466000 -14400 1 CDT}
- {2866424400 -18000 0 CST}
+ {2867029200 -18000 0 CST}
{2877915600 -14400 1 CDT}
- {2897874000 -18000 0 CST}
+ {2898478800 -18000 0 CST}
{2909365200 -14400 1 CDT}
- {2929323600 -18000 0 CST}
+ {2929928400 -18000 0 CST}
{2940814800 -14400 1 CDT}
- {2960773200 -18000 0 CST}
+ {2961378000 -18000 0 CST}
{2972264400 -14400 1 CDT}
- {2992222800 -18000 0 CST}
+ {2992827600 -18000 0 CST}
{3003714000 -14400 1 CDT}
- {3023672400 -18000 0 CST}
+ {3024277200 -18000 0 CST}
{3035768400 -14400 1 CDT}
- {3055726800 -18000 0 CST}
+ {3056331600 -18000 0 CST}
{3067218000 -14400 1 CDT}
- {3087176400 -18000 0 CST}
+ {3087781200 -18000 0 CST}
{3098667600 -14400 1 CDT}
- {3118626000 -18000 0 CST}
+ {3119230800 -18000 0 CST}
{3130117200 -14400 1 CDT}
- {3150075600 -18000 0 CST}
+ {3150680400 -18000 0 CST}
{3161566800 -14400 1 CDT}
- {3181525200 -18000 0 CST}
+ {3182130000 -18000 0 CST}
{3193016400 -14400 1 CDT}
- {3212974800 -18000 0 CST}
+ {3213579600 -18000 0 CST}
{3225070800 -14400 1 CDT}
- {3245029200 -18000 0 CST}
+ {3245634000 -18000 0 CST}
{3256520400 -14400 1 CDT}
- {3276478800 -18000 0 CST}
+ {3277083600 -18000 0 CST}
{3287970000 -14400 1 CDT}
- {3307928400 -18000 0 CST}
+ {3308533200 -18000 0 CST}
{3319419600 -14400 1 CDT}
- {3339378000 -18000 0 CST}
+ {3339982800 -18000 0 CST}
{3350869200 -14400 1 CDT}
- {3370827600 -18000 0 CST}
+ {3371432400 -18000 0 CST}
{3382923600 -14400 1 CDT}
- {3402882000 -18000 0 CST}
+ {3403486800 -18000 0 CST}
{3414373200 -14400 1 CDT}
- {3434331600 -18000 0 CST}
+ {3434936400 -18000 0 CST}
{3445822800 -14400 1 CDT}
- {3465781200 -18000 0 CST}
+ {3466386000 -18000 0 CST}
{3477272400 -14400 1 CDT}
- {3497230800 -18000 0 CST}
+ {3497835600 -18000 0 CST}
{3508722000 -14400 1 CDT}
- {3528680400 -18000 0 CST}
+ {3529285200 -18000 0 CST}
{3540171600 -14400 1 CDT}
- {3560130000 -18000 0 CST}
+ {3560734800 -18000 0 CST}
{3572226000 -14400 1 CDT}
- {3592184400 -18000 0 CST}
+ {3592789200 -18000 0 CST}
{3603675600 -14400 1 CDT}
- {3623634000 -18000 0 CST}
+ {3624238800 -18000 0 CST}
{3635125200 -14400 1 CDT}
- {3655083600 -18000 0 CST}
+ {3655688400 -18000 0 CST}
{3666574800 -14400 1 CDT}
- {3686533200 -18000 0 CST}
+ {3687138000 -18000 0 CST}
{3698024400 -14400 1 CDT}
- {3717982800 -18000 0 CST}
+ {3718587600 -18000 0 CST}
{3730078800 -14400 1 CDT}
- {3750037200 -18000 0 CST}
+ {3750642000 -18000 0 CST}
{3761528400 -14400 1 CDT}
- {3781486800 -18000 0 CST}
+ {3782091600 -18000 0 CST}
{3792978000 -14400 1 CDT}
- {3812936400 -18000 0 CST}
+ {3813541200 -18000 0 CST}
{3824427600 -14400 1 CDT}
- {3844386000 -18000 0 CST}
+ {3844990800 -18000 0 CST}
{3855877200 -14400 1 CDT}
- {3875835600 -18000 0 CST}
+ {3876440400 -18000 0 CST}
{3887326800 -14400 1 CDT}
- {3907285200 -18000 0 CST}
+ {3907890000 -18000 0 CST}
{3919381200 -14400 1 CDT}
- {3939339600 -18000 0 CST}
+ {3939944400 -18000 0 CST}
{3950830800 -14400 1 CDT}
- {3970789200 -18000 0 CST}
+ {3971394000 -18000 0 CST}
{3982280400 -14400 1 CDT}
- {4002238800 -18000 0 CST}
+ {4002843600 -18000 0 CST}
{4013730000 -14400 1 CDT}
- {4033688400 -18000 0 CST}
+ {4034293200 -18000 0 CST}
{4045179600 -14400 1 CDT}
- {4065138000 -18000 0 CST}
+ {4065742800 -18000 0 CST}
{4076629200 -14400 1 CDT}
- {4096587600 -18000 0 CST}
+ {4097192400 -18000 0 CST}
}
diff --git a/library/tzdata/America/Indiana/Petersburg b/library/tzdata/America/Indiana/Petersburg
index 6992bfc..6992bfc 100755..100644
--- a/library/tzdata/America/Indiana/Petersburg
+++ b/library/tzdata/America/Indiana/Petersburg
diff --git a/library/tzdata/America/Indiana/Tell_City b/library/tzdata/America/Indiana/Tell_City
index 9eebcf7..9eebcf7 100755..100644
--- a/library/tzdata/America/Indiana/Tell_City
+++ b/library/tzdata/America/Indiana/Tell_City
diff --git a/library/tzdata/America/Indiana/Vincennes b/library/tzdata/America/Indiana/Vincennes
index 1af7fc9..1af7fc9 100755..100644
--- a/library/tzdata/America/Indiana/Vincennes
+++ b/library/tzdata/America/Indiana/Vincennes
diff --git a/library/tzdata/America/Indiana/Winamac b/library/tzdata/America/Indiana/Winamac
index fb6cd37..fb6cd37 100755..100644
--- a/library/tzdata/America/Indiana/Winamac
+++ b/library/tzdata/America/Indiana/Winamac
diff --git a/library/tzdata/America/Jamaica b/library/tzdata/America/Jamaica
index 393d90a8..682e47c 100644
--- a/library/tzdata/America/Jamaica
+++ b/library/tzdata/America/Jamaica
@@ -1,9 +1,9 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:America/Jamaica) {
- {-9223372036854775808 -18432 0 LMT}
- {-2524503168 -18432 0 KMT}
- {-1827687168 -18000 0 EST}
+ {-9223372036854775808 -18431 0 LMT}
+ {-2524503169 -18431 0 KMT}
+ {-1827687169 -18000 0 EST}
{136364400 -14400 0 EDT}
{152085600 -18000 0 EST}
{162370800 -14400 1 EDT}
diff --git a/library/tzdata/America/Marigot b/library/tzdata/America/Marigot
index 9f3f8f6..c2b3873 100644
--- a/library/tzdata/America/Marigot
+++ b/library/tzdata/America/Marigot
@@ -1,5 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-if {![info exists TZData(America/Guadeloupe)]} {
- LoadTimeZoneFile America/Guadeloupe
+if {![info exists TZData(America/Port_of_Spain)]} {
+ LoadTimeZoneFile America/Port_of_Spain
}
-set TZData(:America/Marigot) $TZData(:America/Guadeloupe)
+set TZData(:America/Marigot) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Metlakatla b/library/tzdata/America/Metlakatla
index 19337bf..e8af1c0 100644
--- a/library/tzdata/America/Metlakatla
+++ b/library/tzdata/America/Metlakatla
@@ -40,236 +40,4 @@ set TZData(:America/Metlakatla) {
{404902800 -28800 0 PST}
{420026400 -25200 1 PDT}
{436356000 -28800 0 MeST}
- {452080800 -25200 1 MeST}
- {467802000 -28800 0 MeST}
- {483530400 -25200 1 MeST}
- {499251600 -28800 0 MeST}
- {514980000 -25200 1 MeST}
- {530701200 -28800 0 MeST}
- {544615200 -25200 1 MeST}
- {562150800 -28800 0 MeST}
- {576064800 -25200 1 MeST}
- {594205200 -28800 0 MeST}
- {607514400 -25200 1 MeST}
- {625654800 -28800 0 MeST}
- {638964000 -25200 1 MeST}
- {657104400 -28800 0 MeST}
- {671018400 -25200 1 MeST}
- {688554000 -28800 0 MeST}
- {702468000 -25200 1 MeST}
- {720003600 -28800 0 MeST}
- {733917600 -25200 1 MeST}
- {752058000 -28800 0 MeST}
- {765367200 -25200 1 MeST}
- {783507600 -28800 0 MeST}
- {796816800 -25200 1 MeST}
- {814957200 -28800 0 MeST}
- {828871200 -25200 1 MeST}
- {846406800 -28800 0 MeST}
- {860320800 -25200 1 MeST}
- {877856400 -28800 0 MeST}
- {891770400 -25200 1 MeST}
- {909306000 -28800 0 MeST}
- {923220000 -25200 1 MeST}
- {941360400 -28800 0 MeST}
- {954669600 -25200 1 MeST}
- {972810000 -28800 0 MeST}
- {986119200 -25200 1 MeST}
- {1004259600 -28800 0 MeST}
- {1018173600 -25200 1 MeST}
- {1035709200 -28800 0 MeST}
- {1049623200 -25200 1 MeST}
- {1067158800 -28800 0 MeST}
- {1081072800 -25200 1 MeST}
- {1099213200 -28800 0 MeST}
- {1112522400 -25200 1 MeST}
- {1130662800 -28800 0 MeST}
- {1143972000 -25200 1 MeST}
- {1162112400 -28800 0 MeST}
- {1173607200 -25200 1 MeST}
- {1194166800 -28800 0 MeST}
- {1205056800 -25200 1 MeST}
- {1225616400 -28800 0 MeST}
- {1236506400 -25200 1 MeST}
- {1257066000 -28800 0 MeST}
- {1268560800 -25200 1 MeST}
- {1289120400 -28800 0 MeST}
- {1300010400 -25200 1 MeST}
- {1320570000 -28800 0 MeST}
- {1331460000 -25200 1 MeST}
- {1352019600 -28800 0 MeST}
- {1362909600 -25200 1 MeST}
- {1383469200 -28800 0 MeST}
- {1394359200 -25200 1 MeST}
- {1414918800 -28800 0 MeST}
- {1425808800 -25200 1 MeST}
- {1446368400 -28800 0 MeST}
- {1457863200 -25200 1 MeST}
- {1478422800 -28800 0 MeST}
- {1489312800 -25200 1 MeST}
- {1509872400 -28800 0 MeST}
- {1520762400 -25200 1 MeST}
- {1541322000 -28800 0 MeST}
- {1552212000 -25200 1 MeST}
- {1572771600 -28800 0 MeST}
- {1583661600 -25200 1 MeST}
- {1604221200 -28800 0 MeST}
- {1615716000 -25200 1 MeST}
- {1636275600 -28800 0 MeST}
- {1647165600 -25200 1 MeST}
- {1667725200 -28800 0 MeST}
- {1678615200 -25200 1 MeST}
- {1699174800 -28800 0 MeST}
- {1710064800 -25200 1 MeST}
- {1730624400 -28800 0 MeST}
- {1741514400 -25200 1 MeST}
- {1762074000 -28800 0 MeST}
- {1772964000 -25200 1 MeST}
- {1793523600 -28800 0 MeST}
- {1805018400 -25200 1 MeST}
- {1825578000 -28800 0 MeST}
- {1836468000 -25200 1 MeST}
- {1857027600 -28800 0 MeST}
- {1867917600 -25200 1 MeST}
- {1888477200 -28800 0 MeST}
- {1899367200 -25200 1 MeST}
- {1919926800 -28800 0 MeST}
- {1930816800 -25200 1 MeST}
- {1951376400 -28800 0 MeST}
- {1962871200 -25200 1 MeST}
- {1983430800 -28800 0 MeST}
- {1994320800 -25200 1 MeST}
- {2014880400 -28800 0 MeST}
- {2025770400 -25200 1 MeST}
- {2046330000 -28800 0 MeST}
- {2057220000 -25200 1 MeST}
- {2077779600 -28800 0 MeST}
- {2088669600 -25200 1 MeST}
- {2109229200 -28800 0 MeST}
- {2120119200 -25200 1 MeST}
- {2140678800 -28800 0 MeST}
- {2152173600 -25200 1 MeST}
- {2172733200 -28800 0 MeST}
- {2183623200 -25200 1 MeST}
- {2204182800 -28800 0 MeST}
- {2215072800 -25200 1 MeST}
- {2235632400 -28800 0 MeST}
- {2246522400 -25200 1 MeST}
- {2267082000 -28800 0 MeST}
- {2277972000 -25200 1 MeST}
- {2298531600 -28800 0 MeST}
- {2309421600 -25200 1 MeST}
- {2329981200 -28800 0 MeST}
- {2341476000 -25200 1 MeST}
- {2362035600 -28800 0 MeST}
- {2372925600 -25200 1 MeST}
- {2393485200 -28800 0 MeST}
- {2404375200 -25200 1 MeST}
- {2424934800 -28800 0 MeST}
- {2435824800 -25200 1 MeST}
- {2456384400 -28800 0 MeST}
- {2467274400 -25200 1 MeST}
- {2487834000 -28800 0 MeST}
- {2499328800 -25200 1 MeST}
- {2519888400 -28800 0 MeST}
- {2530778400 -25200 1 MeST}
- {2551338000 -28800 0 MeST}
- {2562228000 -25200 1 MeST}
- {2582787600 -28800 0 MeST}
- {2593677600 -25200 1 MeST}
- {2614237200 -28800 0 MeST}
- {2625127200 -25200 1 MeST}
- {2645686800 -28800 0 MeST}
- {2656576800 -25200 1 MeST}
- {2677136400 -28800 0 MeST}
- {2688631200 -25200 1 MeST}
- {2709190800 -28800 0 MeST}
- {2720080800 -25200 1 MeST}
- {2740640400 -28800 0 MeST}
- {2751530400 -25200 1 MeST}
- {2772090000 -28800 0 MeST}
- {2782980000 -25200 1 MeST}
- {2803539600 -28800 0 MeST}
- {2814429600 -25200 1 MeST}
- {2834989200 -28800 0 MeST}
- {2846484000 -25200 1 MeST}
- {2867043600 -28800 0 MeST}
- {2877933600 -25200 1 MeST}
- {2898493200 -28800 0 MeST}
- {2909383200 -25200 1 MeST}
- {2929942800 -28800 0 MeST}
- {2940832800 -25200 1 MeST}
- {2961392400 -28800 0 MeST}
- {2972282400 -25200 1 MeST}
- {2992842000 -28800 0 MeST}
- {3003732000 -25200 1 MeST}
- {3024291600 -28800 0 MeST}
- {3035786400 -25200 1 MeST}
- {3056346000 -28800 0 MeST}
- {3067236000 -25200 1 MeST}
- {3087795600 -28800 0 MeST}
- {3098685600 -25200 1 MeST}
- {3119245200 -28800 0 MeST}
- {3130135200 -25200 1 MeST}
- {3150694800 -28800 0 MeST}
- {3161584800 -25200 1 MeST}
- {3182144400 -28800 0 MeST}
- {3193034400 -25200 1 MeST}
- {3213594000 -28800 0 MeST}
- {3225088800 -25200 1 MeST}
- {3245648400 -28800 0 MeST}
- {3256538400 -25200 1 MeST}
- {3277098000 -28800 0 MeST}
- {3287988000 -25200 1 MeST}
- {3308547600 -28800 0 MeST}
- {3319437600 -25200 1 MeST}
- {3339997200 -28800 0 MeST}
- {3350887200 -25200 1 MeST}
- {3371446800 -28800 0 MeST}
- {3382941600 -25200 1 MeST}
- {3403501200 -28800 0 MeST}
- {3414391200 -25200 1 MeST}
- {3434950800 -28800 0 MeST}
- {3445840800 -25200 1 MeST}
- {3466400400 -28800 0 MeST}
- {3477290400 -25200 1 MeST}
- {3497850000 -28800 0 MeST}
- {3508740000 -25200 1 MeST}
- {3529299600 -28800 0 MeST}
- {3540189600 -25200 1 MeST}
- {3560749200 -28800 0 MeST}
- {3572244000 -25200 1 MeST}
- {3592803600 -28800 0 MeST}
- {3603693600 -25200 1 MeST}
- {3624253200 -28800 0 MeST}
- {3635143200 -25200 1 MeST}
- {3655702800 -28800 0 MeST}
- {3666592800 -25200 1 MeST}
- {3687152400 -28800 0 MeST}
- {3698042400 -25200 1 MeST}
- {3718602000 -28800 0 MeST}
- {3730096800 -25200 1 MeST}
- {3750656400 -28800 0 MeST}
- {3761546400 -25200 1 MeST}
- {3782106000 -28800 0 MeST}
- {3792996000 -25200 1 MeST}
- {3813555600 -28800 0 MeST}
- {3824445600 -25200 1 MeST}
- {3845005200 -28800 0 MeST}
- {3855895200 -25200 1 MeST}
- {3876454800 -28800 0 MeST}
- {3887344800 -25200 1 MeST}
- {3907904400 -28800 0 MeST}
- {3919399200 -25200 1 MeST}
- {3939958800 -28800 0 MeST}
- {3950848800 -25200 1 MeST}
- {3971408400 -28800 0 MeST}
- {3982298400 -25200 1 MeST}
- {4002858000 -28800 0 MeST}
- {4013748000 -25200 1 MeST}
- {4034307600 -28800 0 MeST}
- {4045197600 -25200 1 MeST}
- {4065757200 -28800 0 MeST}
- {4076647200 -25200 1 MeST}
- {4097206800 -28800 0 MeST}
}
diff --git a/library/tzdata/America/Moncton b/library/tzdata/America/Moncton
index 408e3a1..d286c88 100755..100644
--- a/library/tzdata/America/Moncton
+++ b/library/tzdata/America/Moncton
@@ -5,7 +5,7 @@ set TZData(:America/Moncton) {
{-2715882052 -18000 0 EST}
{-2131642800 -14400 0 AST}
{-1632074400 -10800 1 ADT}
- {-1614798000 -14400 0 AST}
+ {-1615143600 -14400 0 AST}
{-1167595200 -14400 0 AST}
{-1153681200 -10800 1 ADT}
{-1145822400 -14400 0 AST}
diff --git a/library/tzdata/America/Montreal b/library/tzdata/America/Montreal
index b9535eb..bebe7dc 100644
--- a/library/tzdata/America/Montreal
+++ b/library/tzdata/America/Montreal
@@ -7,7 +7,7 @@ set TZData(:America/Montreal) {
{-1662753600 -18000 0 EST}
{-1640977200 -18000 0 EST}
{-1632070800 -14400 1 EDT}
- {-1614794400 -18000 0 EST}
+ {-1615140000 -18000 0 EST}
{-1609441200 -18000 0 EST}
{-1601742600 -14400 1 EDT}
{-1583775000 -18000 0 EST}
diff --git a/library/tzdata/America/Montserrat b/library/tzdata/America/Montserrat
index 4d82766..0a656d3 100644
--- a/library/tzdata/America/Montserrat
+++ b/library/tzdata/America/Montserrat
@@ -1,6 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-
-set TZData(:America/Montserrat) {
- {-9223372036854775808 -14932 0 LMT}
- {-1846266608 -14400 0 AST}
+if {![info exists TZData(America/Port_of_Spain)]} {
+ LoadTimeZoneFile America/Port_of_Spain
}
+set TZData(:America/Montserrat) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Nassau b/library/tzdata/America/Nassau
index 06c5f06..1c35e93 100644
--- a/library/tzdata/America/Nassau
+++ b/library/tzdata/America/Nassau
@@ -1,8 +1,8 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:America/Nassau) {
- {-9223372036854775808 -18564 0 LMT}
- {-1825095036 -18000 0 EST}
+ {-9223372036854775808 -18570 0 LMT}
+ {-1825095030 -18000 0 EST}
{-179341200 -14400 1 EDT}
{-163620000 -18000 0 EST}
{-147891600 -14400 1 EDT}
diff --git a/library/tzdata/America/Nipigon b/library/tzdata/America/Nipigon
index e98bb8c..30690aa 100644
--- a/library/tzdata/America/Nipigon
+++ b/library/tzdata/America/Nipigon
@@ -4,7 +4,7 @@ set TZData(:America/Nipigon) {
{-9223372036854775808 -21184 0 LMT}
{-2366734016 -18000 0 EST}
{-1632070800 -14400 1 EDT}
- {-1614794400 -18000 0 EST}
+ {-1615140000 -18000 0 EST}
{-923252400 -14400 1 EDT}
{-880218000 -14400 0 EWT}
{-769395600 -14400 1 EPT}
diff --git a/library/tzdata/America/North_Dakota/New_Salem b/library/tzdata/America/North_Dakota/New_Salem
index 5a9d229..5a9d229 100755..100644
--- a/library/tzdata/America/North_Dakota/New_Salem
+++ b/library/tzdata/America/North_Dakota/New_Salem
diff --git a/library/tzdata/America/Port-au-Prince b/library/tzdata/America/Port-au-Prince
index 04ee62c..f1d7fc4 100644
--- a/library/tzdata/America/Port-au-Prince
+++ b/library/tzdata/America/Port-au-Prince
@@ -38,4 +38,180 @@ set TZData(:America/Port-au-Prince) {
{1130644800 -18000 0 EST}
{1143954000 -14400 1 EDT}
{1162094400 -18000 0 EST}
+ {1331449200 -14400 1 EDT}
+ {1352008800 -18000 0 EST}
+ {1362898800 -14400 1 EDT}
+ {1383458400 -18000 0 EST}
+ {1394348400 -14400 1 EDT}
+ {1414908000 -18000 0 EST}
+ {1425798000 -14400 1 EDT}
+ {1446357600 -18000 0 EST}
+ {1457852400 -14400 1 EDT}
+ {1478412000 -18000 0 EST}
+ {1489302000 -14400 1 EDT}
+ {1509861600 -18000 0 EST}
+ {1520751600 -14400 1 EDT}
+ {1541311200 -18000 0 EST}
+ {1552201200 -14400 1 EDT}
+ {1572760800 -18000 0 EST}
+ {1583650800 -14400 1 EDT}
+ {1604210400 -18000 0 EST}
+ {1615705200 -14400 1 EDT}
+ {1636264800 -18000 0 EST}
+ {1647154800 -14400 1 EDT}
+ {1667714400 -18000 0 EST}
+ {1678604400 -14400 1 EDT}
+ {1699164000 -18000 0 EST}
+ {1710054000 -14400 1 EDT}
+ {1730613600 -18000 0 EST}
+ {1741503600 -14400 1 EDT}
+ {1762063200 -18000 0 EST}
+ {1772953200 -14400 1 EDT}
+ {1793512800 -18000 0 EST}
+ {1805007600 -14400 1 EDT}
+ {1825567200 -18000 0 EST}
+ {1836457200 -14400 1 EDT}
+ {1857016800 -18000 0 EST}
+ {1867906800 -14400 1 EDT}
+ {1888466400 -18000 0 EST}
+ {1899356400 -14400 1 EDT}
+ {1919916000 -18000 0 EST}
+ {1930806000 -14400 1 EDT}
+ {1951365600 -18000 0 EST}
+ {1962860400 -14400 1 EDT}
+ {1983420000 -18000 0 EST}
+ {1994310000 -14400 1 EDT}
+ {2014869600 -18000 0 EST}
+ {2025759600 -14400 1 EDT}
+ {2046319200 -18000 0 EST}
+ {2057209200 -14400 1 EDT}
+ {2077768800 -18000 0 EST}
+ {2088658800 -14400 1 EDT}
+ {2109218400 -18000 0 EST}
+ {2120108400 -14400 1 EDT}
+ {2140668000 -18000 0 EST}
+ {2152162800 -14400 1 EDT}
+ {2172722400 -18000 0 EST}
+ {2183612400 -14400 1 EDT}
+ {2204172000 -18000 0 EST}
+ {2215062000 -14400 1 EDT}
+ {2235621600 -18000 0 EST}
+ {2246511600 -14400 1 EDT}
+ {2267071200 -18000 0 EST}
+ {2277961200 -14400 1 EDT}
+ {2298520800 -18000 0 EST}
+ {2309410800 -14400 1 EDT}
+ {2329970400 -18000 0 EST}
+ {2341465200 -14400 1 EDT}
+ {2362024800 -18000 0 EST}
+ {2372914800 -14400 1 EDT}
+ {2393474400 -18000 0 EST}
+ {2404364400 -14400 1 EDT}
+ {2424924000 -18000 0 EST}
+ {2435814000 -14400 1 EDT}
+ {2456373600 -18000 0 EST}
+ {2467263600 -14400 1 EDT}
+ {2487823200 -18000 0 EST}
+ {2499318000 -14400 1 EDT}
+ {2519877600 -18000 0 EST}
+ {2530767600 -14400 1 EDT}
+ {2551327200 -18000 0 EST}
+ {2562217200 -14400 1 EDT}
+ {2582776800 -18000 0 EST}
+ {2593666800 -14400 1 EDT}
+ {2614226400 -18000 0 EST}
+ {2625116400 -14400 1 EDT}
+ {2645676000 -18000 0 EST}
+ {2656566000 -14400 1 EDT}
+ {2677125600 -18000 0 EST}
+ {2688620400 -14400 1 EDT}
+ {2709180000 -18000 0 EST}
+ {2720070000 -14400 1 EDT}
+ {2740629600 -18000 0 EST}
+ {2751519600 -14400 1 EDT}
+ {2772079200 -18000 0 EST}
+ {2782969200 -14400 1 EDT}
+ {2803528800 -18000 0 EST}
+ {2814418800 -14400 1 EDT}
+ {2834978400 -18000 0 EST}
+ {2846473200 -14400 1 EDT}
+ {2867032800 -18000 0 EST}
+ {2877922800 -14400 1 EDT}
+ {2898482400 -18000 0 EST}
+ {2909372400 -14400 1 EDT}
+ {2929932000 -18000 0 EST}
+ {2940822000 -14400 1 EDT}
+ {2961381600 -18000 0 EST}
+ {2972271600 -14400 1 EDT}
+ {2992831200 -18000 0 EST}
+ {3003721200 -14400 1 EDT}
+ {3024280800 -18000 0 EST}
+ {3035775600 -14400 1 EDT}
+ {3056335200 -18000 0 EST}
+ {3067225200 -14400 1 EDT}
+ {3087784800 -18000 0 EST}
+ {3098674800 -14400 1 EDT}
+ {3119234400 -18000 0 EST}
+ {3130124400 -14400 1 EDT}
+ {3150684000 -18000 0 EST}
+ {3161574000 -14400 1 EDT}
+ {3182133600 -18000 0 EST}
+ {3193023600 -14400 1 EDT}
+ {3213583200 -18000 0 EST}
+ {3225078000 -14400 1 EDT}
+ {3245637600 -18000 0 EST}
+ {3256527600 -14400 1 EDT}
+ {3277087200 -18000 0 EST}
+ {3287977200 -14400 1 EDT}
+ {3308536800 -18000 0 EST}
+ {3319426800 -14400 1 EDT}
+ {3339986400 -18000 0 EST}
+ {3350876400 -14400 1 EDT}
+ {3371436000 -18000 0 EST}
+ {3382930800 -14400 1 EDT}
+ {3403490400 -18000 0 EST}
+ {3414380400 -14400 1 EDT}
+ {3434940000 -18000 0 EST}
+ {3445830000 -14400 1 EDT}
+ {3466389600 -18000 0 EST}
+ {3477279600 -14400 1 EDT}
+ {3497839200 -18000 0 EST}
+ {3508729200 -14400 1 EDT}
+ {3529288800 -18000 0 EST}
+ {3540178800 -14400 1 EDT}
+ {3560738400 -18000 0 EST}
+ {3572233200 -14400 1 EDT}
+ {3592792800 -18000 0 EST}
+ {3603682800 -14400 1 EDT}
+ {3624242400 -18000 0 EST}
+ {3635132400 -14400 1 EDT}
+ {3655692000 -18000 0 EST}
+ {3666582000 -14400 1 EDT}
+ {3687141600 -18000 0 EST}
+ {3698031600 -14400 1 EDT}
+ {3718591200 -18000 0 EST}
+ {3730086000 -14400 1 EDT}
+ {3750645600 -18000 0 EST}
+ {3761535600 -14400 1 EDT}
+ {3782095200 -18000 0 EST}
+ {3792985200 -14400 1 EDT}
+ {3813544800 -18000 0 EST}
+ {3824434800 -14400 1 EDT}
+ {3844994400 -18000 0 EST}
+ {3855884400 -14400 1 EDT}
+ {3876444000 -18000 0 EST}
+ {3887334000 -14400 1 EDT}
+ {3907893600 -18000 0 EST}
+ {3919388400 -14400 1 EDT}
+ {3939948000 -18000 0 EST}
+ {3950838000 -14400 1 EDT}
+ {3971397600 -18000 0 EST}
+ {3982287600 -14400 1 EDT}
+ {4002847200 -18000 0 EST}
+ {4013737200 -14400 1 EDT}
+ {4034296800 -18000 0 EST}
+ {4045186800 -14400 1 EDT}
+ {4065746400 -18000 0 EST}
+ {4076636400 -14400 1 EDT}
+ {4097196000 -18000 0 EST}
}
diff --git a/library/tzdata/America/Rainy_River b/library/tzdata/America/Rainy_River
index 331bac6..a2b11aa 100644
--- a/library/tzdata/America/Rainy_River
+++ b/library/tzdata/America/Rainy_River
@@ -4,7 +4,7 @@ set TZData(:America/Rainy_River) {
{-9223372036854775808 -22696 0 LMT}
{-2366732504 -21600 0 CST}
{-1632067200 -18000 1 CDT}
- {-1614790800 -21600 0 CST}
+ {-1615136400 -21600 0 CST}
{-923248800 -18000 1 CDT}
{-880214400 -18000 0 CWT}
{-769395600 -18000 1 CPT}
diff --git a/library/tzdata/America/Regina b/library/tzdata/America/Regina
index 2030d75..e42b5be 100644
--- a/library/tzdata/America/Regina
+++ b/library/tzdata/America/Regina
@@ -4,7 +4,7 @@ set TZData(:America/Regina) {
{-9223372036854775808 -25116 0 LMT}
{-2030202084 -25200 0 MST}
{-1632063600 -21600 1 MDT}
- {-1614787200 -25200 0 MST}
+ {-1615132800 -25200 0 MST}
{-1251651600 -21600 1 MDT}
{-1238349600 -25200 0 MST}
{-1220202000 -21600 1 MDT}
diff --git a/library/tzdata/America/Resolute b/library/tzdata/America/Resolute
index 50ab9df..b4c0bab 100755..100644
--- a/library/tzdata/America/Resolute
+++ b/library/tzdata/America/Resolute
@@ -59,191 +59,190 @@ set TZData(:America/Resolute) {
{1130655600 -21600 0 CST}
{1143964800 -18000 1 CDT}
{1162108800 -18000 0 EST}
- {1162710000 -18000 0 EST}
- {1173596400 -18000 0 CDT}
- {1194159600 -18000 0 EST}
- {1205046000 -18000 0 CDT}
- {1225609200 -18000 0 EST}
- {1236495600 -18000 0 CDT}
- {1257058800 -18000 0 EST}
- {1268550000 -18000 0 CDT}
- {1289113200 -18000 0 EST}
- {1299999600 -18000 0 CDT}
- {1320562800 -18000 0 EST}
- {1331449200 -18000 0 CDT}
- {1352012400 -18000 0 EST}
- {1362898800 -18000 0 CDT}
- {1383462000 -18000 0 EST}
- {1394348400 -18000 0 CDT}
- {1414911600 -18000 0 EST}
- {1425798000 -18000 0 CDT}
- {1446361200 -18000 0 EST}
- {1457852400 -18000 0 CDT}
- {1478415600 -18000 0 EST}
- {1489302000 -18000 0 CDT}
- {1509865200 -18000 0 EST}
- {1520751600 -18000 0 CDT}
- {1541314800 -18000 0 EST}
- {1552201200 -18000 0 CDT}
- {1572764400 -18000 0 EST}
- {1583650800 -18000 0 CDT}
- {1604214000 -18000 0 EST}
- {1615705200 -18000 0 CDT}
- {1636268400 -18000 0 EST}
- {1647154800 -18000 0 CDT}
- {1667718000 -18000 0 EST}
- {1678604400 -18000 0 CDT}
- {1699167600 -18000 0 EST}
- {1710054000 -18000 0 CDT}
- {1730617200 -18000 0 EST}
- {1741503600 -18000 0 CDT}
- {1762066800 -18000 0 EST}
- {1772953200 -18000 0 CDT}
- {1793516400 -18000 0 EST}
- {1805007600 -18000 0 CDT}
- {1825570800 -18000 0 EST}
- {1836457200 -18000 0 CDT}
- {1857020400 -18000 0 EST}
- {1867906800 -18000 0 CDT}
- {1888470000 -18000 0 EST}
- {1899356400 -18000 0 CDT}
- {1919919600 -18000 0 EST}
- {1930806000 -18000 0 CDT}
- {1951369200 -18000 0 EST}
- {1962860400 -18000 0 CDT}
- {1983423600 -18000 0 EST}
- {1994310000 -18000 0 CDT}
- {2014873200 -18000 0 EST}
- {2025759600 -18000 0 CDT}
- {2046322800 -18000 0 EST}
- {2057209200 -18000 0 CDT}
- {2077772400 -18000 0 EST}
- {2088658800 -18000 0 CDT}
- {2109222000 -18000 0 EST}
- {2120108400 -18000 0 CDT}
- {2140671600 -18000 0 EST}
- {2152162800 -18000 0 CDT}
- {2172726000 -18000 0 EST}
- {2183612400 -18000 0 CDT}
- {2204175600 -18000 0 EST}
- {2215062000 -18000 0 CDT}
- {2235625200 -18000 0 EST}
- {2246511600 -18000 0 CDT}
- {2267074800 -18000 0 EST}
- {2277961200 -18000 0 CDT}
- {2298524400 -18000 0 EST}
- {2309410800 -18000 0 CDT}
- {2329974000 -18000 0 EST}
- {2341465200 -18000 0 CDT}
- {2362028400 -18000 0 EST}
- {2372914800 -18000 0 CDT}
- {2393478000 -18000 0 EST}
- {2404364400 -18000 0 CDT}
- {2424927600 -18000 0 EST}
- {2435814000 -18000 0 CDT}
- {2456377200 -18000 0 EST}
- {2467263600 -18000 0 CDT}
- {2487826800 -18000 0 EST}
- {2499318000 -18000 0 CDT}
- {2519881200 -18000 0 EST}
- {2530767600 -18000 0 CDT}
- {2551330800 -18000 0 EST}
- {2562217200 -18000 0 CDT}
- {2582780400 -18000 0 EST}
- {2593666800 -18000 0 CDT}
- {2614230000 -18000 0 EST}
- {2625116400 -18000 0 CDT}
- {2645679600 -18000 0 EST}
- {2656566000 -18000 0 CDT}
- {2677129200 -18000 0 EST}
- {2688620400 -18000 0 CDT}
- {2709183600 -18000 0 EST}
- {2720070000 -18000 0 CDT}
- {2740633200 -18000 0 EST}
- {2751519600 -18000 0 CDT}
- {2772082800 -18000 0 EST}
- {2782969200 -18000 0 CDT}
- {2803532400 -18000 0 EST}
- {2814418800 -18000 0 CDT}
- {2834982000 -18000 0 EST}
- {2846473200 -18000 0 CDT}
- {2867036400 -18000 0 EST}
- {2877922800 -18000 0 CDT}
- {2898486000 -18000 0 EST}
- {2909372400 -18000 0 CDT}
- {2929935600 -18000 0 EST}
- {2940822000 -18000 0 CDT}
- {2961385200 -18000 0 EST}
- {2972271600 -18000 0 CDT}
- {2992834800 -18000 0 EST}
- {3003721200 -18000 0 CDT}
- {3024284400 -18000 0 EST}
- {3035775600 -18000 0 CDT}
- {3056338800 -18000 0 EST}
- {3067225200 -18000 0 CDT}
- {3087788400 -18000 0 EST}
- {3098674800 -18000 0 CDT}
- {3119238000 -18000 0 EST}
- {3130124400 -18000 0 CDT}
- {3150687600 -18000 0 EST}
- {3161574000 -18000 0 CDT}
- {3182137200 -18000 0 EST}
- {3193023600 -18000 0 CDT}
- {3213586800 -18000 0 EST}
- {3225078000 -18000 0 CDT}
- {3245641200 -18000 0 EST}
- {3256527600 -18000 0 CDT}
- {3277090800 -18000 0 EST}
- {3287977200 -18000 0 CDT}
- {3308540400 -18000 0 EST}
- {3319426800 -18000 0 CDT}
- {3339990000 -18000 0 EST}
- {3350876400 -18000 0 CDT}
- {3371439600 -18000 0 EST}
- {3382930800 -18000 0 CDT}
- {3403494000 -18000 0 EST}
- {3414380400 -18000 0 CDT}
- {3434943600 -18000 0 EST}
- {3445830000 -18000 0 CDT}
- {3466393200 -18000 0 EST}
- {3477279600 -18000 0 CDT}
- {3497842800 -18000 0 EST}
- {3508729200 -18000 0 CDT}
- {3529292400 -18000 0 EST}
- {3540178800 -18000 0 CDT}
- {3560742000 -18000 0 EST}
- {3572233200 -18000 0 CDT}
- {3592796400 -18000 0 EST}
- {3603682800 -18000 0 CDT}
- {3624246000 -18000 0 EST}
- {3635132400 -18000 0 CDT}
- {3655695600 -18000 0 EST}
- {3666582000 -18000 0 CDT}
- {3687145200 -18000 0 EST}
- {3698031600 -18000 0 CDT}
- {3718594800 -18000 0 EST}
- {3730086000 -18000 0 CDT}
- {3750649200 -18000 0 EST}
- {3761535600 -18000 0 CDT}
- {3782098800 -18000 0 EST}
- {3792985200 -18000 0 CDT}
- {3813548400 -18000 0 EST}
- {3824434800 -18000 0 CDT}
- {3844998000 -18000 0 EST}
- {3855884400 -18000 0 CDT}
- {3876447600 -18000 0 EST}
- {3887334000 -18000 0 CDT}
- {3907897200 -18000 0 EST}
- {3919388400 -18000 0 CDT}
- {3939951600 -18000 0 EST}
- {3950838000 -18000 0 CDT}
- {3971401200 -18000 0 EST}
- {3982287600 -18000 0 CDT}
- {4002850800 -18000 0 EST}
- {4013737200 -18000 0 CDT}
- {4034300400 -18000 0 EST}
- {4045186800 -18000 0 CDT}
- {4065750000 -18000 0 EST}
- {4076636400 -18000 0 CDT}
- {4097199600 -18000 0 EST}
+ {1173600000 -18000 0 CDT}
+ {1194159600 -21600 0 CST}
+ {1205049600 -18000 1 CDT}
+ {1225609200 -21600 0 CST}
+ {1236499200 -18000 1 CDT}
+ {1257058800 -21600 0 CST}
+ {1268553600 -18000 1 CDT}
+ {1289113200 -21600 0 CST}
+ {1300003200 -18000 1 CDT}
+ {1320562800 -21600 0 CST}
+ {1331452800 -18000 1 CDT}
+ {1352012400 -21600 0 CST}
+ {1362902400 -18000 1 CDT}
+ {1383462000 -21600 0 CST}
+ {1394352000 -18000 1 CDT}
+ {1414911600 -21600 0 CST}
+ {1425801600 -18000 1 CDT}
+ {1446361200 -21600 0 CST}
+ {1457856000 -18000 1 CDT}
+ {1478415600 -21600 0 CST}
+ {1489305600 -18000 1 CDT}
+ {1509865200 -21600 0 CST}
+ {1520755200 -18000 1 CDT}
+ {1541314800 -21600 0 CST}
+ {1552204800 -18000 1 CDT}
+ {1572764400 -21600 0 CST}
+ {1583654400 -18000 1 CDT}
+ {1604214000 -21600 0 CST}
+ {1615708800 -18000 1 CDT}
+ {1636268400 -21600 0 CST}
+ {1647158400 -18000 1 CDT}
+ {1667718000 -21600 0 CST}
+ {1678608000 -18000 1 CDT}
+ {1699167600 -21600 0 CST}
+ {1710057600 -18000 1 CDT}
+ {1730617200 -21600 0 CST}
+ {1741507200 -18000 1 CDT}
+ {1762066800 -21600 0 CST}
+ {1772956800 -18000 1 CDT}
+ {1793516400 -21600 0 CST}
+ {1805011200 -18000 1 CDT}
+ {1825570800 -21600 0 CST}
+ {1836460800 -18000 1 CDT}
+ {1857020400 -21600 0 CST}
+ {1867910400 -18000 1 CDT}
+ {1888470000 -21600 0 CST}
+ {1899360000 -18000 1 CDT}
+ {1919919600 -21600 0 CST}
+ {1930809600 -18000 1 CDT}
+ {1951369200 -21600 0 CST}
+ {1962864000 -18000 1 CDT}
+ {1983423600 -21600 0 CST}
+ {1994313600 -18000 1 CDT}
+ {2014873200 -21600 0 CST}
+ {2025763200 -18000 1 CDT}
+ {2046322800 -21600 0 CST}
+ {2057212800 -18000 1 CDT}
+ {2077772400 -21600 0 CST}
+ {2088662400 -18000 1 CDT}
+ {2109222000 -21600 0 CST}
+ {2120112000 -18000 1 CDT}
+ {2140671600 -21600 0 CST}
+ {2152166400 -18000 1 CDT}
+ {2172726000 -21600 0 CST}
+ {2183616000 -18000 1 CDT}
+ {2204175600 -21600 0 CST}
+ {2215065600 -18000 1 CDT}
+ {2235625200 -21600 0 CST}
+ {2246515200 -18000 1 CDT}
+ {2267074800 -21600 0 CST}
+ {2277964800 -18000 1 CDT}
+ {2298524400 -21600 0 CST}
+ {2309414400 -18000 1 CDT}
+ {2329974000 -21600 0 CST}
+ {2341468800 -18000 1 CDT}
+ {2362028400 -21600 0 CST}
+ {2372918400 -18000 1 CDT}
+ {2393478000 -21600 0 CST}
+ {2404368000 -18000 1 CDT}
+ {2424927600 -21600 0 CST}
+ {2435817600 -18000 1 CDT}
+ {2456377200 -21600 0 CST}
+ {2467267200 -18000 1 CDT}
+ {2487826800 -21600 0 CST}
+ {2499321600 -18000 1 CDT}
+ {2519881200 -21600 0 CST}
+ {2530771200 -18000 1 CDT}
+ {2551330800 -21600 0 CST}
+ {2562220800 -18000 1 CDT}
+ {2582780400 -21600 0 CST}
+ {2593670400 -18000 1 CDT}
+ {2614230000 -21600 0 CST}
+ {2625120000 -18000 1 CDT}
+ {2645679600 -21600 0 CST}
+ {2656569600 -18000 1 CDT}
+ {2677129200 -21600 0 CST}
+ {2688624000 -18000 1 CDT}
+ {2709183600 -21600 0 CST}
+ {2720073600 -18000 1 CDT}
+ {2740633200 -21600 0 CST}
+ {2751523200 -18000 1 CDT}
+ {2772082800 -21600 0 CST}
+ {2782972800 -18000 1 CDT}
+ {2803532400 -21600 0 CST}
+ {2814422400 -18000 1 CDT}
+ {2834982000 -21600 0 CST}
+ {2846476800 -18000 1 CDT}
+ {2867036400 -21600 0 CST}
+ {2877926400 -18000 1 CDT}
+ {2898486000 -21600 0 CST}
+ {2909376000 -18000 1 CDT}
+ {2929935600 -21600 0 CST}
+ {2940825600 -18000 1 CDT}
+ {2961385200 -21600 0 CST}
+ {2972275200 -18000 1 CDT}
+ {2992834800 -21600 0 CST}
+ {3003724800 -18000 1 CDT}
+ {3024284400 -21600 0 CST}
+ {3035779200 -18000 1 CDT}
+ {3056338800 -21600 0 CST}
+ {3067228800 -18000 1 CDT}
+ {3087788400 -21600 0 CST}
+ {3098678400 -18000 1 CDT}
+ {3119238000 -21600 0 CST}
+ {3130128000 -18000 1 CDT}
+ {3150687600 -21600 0 CST}
+ {3161577600 -18000 1 CDT}
+ {3182137200 -21600 0 CST}
+ {3193027200 -18000 1 CDT}
+ {3213586800 -21600 0 CST}
+ {3225081600 -18000 1 CDT}
+ {3245641200 -21600 0 CST}
+ {3256531200 -18000 1 CDT}
+ {3277090800 -21600 0 CST}
+ {3287980800 -18000 1 CDT}
+ {3308540400 -21600 0 CST}
+ {3319430400 -18000 1 CDT}
+ {3339990000 -21600 0 CST}
+ {3350880000 -18000 1 CDT}
+ {3371439600 -21600 0 CST}
+ {3382934400 -18000 1 CDT}
+ {3403494000 -21600 0 CST}
+ {3414384000 -18000 1 CDT}
+ {3434943600 -21600 0 CST}
+ {3445833600 -18000 1 CDT}
+ {3466393200 -21600 0 CST}
+ {3477283200 -18000 1 CDT}
+ {3497842800 -21600 0 CST}
+ {3508732800 -18000 1 CDT}
+ {3529292400 -21600 0 CST}
+ {3540182400 -18000 1 CDT}
+ {3560742000 -21600 0 CST}
+ {3572236800 -18000 1 CDT}
+ {3592796400 -21600 0 CST}
+ {3603686400 -18000 1 CDT}
+ {3624246000 -21600 0 CST}
+ {3635136000 -18000 1 CDT}
+ {3655695600 -21600 0 CST}
+ {3666585600 -18000 1 CDT}
+ {3687145200 -21600 0 CST}
+ {3698035200 -18000 1 CDT}
+ {3718594800 -21600 0 CST}
+ {3730089600 -18000 1 CDT}
+ {3750649200 -21600 0 CST}
+ {3761539200 -18000 1 CDT}
+ {3782098800 -21600 0 CST}
+ {3792988800 -18000 1 CDT}
+ {3813548400 -21600 0 CST}
+ {3824438400 -18000 1 CDT}
+ {3844998000 -21600 0 CST}
+ {3855888000 -18000 1 CDT}
+ {3876447600 -21600 0 CST}
+ {3887337600 -18000 1 CDT}
+ {3907897200 -21600 0 CST}
+ {3919392000 -18000 1 CDT}
+ {3939951600 -21600 0 CST}
+ {3950841600 -18000 1 CDT}
+ {3971401200 -21600 0 CST}
+ {3982291200 -18000 1 CDT}
+ {4002850800 -21600 0 CST}
+ {4013740800 -18000 1 CDT}
+ {4034300400 -21600 0 CST}
+ {4045190400 -18000 1 CDT}
+ {4065750000 -21600 0 CST}
+ {4076640000 -18000 1 CDT}
+ {4097199600 -21600 0 CST}
}
diff --git a/library/tzdata/America/Santiago b/library/tzdata/America/Santiago
index c631bd1..44be9f8 100644
--- a/library/tzdata/America/Santiago
+++ b/library/tzdata/America/Santiago
@@ -112,180 +112,180 @@ set TZData(:America/Santiago) {
{1286683200 -10800 1 CLST}
{1304823600 -14400 0 CLT}
{1313899200 -10800 1 CLST}
- {1331434800 -14400 0 CLT}
- {1350187200 -10800 1 CLST}
- {1362884400 -14400 0 CLT}
- {1381636800 -10800 1 CLST}
- {1394334000 -14400 0 CLT}
- {1413086400 -10800 1 CLST}
- {1426388400 -14400 0 CLT}
- {1444536000 -10800 1 CLST}
- {1457838000 -14400 0 CLT}
- {1475985600 -10800 1 CLST}
- {1489287600 -14400 0 CLT}
- {1508040000 -10800 1 CLST}
- {1520737200 -14400 0 CLT}
- {1539489600 -10800 1 CLST}
- {1552186800 -14400 0 CLT}
- {1570939200 -10800 1 CLST}
- {1584241200 -14400 0 CLT}
- {1602388800 -10800 1 CLST}
- {1615690800 -14400 0 CLT}
- {1633838400 -10800 1 CLST}
- {1647140400 -14400 0 CLT}
- {1665288000 -10800 1 CLST}
- {1678590000 -14400 0 CLT}
- {1697342400 -10800 1 CLST}
- {1710039600 -14400 0 CLT}
- {1728792000 -10800 1 CLST}
- {1741489200 -14400 0 CLT}
- {1760241600 -10800 1 CLST}
- {1773543600 -14400 0 CLT}
- {1791691200 -10800 1 CLST}
- {1804993200 -14400 0 CLT}
- {1823140800 -10800 1 CLST}
- {1836442800 -14400 0 CLT}
- {1855195200 -10800 1 CLST}
- {1867892400 -14400 0 CLT}
- {1886644800 -10800 1 CLST}
- {1899342000 -14400 0 CLT}
- {1918094400 -10800 1 CLST}
- {1930791600 -14400 0 CLT}
- {1949544000 -10800 1 CLST}
- {1962846000 -14400 0 CLT}
- {1980993600 -10800 1 CLST}
- {1994295600 -14400 0 CLT}
- {2012443200 -10800 1 CLST}
- {2025745200 -14400 0 CLT}
- {2044497600 -10800 1 CLST}
- {2057194800 -14400 0 CLT}
- {2075947200 -10800 1 CLST}
- {2088644400 -14400 0 CLT}
- {2107396800 -10800 1 CLST}
- {2120698800 -14400 0 CLT}
- {2138846400 -10800 1 CLST}
- {2152148400 -14400 0 CLT}
- {2170296000 -10800 1 CLST}
- {2183598000 -14400 0 CLT}
- {2201745600 -10800 1 CLST}
- {2215047600 -14400 0 CLT}
- {2233800000 -10800 1 CLST}
- {2246497200 -14400 0 CLT}
- {2265249600 -10800 1 CLST}
- {2277946800 -14400 0 CLT}
- {2296699200 -10800 1 CLST}
- {2310001200 -14400 0 CLT}
- {2328148800 -10800 1 CLST}
- {2341450800 -14400 0 CLT}
- {2359598400 -10800 1 CLST}
- {2372900400 -14400 0 CLT}
- {2391652800 -10800 1 CLST}
- {2404350000 -14400 0 CLT}
- {2423102400 -10800 1 CLST}
- {2435799600 -14400 0 CLT}
- {2454552000 -10800 1 CLST}
- {2467854000 -14400 0 CLT}
- {2486001600 -10800 1 CLST}
- {2499303600 -14400 0 CLT}
- {2517451200 -10800 1 CLST}
- {2530753200 -14400 0 CLT}
- {2548900800 -10800 1 CLST}
- {2562202800 -14400 0 CLT}
- {2580955200 -10800 1 CLST}
- {2593652400 -14400 0 CLT}
- {2612404800 -10800 1 CLST}
- {2625102000 -14400 0 CLT}
- {2643854400 -10800 1 CLST}
- {2657156400 -14400 0 CLT}
- {2675304000 -10800 1 CLST}
- {2688606000 -14400 0 CLT}
- {2706753600 -10800 1 CLST}
- {2720055600 -14400 0 CLT}
- {2738808000 -10800 1 CLST}
- {2751505200 -14400 0 CLT}
- {2770257600 -10800 1 CLST}
- {2782954800 -14400 0 CLT}
- {2801707200 -10800 1 CLST}
- {2814404400 -14400 0 CLT}
- {2833156800 -10800 1 CLST}
- {2846458800 -14400 0 CLT}
- {2864606400 -10800 1 CLST}
- {2877908400 -14400 0 CLT}
- {2896056000 -10800 1 CLST}
- {2909358000 -14400 0 CLT}
- {2928110400 -10800 1 CLST}
- {2940807600 -14400 0 CLT}
- {2959560000 -10800 1 CLST}
- {2972257200 -14400 0 CLT}
- {2991009600 -10800 1 CLST}
- {3004311600 -14400 0 CLT}
- {3022459200 -10800 1 CLST}
- {3035761200 -14400 0 CLT}
- {3053908800 -10800 1 CLST}
- {3067210800 -14400 0 CLT}
- {3085358400 -10800 1 CLST}
- {3098660400 -14400 0 CLT}
- {3117412800 -10800 1 CLST}
- {3130110000 -14400 0 CLT}
- {3148862400 -10800 1 CLST}
- {3161559600 -14400 0 CLT}
- {3180312000 -10800 1 CLST}
- {3193614000 -14400 0 CLT}
- {3211761600 -10800 1 CLST}
- {3225063600 -14400 0 CLT}
- {3243211200 -10800 1 CLST}
- {3256513200 -14400 0 CLT}
- {3275265600 -10800 1 CLST}
- {3287962800 -14400 0 CLT}
- {3306715200 -10800 1 CLST}
- {3319412400 -14400 0 CLT}
- {3338164800 -10800 1 CLST}
- {3351466800 -14400 0 CLT}
- {3369614400 -10800 1 CLST}
- {3382916400 -14400 0 CLT}
- {3401064000 -10800 1 CLST}
- {3414366000 -14400 0 CLT}
- {3432513600 -10800 1 CLST}
- {3445815600 -14400 0 CLT}
- {3464568000 -10800 1 CLST}
- {3477265200 -14400 0 CLT}
- {3496017600 -10800 1 CLST}
- {3508714800 -14400 0 CLT}
- {3527467200 -10800 1 CLST}
- {3540769200 -14400 0 CLT}
- {3558916800 -10800 1 CLST}
- {3572218800 -14400 0 CLT}
- {3590366400 -10800 1 CLST}
- {3603668400 -14400 0 CLT}
- {3622420800 -10800 1 CLST}
- {3635118000 -14400 0 CLT}
- {3653870400 -10800 1 CLST}
- {3666567600 -14400 0 CLT}
- {3685320000 -10800 1 CLST}
- {3698017200 -14400 0 CLT}
- {3716769600 -10800 1 CLST}
- {3730071600 -14400 0 CLT}
- {3748219200 -10800 1 CLST}
- {3761521200 -14400 0 CLT}
- {3779668800 -10800 1 CLST}
- {3792970800 -14400 0 CLT}
- {3811723200 -10800 1 CLST}
- {3824420400 -14400 0 CLT}
- {3843172800 -10800 1 CLST}
- {3855870000 -14400 0 CLT}
- {3874622400 -10800 1 CLST}
- {3887924400 -14400 0 CLT}
- {3906072000 -10800 1 CLST}
- {3919374000 -14400 0 CLT}
- {3937521600 -10800 1 CLST}
- {3950823600 -14400 0 CLT}
- {3968971200 -10800 1 CLST}
- {3982273200 -14400 0 CLT}
- {4001025600 -10800 1 CLST}
- {4013722800 -14400 0 CLT}
- {4032475200 -10800 1 CLST}
- {4045172400 -14400 0 CLT}
- {4063924800 -10800 1 CLST}
- {4077226800 -14400 0 CLT}
- {4095374400 -10800 1 CLST}
+ {1335668400 -14400 0 CLT}
+ {1346558400 -10800 1 CLST}
+ {1367118000 -14400 0 CLT}
+ {1378612800 -10800 1 CLST}
+ {1398567600 -14400 0 CLT}
+ {1410062400 -10800 1 CLST}
+ {1430017200 -14400 0 CLT}
+ {1441512000 -10800 1 CLST}
+ {1461466800 -14400 0 CLT}
+ {1472961600 -10800 1 CLST}
+ {1492916400 -14400 0 CLT}
+ {1504411200 -10800 1 CLST}
+ {1524970800 -14400 0 CLT}
+ {1535860800 -10800 1 CLST}
+ {1556420400 -14400 0 CLT}
+ {1567915200 -10800 1 CLST}
+ {1587870000 -14400 0 CLT}
+ {1599364800 -10800 1 CLST}
+ {1619319600 -14400 0 CLT}
+ {1630814400 -10800 1 CLST}
+ {1650769200 -14400 0 CLT}
+ {1662264000 -10800 1 CLST}
+ {1682218800 -14400 0 CLT}
+ {1693713600 -10800 1 CLST}
+ {1714273200 -14400 0 CLT}
+ {1725768000 -10800 1 CLST}
+ {1745722800 -14400 0 CLT}
+ {1757217600 -10800 1 CLST}
+ {1777172400 -14400 0 CLT}
+ {1788667200 -10800 1 CLST}
+ {1808622000 -14400 0 CLT}
+ {1820116800 -10800 1 CLST}
+ {1840071600 -14400 0 CLT}
+ {1851566400 -10800 1 CLST}
+ {1872126000 -14400 0 CLT}
+ {1883016000 -10800 1 CLST}
+ {1903575600 -14400 0 CLT}
+ {1915070400 -10800 1 CLST}
+ {1935025200 -14400 0 CLT}
+ {1946520000 -10800 1 CLST}
+ {1966474800 -14400 0 CLT}
+ {1977969600 -10800 1 CLST}
+ {1997924400 -14400 0 CLT}
+ {2009419200 -10800 1 CLST}
+ {2029374000 -14400 0 CLT}
+ {2040868800 -10800 1 CLST}
+ {2061428400 -14400 0 CLT}
+ {2072318400 -10800 1 CLST}
+ {2092878000 -14400 0 CLT}
+ {2104372800 -10800 1 CLST}
+ {2124327600 -14400 0 CLT}
+ {2135822400 -10800 1 CLST}
+ {2155777200 -14400 0 CLT}
+ {2167272000 -10800 1 CLST}
+ {2187226800 -14400 0 CLT}
+ {2198721600 -10800 1 CLST}
+ {2219281200 -14400 0 CLT}
+ {2230171200 -10800 1 CLST}
+ {2250730800 -14400 0 CLT}
+ {2262225600 -10800 1 CLST}
+ {2282180400 -14400 0 CLT}
+ {2293675200 -10800 1 CLST}
+ {2313630000 -14400 0 CLT}
+ {2325124800 -10800 1 CLST}
+ {2345079600 -14400 0 CLT}
+ {2356574400 -10800 1 CLST}
+ {2376529200 -14400 0 CLT}
+ {2388024000 -10800 1 CLST}
+ {2408583600 -14400 0 CLT}
+ {2419473600 -10800 1 CLST}
+ {2440033200 -14400 0 CLT}
+ {2451528000 -10800 1 CLST}
+ {2471482800 -14400 0 CLT}
+ {2482977600 -10800 1 CLST}
+ {2502932400 -14400 0 CLT}
+ {2514427200 -10800 1 CLST}
+ {2534382000 -14400 0 CLT}
+ {2545876800 -10800 1 CLST}
+ {2565831600 -14400 0 CLT}
+ {2577326400 -10800 1 CLST}
+ {2597886000 -14400 0 CLT}
+ {2609380800 -10800 1 CLST}
+ {2629335600 -14400 0 CLT}
+ {2640830400 -10800 1 CLST}
+ {2660785200 -14400 0 CLT}
+ {2672280000 -10800 1 CLST}
+ {2692234800 -14400 0 CLT}
+ {2703729600 -10800 1 CLST}
+ {2723684400 -14400 0 CLT}
+ {2735179200 -10800 1 CLST}
+ {2755738800 -14400 0 CLT}
+ {2766628800 -10800 1 CLST}
+ {2787188400 -14400 0 CLT}
+ {2798683200 -10800 1 CLST}
+ {2818638000 -14400 0 CLT}
+ {2830132800 -10800 1 CLST}
+ {2850087600 -14400 0 CLT}
+ {2861582400 -10800 1 CLST}
+ {2881537200 -14400 0 CLT}
+ {2893032000 -10800 1 CLST}
+ {2912986800 -14400 0 CLT}
+ {2924481600 -10800 1 CLST}
+ {2945041200 -14400 0 CLT}
+ {2955931200 -10800 1 CLST}
+ {2976490800 -14400 0 CLT}
+ {2987985600 -10800 1 CLST}
+ {3007940400 -14400 0 CLT}
+ {3019435200 -10800 1 CLST}
+ {3039390000 -14400 0 CLT}
+ {3050884800 -10800 1 CLST}
+ {3070839600 -14400 0 CLT}
+ {3082334400 -10800 1 CLST}
+ {3102894000 -14400 0 CLT}
+ {3113784000 -10800 1 CLST}
+ {3134343600 -14400 0 CLT}
+ {3145838400 -10800 1 CLST}
+ {3165793200 -14400 0 CLT}
+ {3177288000 -10800 1 CLST}
+ {3197242800 -14400 0 CLT}
+ {3208737600 -10800 1 CLST}
+ {3228692400 -14400 0 CLT}
+ {3240187200 -10800 1 CLST}
+ {3260142000 -14400 0 CLT}
+ {3271636800 -10800 1 CLST}
+ {3292196400 -14400 0 CLT}
+ {3303086400 -10800 1 CLST}
+ {3323646000 -14400 0 CLT}
+ {3335140800 -10800 1 CLST}
+ {3355095600 -14400 0 CLT}
+ {3366590400 -10800 1 CLST}
+ {3386545200 -14400 0 CLT}
+ {3398040000 -10800 1 CLST}
+ {3417994800 -14400 0 CLT}
+ {3429489600 -10800 1 CLST}
+ {3449444400 -14400 0 CLT}
+ {3460939200 -10800 1 CLST}
+ {3481498800 -14400 0 CLT}
+ {3492993600 -10800 1 CLST}
+ {3512948400 -14400 0 CLT}
+ {3524443200 -10800 1 CLST}
+ {3544398000 -14400 0 CLT}
+ {3555892800 -10800 1 CLST}
+ {3575847600 -14400 0 CLT}
+ {3587342400 -10800 1 CLST}
+ {3607297200 -14400 0 CLT}
+ {3618792000 -10800 1 CLST}
+ {3639351600 -14400 0 CLT}
+ {3650241600 -10800 1 CLST}
+ {3670801200 -14400 0 CLT}
+ {3682296000 -10800 1 CLST}
+ {3702250800 -14400 0 CLT}
+ {3713745600 -10800 1 CLST}
+ {3733700400 -14400 0 CLT}
+ {3745195200 -10800 1 CLST}
+ {3765150000 -14400 0 CLT}
+ {3776644800 -10800 1 CLST}
+ {3796599600 -14400 0 CLT}
+ {3808094400 -10800 1 CLST}
+ {3828654000 -14400 0 CLT}
+ {3839544000 -10800 1 CLST}
+ {3860103600 -14400 0 CLT}
+ {3871598400 -10800 1 CLST}
+ {3891553200 -14400 0 CLT}
+ {3903048000 -10800 1 CLST}
+ {3923002800 -14400 0 CLT}
+ {3934497600 -10800 1 CLST}
+ {3954452400 -14400 0 CLT}
+ {3965947200 -10800 1 CLST}
+ {3986506800 -14400 0 CLT}
+ {3997396800 -10800 1 CLST}
+ {4017956400 -14400 0 CLT}
+ {4029451200 -10800 1 CLST}
+ {4049406000 -14400 0 CLT}
+ {4060900800 -10800 1 CLST}
+ {4080855600 -14400 0 CLT}
+ {4092350400 -10800 1 CLST}
}
diff --git a/library/tzdata/America/Sitka b/library/tzdata/America/Sitka
index c096fc9..8c53d93 100644
--- a/library/tzdata/America/Sitka
+++ b/library/tzdata/America/Sitka
@@ -1,8 +1,8 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:America/Sitka) {
- {-9223372036854775808 -53927 0 LMT}
- {-3225258073 -32473 0 LMT}
+ {-9223372036854775808 53927 0 LMT}
+ {-3225365927 -32473 0 LMT}
{-2188954727 -28800 0 PST}
{-883584000 -28800 0 PST}
{-880207200 -25200 1 PWT}
diff --git a/library/tzdata/America/St_Barthelemy b/library/tzdata/America/St_Barthelemy
index 25c114a..46bc287 100644
--- a/library/tzdata/America/St_Barthelemy
+++ b/library/tzdata/America/St_Barthelemy
@@ -1,5 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-if {![info exists TZData(America/Guadeloupe)]} {
- LoadTimeZoneFile America/Guadeloupe
+if {![info exists TZData(America/Port_of_Spain)]} {
+ LoadTimeZoneFile America/Port_of_Spain
}
-set TZData(:America/St_Barthelemy) $TZData(:America/Guadeloupe)
+set TZData(:America/St_Barthelemy) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/St_Johns b/library/tzdata/America/St_Johns
index 59f92bb..1492961 100644
--- a/library/tzdata/America/St_Johns
+++ b/library/tzdata/America/St_Johns
@@ -7,7 +7,7 @@ set TZData(:America/St_Johns) {
{-1650137348 -12652 0 NST}
{-1640982548 -12652 0 NST}
{-1632076148 -9052 1 NDT}
- {-1614799748 -12652 0 NST}
+ {-1615145348 -12652 0 NST}
{-1609446548 -12652 0 NST}
{-1598650148 -9052 1 NDT}
{-1590100148 -12652 0 NST}
@@ -191,181 +191,182 @@ set TZData(:America/St_Johns) {
{1268537460 -9000 1 NDT}
{1289097060 -12600 0 NST}
{1299987060 -9000 1 NDT}
- {1320546660 -12600 0 NST}
- {1331436660 -9000 1 NDT}
- {1351996260 -12600 0 NST}
- {1362886260 -9000 1 NDT}
- {1383445860 -12600 0 NST}
- {1394335860 -9000 1 NDT}
- {1414895460 -12600 0 NST}
- {1425785460 -9000 1 NDT}
- {1446345060 -12600 0 NST}
- {1457839860 -9000 1 NDT}
- {1478399460 -12600 0 NST}
- {1489289460 -9000 1 NDT}
- {1509849060 -12600 0 NST}
- {1520739060 -9000 1 NDT}
- {1541298660 -12600 0 NST}
- {1552188660 -9000 1 NDT}
- {1572748260 -12600 0 NST}
- {1583638260 -9000 1 NDT}
- {1604197860 -12600 0 NST}
- {1615692660 -9000 1 NDT}
- {1636252260 -12600 0 NST}
- {1647142260 -9000 1 NDT}
- {1667701860 -12600 0 NST}
- {1678591860 -9000 1 NDT}
- {1699151460 -12600 0 NST}
- {1710041460 -9000 1 NDT}
- {1730601060 -12600 0 NST}
- {1741491060 -9000 1 NDT}
- {1762050660 -12600 0 NST}
- {1772940660 -9000 1 NDT}
- {1793500260 -12600 0 NST}
- {1804995060 -9000 1 NDT}
- {1825554660 -12600 0 NST}
- {1836444660 -9000 1 NDT}
- {1857004260 -12600 0 NST}
- {1867894260 -9000 1 NDT}
- {1888453860 -12600 0 NST}
- {1899343860 -9000 1 NDT}
- {1919903460 -12600 0 NST}
- {1930793460 -9000 1 NDT}
- {1951353060 -12600 0 NST}
- {1962847860 -9000 1 NDT}
- {1983407460 -12600 0 NST}
- {1994297460 -9000 1 NDT}
- {2014857060 -12600 0 NST}
- {2025747060 -9000 1 NDT}
- {2046306660 -12600 0 NST}
- {2057196660 -9000 1 NDT}
- {2077756260 -12600 0 NST}
- {2088646260 -9000 1 NDT}
- {2109205860 -12600 0 NST}
- {2120095860 -9000 1 NDT}
- {2140655460 -12600 0 NST}
- {2152150260 -9000 1 NDT}
- {2172709860 -12600 0 NST}
- {2183599860 -9000 1 NDT}
- {2204159460 -12600 0 NST}
- {2215049460 -9000 1 NDT}
- {2235609060 -12600 0 NST}
- {2246499060 -9000 1 NDT}
- {2267058660 -12600 0 NST}
- {2277948660 -9000 1 NDT}
- {2298508260 -12600 0 NST}
- {2309398260 -9000 1 NDT}
- {2329957860 -12600 0 NST}
- {2341452660 -9000 1 NDT}
- {2362012260 -12600 0 NST}
- {2372902260 -9000 1 NDT}
- {2393461860 -12600 0 NST}
- {2404351860 -9000 1 NDT}
- {2424911460 -12600 0 NST}
- {2435801460 -9000 1 NDT}
- {2456361060 -12600 0 NST}
- {2467251060 -9000 1 NDT}
- {2487810660 -12600 0 NST}
- {2499305460 -9000 1 NDT}
- {2519865060 -12600 0 NST}
- {2530755060 -9000 1 NDT}
- {2551314660 -12600 0 NST}
- {2562204660 -9000 1 NDT}
- {2582764260 -12600 0 NST}
- {2593654260 -9000 1 NDT}
- {2614213860 -12600 0 NST}
- {2625103860 -9000 1 NDT}
- {2645663460 -12600 0 NST}
- {2656553460 -9000 1 NDT}
- {2677113060 -12600 0 NST}
- {2688607860 -9000 1 NDT}
- {2709167460 -12600 0 NST}
- {2720057460 -9000 1 NDT}
- {2740617060 -12600 0 NST}
- {2751507060 -9000 1 NDT}
- {2772066660 -12600 0 NST}
- {2782956660 -9000 1 NDT}
- {2803516260 -12600 0 NST}
- {2814406260 -9000 1 NDT}
- {2834965860 -12600 0 NST}
- {2846460660 -9000 1 NDT}
- {2867020260 -12600 0 NST}
- {2877910260 -9000 1 NDT}
- {2898469860 -12600 0 NST}
- {2909359860 -9000 1 NDT}
- {2929919460 -12600 0 NST}
- {2940809460 -9000 1 NDT}
- {2961369060 -12600 0 NST}
- {2972259060 -9000 1 NDT}
- {2992818660 -12600 0 NST}
- {3003708660 -9000 1 NDT}
- {3024268260 -12600 0 NST}
- {3035763060 -9000 1 NDT}
- {3056322660 -12600 0 NST}
- {3067212660 -9000 1 NDT}
- {3087772260 -12600 0 NST}
- {3098662260 -9000 1 NDT}
- {3119221860 -12600 0 NST}
- {3130111860 -9000 1 NDT}
- {3150671460 -12600 0 NST}
- {3161561460 -9000 1 NDT}
- {3182121060 -12600 0 NST}
- {3193011060 -9000 1 NDT}
- {3213570660 -12600 0 NST}
- {3225065460 -9000 1 NDT}
- {3245625060 -12600 0 NST}
- {3256515060 -9000 1 NDT}
- {3277074660 -12600 0 NST}
- {3287964660 -9000 1 NDT}
- {3308524260 -12600 0 NST}
- {3319414260 -9000 1 NDT}
- {3339973860 -12600 0 NST}
- {3350863860 -9000 1 NDT}
- {3371423460 -12600 0 NST}
- {3382918260 -9000 1 NDT}
- {3403477860 -12600 0 NST}
- {3414367860 -9000 1 NDT}
- {3434927460 -12600 0 NST}
- {3445817460 -9000 1 NDT}
- {3466377060 -12600 0 NST}
- {3477267060 -9000 1 NDT}
- {3497826660 -12600 0 NST}
- {3508716660 -9000 1 NDT}
- {3529276260 -12600 0 NST}
- {3540166260 -9000 1 NDT}
- {3560725860 -12600 0 NST}
- {3572220660 -9000 1 NDT}
- {3592780260 -12600 0 NST}
- {3603670260 -9000 1 NDT}
- {3624229860 -12600 0 NST}
- {3635119860 -9000 1 NDT}
- {3655679460 -12600 0 NST}
- {3666569460 -9000 1 NDT}
- {3687129060 -12600 0 NST}
- {3698019060 -9000 1 NDT}
- {3718578660 -12600 0 NST}
- {3730073460 -9000 1 NDT}
- {3750633060 -12600 0 NST}
- {3761523060 -9000 1 NDT}
- {3782082660 -12600 0 NST}
- {3792972660 -9000 1 NDT}
- {3813532260 -12600 0 NST}
- {3824422260 -9000 1 NDT}
- {3844981860 -12600 0 NST}
- {3855871860 -9000 1 NDT}
- {3876431460 -12600 0 NST}
- {3887321460 -9000 1 NDT}
- {3907881060 -12600 0 NST}
- {3919375860 -9000 1 NDT}
- {3939935460 -12600 0 NST}
- {3950825460 -9000 1 NDT}
- {3971385060 -12600 0 NST}
- {3982275060 -9000 1 NDT}
- {4002834660 -12600 0 NST}
- {4013724660 -9000 1 NDT}
- {4034284260 -12600 0 NST}
- {4045174260 -9000 1 NDT}
- {4065733860 -12600 0 NST}
- {4076623860 -9000 1 NDT}
- {4097183460 -12600 0 NST}
+ {1320114600 -9000 0 NDT}
+ {1320553800 -12600 0 NST}
+ {1331443800 -9000 1 NDT}
+ {1352003400 -12600 0 NST}
+ {1362893400 -9000 1 NDT}
+ {1383453000 -12600 0 NST}
+ {1394343000 -9000 1 NDT}
+ {1414902600 -12600 0 NST}
+ {1425792600 -9000 1 NDT}
+ {1446352200 -12600 0 NST}
+ {1457847000 -9000 1 NDT}
+ {1478406600 -12600 0 NST}
+ {1489296600 -9000 1 NDT}
+ {1509856200 -12600 0 NST}
+ {1520746200 -9000 1 NDT}
+ {1541305800 -12600 0 NST}
+ {1552195800 -9000 1 NDT}
+ {1572755400 -12600 0 NST}
+ {1583645400 -9000 1 NDT}
+ {1604205000 -12600 0 NST}
+ {1615699800 -9000 1 NDT}
+ {1636259400 -12600 0 NST}
+ {1647149400 -9000 1 NDT}
+ {1667709000 -12600 0 NST}
+ {1678599000 -9000 1 NDT}
+ {1699158600 -12600 0 NST}
+ {1710048600 -9000 1 NDT}
+ {1730608200 -12600 0 NST}
+ {1741498200 -9000 1 NDT}
+ {1762057800 -12600 0 NST}
+ {1772947800 -9000 1 NDT}
+ {1793507400 -12600 0 NST}
+ {1805002200 -9000 1 NDT}
+ {1825561800 -12600 0 NST}
+ {1836451800 -9000 1 NDT}
+ {1857011400 -12600 0 NST}
+ {1867901400 -9000 1 NDT}
+ {1888461000 -12600 0 NST}
+ {1899351000 -9000 1 NDT}
+ {1919910600 -12600 0 NST}
+ {1930800600 -9000 1 NDT}
+ {1951360200 -12600 0 NST}
+ {1962855000 -9000 1 NDT}
+ {1983414600 -12600 0 NST}
+ {1994304600 -9000 1 NDT}
+ {2014864200 -12600 0 NST}
+ {2025754200 -9000 1 NDT}
+ {2046313800 -12600 0 NST}
+ {2057203800 -9000 1 NDT}
+ {2077763400 -12600 0 NST}
+ {2088653400 -9000 1 NDT}
+ {2109213000 -12600 0 NST}
+ {2120103000 -9000 1 NDT}
+ {2140662600 -12600 0 NST}
+ {2152157400 -9000 1 NDT}
+ {2172717000 -12600 0 NST}
+ {2183607000 -9000 1 NDT}
+ {2204166600 -12600 0 NST}
+ {2215056600 -9000 1 NDT}
+ {2235616200 -12600 0 NST}
+ {2246506200 -9000 1 NDT}
+ {2267065800 -12600 0 NST}
+ {2277955800 -9000 1 NDT}
+ {2298515400 -12600 0 NST}
+ {2309405400 -9000 1 NDT}
+ {2329965000 -12600 0 NST}
+ {2341459800 -9000 1 NDT}
+ {2362019400 -12600 0 NST}
+ {2372909400 -9000 1 NDT}
+ {2393469000 -12600 0 NST}
+ {2404359000 -9000 1 NDT}
+ {2424918600 -12600 0 NST}
+ {2435808600 -9000 1 NDT}
+ {2456368200 -12600 0 NST}
+ {2467258200 -9000 1 NDT}
+ {2487817800 -12600 0 NST}
+ {2499312600 -9000 1 NDT}
+ {2519872200 -12600 0 NST}
+ {2530762200 -9000 1 NDT}
+ {2551321800 -12600 0 NST}
+ {2562211800 -9000 1 NDT}
+ {2582771400 -12600 0 NST}
+ {2593661400 -9000 1 NDT}
+ {2614221000 -12600 0 NST}
+ {2625111000 -9000 1 NDT}
+ {2645670600 -12600 0 NST}
+ {2656560600 -9000 1 NDT}
+ {2677120200 -12600 0 NST}
+ {2688615000 -9000 1 NDT}
+ {2709174600 -12600 0 NST}
+ {2720064600 -9000 1 NDT}
+ {2740624200 -12600 0 NST}
+ {2751514200 -9000 1 NDT}
+ {2772073800 -12600 0 NST}
+ {2782963800 -9000 1 NDT}
+ {2803523400 -12600 0 NST}
+ {2814413400 -9000 1 NDT}
+ {2834973000 -12600 0 NST}
+ {2846467800 -9000 1 NDT}
+ {2867027400 -12600 0 NST}
+ {2877917400 -9000 1 NDT}
+ {2898477000 -12600 0 NST}
+ {2909367000 -9000 1 NDT}
+ {2929926600 -12600 0 NST}
+ {2940816600 -9000 1 NDT}
+ {2961376200 -12600 0 NST}
+ {2972266200 -9000 1 NDT}
+ {2992825800 -12600 0 NST}
+ {3003715800 -9000 1 NDT}
+ {3024275400 -12600 0 NST}
+ {3035770200 -9000 1 NDT}
+ {3056329800 -12600 0 NST}
+ {3067219800 -9000 1 NDT}
+ {3087779400 -12600 0 NST}
+ {3098669400 -9000 1 NDT}
+ {3119229000 -12600 0 NST}
+ {3130119000 -9000 1 NDT}
+ {3150678600 -12600 0 NST}
+ {3161568600 -9000 1 NDT}
+ {3182128200 -12600 0 NST}
+ {3193018200 -9000 1 NDT}
+ {3213577800 -12600 0 NST}
+ {3225072600 -9000 1 NDT}
+ {3245632200 -12600 0 NST}
+ {3256522200 -9000 1 NDT}
+ {3277081800 -12600 0 NST}
+ {3287971800 -9000 1 NDT}
+ {3308531400 -12600 0 NST}
+ {3319421400 -9000 1 NDT}
+ {3339981000 -12600 0 NST}
+ {3350871000 -9000 1 NDT}
+ {3371430600 -12600 0 NST}
+ {3382925400 -9000 1 NDT}
+ {3403485000 -12600 0 NST}
+ {3414375000 -9000 1 NDT}
+ {3434934600 -12600 0 NST}
+ {3445824600 -9000 1 NDT}
+ {3466384200 -12600 0 NST}
+ {3477274200 -9000 1 NDT}
+ {3497833800 -12600 0 NST}
+ {3508723800 -9000 1 NDT}
+ {3529283400 -12600 0 NST}
+ {3540173400 -9000 1 NDT}
+ {3560733000 -12600 0 NST}
+ {3572227800 -9000 1 NDT}
+ {3592787400 -12600 0 NST}
+ {3603677400 -9000 1 NDT}
+ {3624237000 -12600 0 NST}
+ {3635127000 -9000 1 NDT}
+ {3655686600 -12600 0 NST}
+ {3666576600 -9000 1 NDT}
+ {3687136200 -12600 0 NST}
+ {3698026200 -9000 1 NDT}
+ {3718585800 -12600 0 NST}
+ {3730080600 -9000 1 NDT}
+ {3750640200 -12600 0 NST}
+ {3761530200 -9000 1 NDT}
+ {3782089800 -12600 0 NST}
+ {3792979800 -9000 1 NDT}
+ {3813539400 -12600 0 NST}
+ {3824429400 -9000 1 NDT}
+ {3844989000 -12600 0 NST}
+ {3855879000 -9000 1 NDT}
+ {3876438600 -12600 0 NST}
+ {3887328600 -9000 1 NDT}
+ {3907888200 -12600 0 NST}
+ {3919383000 -9000 1 NDT}
+ {3939942600 -12600 0 NST}
+ {3950832600 -9000 1 NDT}
+ {3971392200 -12600 0 NST}
+ {3982282200 -9000 1 NDT}
+ {4002841800 -12600 0 NST}
+ {4013731800 -9000 1 NDT}
+ {4034291400 -12600 0 NST}
+ {4045181400 -9000 1 NDT}
+ {4065741000 -12600 0 NST}
+ {4076631000 -9000 1 NDT}
+ {4097190600 -12600 0 NST}
}
diff --git a/library/tzdata/America/St_Kitts b/library/tzdata/America/St_Kitts
index bfd803b..6ad7f04 100644
--- a/library/tzdata/America/St_Kitts
+++ b/library/tzdata/America/St_Kitts
@@ -1,6 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-
-set TZData(:America/St_Kitts) {
- {-9223372036854775808 -15052 0 LMT}
- {-1825098548 -14400 0 AST}
+if {![info exists TZData(America/Port_of_Spain)]} {
+ LoadTimeZoneFile America/Port_of_Spain
}
+set TZData(:America/St_Kitts) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/St_Lucia b/library/tzdata/America/St_Lucia
index c2767dd..e479b31 100644
--- a/library/tzdata/America/St_Lucia
+++ b/library/tzdata/America/St_Lucia
@@ -1,7 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-
-set TZData(:America/St_Lucia) {
- {-9223372036854775808 -14640 0 LMT}
- {-2524506960 -14640 0 CMT}
- {-1830369360 -14400 0 AST}
+if {![info exists TZData(America/Port_of_Spain)]} {
+ LoadTimeZoneFile America/Port_of_Spain
}
+set TZData(:America/St_Lucia) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/St_Thomas b/library/tzdata/America/St_Thomas
index bf93595..24698b8 100644
--- a/library/tzdata/America/St_Thomas
+++ b/library/tzdata/America/St_Thomas
@@ -1,6 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-
-set TZData(:America/St_Thomas) {
- {-9223372036854775808 -15584 0 LMT}
- {-1846266016 -14400 0 AST}
+if {![info exists TZData(America/Port_of_Spain)]} {
+ LoadTimeZoneFile America/Port_of_Spain
}
+set TZData(:America/St_Thomas) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/St_Vincent b/library/tzdata/America/St_Vincent
index 3a884c7..e3b32fb 100644
--- a/library/tzdata/America/St_Vincent
+++ b/library/tzdata/America/St_Vincent
@@ -1,7 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-
-set TZData(:America/St_Vincent) {
- {-9223372036854775808 -14696 0 LMT}
- {-2524506904 -14696 0 KMT}
- {-1830369304 -14400 0 AST}
+if {![info exists TZData(America/Port_of_Spain)]} {
+ LoadTimeZoneFile America/Port_of_Spain
}
+set TZData(:America/St_Vincent) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Swift_Current b/library/tzdata/America/Swift_Current
index dc4aa37..ad07762 100644
--- a/library/tzdata/America/Swift_Current
+++ b/library/tzdata/America/Swift_Current
@@ -4,7 +4,7 @@ set TZData(:America/Swift_Current) {
{-9223372036854775808 -25880 0 LMT}
{-2030201320 -25200 0 MST}
{-1632063600 -21600 1 MDT}
- {-1614787200 -25200 0 MST}
+ {-1615132800 -25200 0 MST}
{-880210800 -21600 1 MWT}
{-769395600 -21600 1 MPT}
{-765388800 -25200 0 MST}
diff --git a/library/tzdata/America/Toronto b/library/tzdata/America/Toronto
index e4fc91a..09bf786 100644
--- a/library/tzdata/America/Toronto
+++ b/library/tzdata/America/Toronto
@@ -4,7 +4,7 @@ set TZData(:America/Toronto) {
{-9223372036854775808 -19052 0 LMT}
{-2366736148 -18000 0 EST}
{-1632070800 -14400 1 EDT}
- {-1614794400 -18000 0 EST}
+ {-1615140000 -18000 0 EST}
{-1609441200 -18000 0 EST}
{-1601753400 -14400 1 EDT}
{-1583697600 -18000 0 EST}
diff --git a/library/tzdata/America/Tortola b/library/tzdata/America/Tortola
index bf7f1fc..aa6f655 100644
--- a/library/tzdata/America/Tortola
+++ b/library/tzdata/America/Tortola
@@ -1,6 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-
-set TZData(:America/Tortola) {
- {-9223372036854775808 -15508 0 LMT}
- {-1846266092 -14400 0 AST}
+if {![info exists TZData(America/Port_of_Spain)]} {
+ LoadTimeZoneFile America/Port_of_Spain
}
+set TZData(:America/Tortola) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Vancouver b/library/tzdata/America/Vancouver
index b2e0415..aef639a 100644
--- a/library/tzdata/America/Vancouver
+++ b/library/tzdata/America/Vancouver
@@ -4,7 +4,7 @@ set TZData(:America/Vancouver) {
{-9223372036854775808 -29548 0 LMT}
{-2713880852 -28800 0 PST}
{-1632060000 -25200 1 PDT}
- {-1614783600 -28800 0 PST}
+ {-1615129200 -28800 0 PST}
{-880207200 -25200 1 PWT}
{-769395600 -25200 1 PPT}
{-765385200 -28800 0 PST}
diff --git a/library/tzdata/America/Virgin b/library/tzdata/America/Virgin
index 390d7c2..c267e5b 100644
--- a/library/tzdata/America/Virgin
+++ b/library/tzdata/America/Virgin
@@ -1,5 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-if {![info exists TZData(America/St_Thomas)]} {
- LoadTimeZoneFile America/St_Thomas
+if {![info exists TZData(America/Port_of_Spain)]} {
+ LoadTimeZoneFile America/Port_of_Spain
}
-set TZData(:America/Virgin) $TZData(:America/St_Thomas)
+set TZData(:America/Virgin) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Winnipeg b/library/tzdata/America/Winnipeg
index 7e6208a..e6efe47 100644
--- a/library/tzdata/America/Winnipeg
+++ b/library/tzdata/America/Winnipeg
@@ -6,7 +6,7 @@ set TZData(:America/Winnipeg) {
{-1694368800 -18000 1 CDT}
{-1681671600 -21600 0 CST}
{-1632067200 -18000 1 CDT}
- {-1614790800 -21600 0 CST}
+ {-1615136400 -21600 0 CST}
{-1029686400 -18000 1 CDT}
{-1018198800 -21600 0 CST}
{-880214400 -18000 1 CWT}
diff --git a/library/tzdata/Antarctica/Casey b/library/tzdata/Antarctica/Casey
index 119d514..cbe3e3c 100644
--- a/library/tzdata/Antarctica/Casey
+++ b/library/tzdata/Antarctica/Casey
@@ -5,4 +5,6 @@ set TZData(:Antarctica/Casey) {
{-31536000 28800 0 WST}
{1255802400 39600 0 CAST}
{1267714800 28800 0 WST}
+ {1319738400 39600 0 CAST}
+ {1329843600 28800 0 WST}
}
diff --git a/library/tzdata/Antarctica/Davis b/library/tzdata/Antarctica/Davis
index 47aece9..2762d2f 100644
--- a/library/tzdata/Antarctica/Davis
+++ b/library/tzdata/Antarctica/Davis
@@ -7,4 +7,6 @@ set TZData(:Antarctica/Davis) {
{-28857600 25200 0 DAVT}
{1255806000 18000 0 DAVT}
{1268251200 25200 0 DAVT}
+ {1319742000 18000 0 DAVT}
+ {1329854400 25200 0 DAVT}
}
diff --git a/library/tzdata/Antarctica/Macquarie b/library/tzdata/Antarctica/Macquarie
index 9877ee8..bd5cf8a 100644
--- a/library/tzdata/Antarctica/Macquarie
+++ b/library/tzdata/Antarctica/Macquarie
@@ -2,16 +2,11 @@
set TZData(:Antarctica/Macquarie) {
{-9223372036854775808 0 0 zzz}
- {-1861920000 36000 0 EST}
+ {-2214259200 36000 0 EST}
{-1680508800 39600 1 EST}
{-1669892400 39600 0 EST}
{-1665392400 36000 0 EST}
- {-883641600 39600 1 EST}
- {-876128400 36000 0 EST}
- {-860400000 39600 1 EST}
- {-844678800 36000 0 EST}
- {-828345600 39600 1 EST}
- {-813229200 36000 0 EST}
+ {-1601719200 0 0 zzz}
{-94730400 36000 0 EST}
{-71136000 39600 1 EST}
{-55411200 36000 0 EST}
diff --git a/library/tzdata/Antarctica/McMurdo b/library/tzdata/Antarctica/McMurdo
index 670f7eb..3b29ba1 100644
--- a/library/tzdata/Antarctica/McMurdo
+++ b/library/tzdata/Antarctica/McMurdo
@@ -1,257 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-
-set TZData(:Antarctica/McMurdo) {
- {-9223372036854775808 0 0 zzz}
- {-441849600 43200 0 NZST}
- {152632800 46800 1 NZDT}
- {162309600 43200 0 NZST}
- {183477600 46800 1 NZDT}
- {194968800 43200 0 NZST}
- {215532000 46800 1 NZDT}
- {226418400 43200 0 NZST}
- {246981600 46800 1 NZDT}
- {257868000 43200 0 NZST}
- {278431200 46800 1 NZDT}
- {289317600 43200 0 NZST}
- {309880800 46800 1 NZDT}
- {320767200 43200 0 NZST}
- {341330400 46800 1 NZDT}
- {352216800 43200 0 NZST}
- {372780000 46800 1 NZDT}
- {384271200 43200 0 NZST}
- {404834400 46800 1 NZDT}
- {415720800 43200 0 NZST}
- {436284000 46800 1 NZDT}
- {447170400 43200 0 NZST}
- {467733600 46800 1 NZDT}
- {478620000 43200 0 NZST}
- {499183200 46800 1 NZDT}
- {510069600 43200 0 NZST}
- {530632800 46800 1 NZDT}
- {541519200 43200 0 NZST}
- {562082400 46800 1 NZDT}
- {573573600 43200 0 NZST}
- {594136800 46800 1 NZDT}
- {605023200 43200 0 NZST}
- {623772000 46800 1 NZDT}
- {637682400 43200 0 NZST}
- {655221600 46800 1 NZDT}
- {669132000 43200 0 NZST}
- {686671200 46800 1 NZDT}
- {700581600 43200 0 NZST}
- {718120800 46800 1 NZDT}
- {732636000 43200 0 NZST}
- {749570400 46800 1 NZDT}
- {764085600 43200 0 NZST}
- {781020000 46800 1 NZDT}
- {795535200 43200 0 NZST}
- {812469600 46800 1 NZDT}
- {826984800 43200 0 NZST}
- {844524000 46800 1 NZDT}
- {858434400 43200 0 NZST}
- {875973600 46800 1 NZDT}
- {889884000 43200 0 NZST}
- {907423200 46800 1 NZDT}
- {921938400 43200 0 NZST}
- {938872800 46800 1 NZDT}
- {953388000 43200 0 NZST}
- {970322400 46800 1 NZDT}
- {984837600 43200 0 NZST}
- {1002376800 46800 1 NZDT}
- {1016287200 43200 0 NZST}
- {1033826400 46800 1 NZDT}
- {1047736800 43200 0 NZST}
- {1065276000 46800 1 NZDT}
- {1079791200 43200 0 NZST}
- {1096725600 46800 1 NZDT}
- {1111240800 43200 0 NZST}
- {1128175200 46800 1 NZDT}
- {1142690400 43200 0 NZST}
- {1159624800 46800 1 NZDT}
- {1174140000 43200 0 NZST}
- {1191074400 46800 1 NZDT}
- {1207404000 43200 0 NZST}
- {1222524000 46800 1 NZDT}
- {1238853600 43200 0 NZST}
- {1253973600 46800 1 NZDT}
- {1270303200 43200 0 NZST}
- {1285423200 46800 1 NZDT}
- {1301752800 43200 0 NZST}
- {1316872800 46800 1 NZDT}
- {1333202400 43200 0 NZST}
- {1348927200 46800 1 NZDT}
- {1365256800 43200 0 NZST}
- {1380376800 46800 1 NZDT}
- {1396706400 43200 0 NZST}
- {1411826400 46800 1 NZDT}
- {1428156000 43200 0 NZST}
- {1443276000 46800 1 NZDT}
- {1459605600 43200 0 NZST}
- {1474725600 46800 1 NZDT}
- {1491055200 43200 0 NZST}
- {1506175200 46800 1 NZDT}
- {1522504800 43200 0 NZST}
- {1538229600 46800 1 NZDT}
- {1554559200 43200 0 NZST}
- {1569679200 46800 1 NZDT}
- {1586008800 43200 0 NZST}
- {1601128800 46800 1 NZDT}
- {1617458400 43200 0 NZST}
- {1632578400 46800 1 NZDT}
- {1648908000 43200 0 NZST}
- {1664028000 46800 1 NZDT}
- {1680357600 43200 0 NZST}
- {1695477600 46800 1 NZDT}
- {1712412000 43200 0 NZST}
- {1727532000 46800 1 NZDT}
- {1743861600 43200 0 NZST}
- {1758981600 46800 1 NZDT}
- {1775311200 43200 0 NZST}
- {1790431200 46800 1 NZDT}
- {1806760800 43200 0 NZST}
- {1821880800 46800 1 NZDT}
- {1838210400 43200 0 NZST}
- {1853330400 46800 1 NZDT}
- {1869660000 43200 0 NZST}
- {1885384800 46800 1 NZDT}
- {1901714400 43200 0 NZST}
- {1916834400 46800 1 NZDT}
- {1933164000 43200 0 NZST}
- {1948284000 46800 1 NZDT}
- {1964613600 43200 0 NZST}
- {1979733600 46800 1 NZDT}
- {1996063200 43200 0 NZST}
- {2011183200 46800 1 NZDT}
- {2027512800 43200 0 NZST}
- {2042632800 46800 1 NZDT}
- {2058962400 43200 0 NZST}
- {2074687200 46800 1 NZDT}
- {2091016800 43200 0 NZST}
- {2106136800 46800 1 NZDT}
- {2122466400 43200 0 NZST}
- {2137586400 46800 1 NZDT}
- {2153916000 43200 0 NZST}
- {2169036000 46800 1 NZDT}
- {2185365600 43200 0 NZST}
- {2200485600 46800 1 NZDT}
- {2216815200 43200 0 NZST}
- {2232540000 46800 1 NZDT}
- {2248869600 43200 0 NZST}
- {2263989600 46800 1 NZDT}
- {2280319200 43200 0 NZST}
- {2295439200 46800 1 NZDT}
- {2311768800 43200 0 NZST}
- {2326888800 46800 1 NZDT}
- {2343218400 43200 0 NZST}
- {2358338400 46800 1 NZDT}
- {2374668000 43200 0 NZST}
- {2389788000 46800 1 NZDT}
- {2406117600 43200 0 NZST}
- {2421842400 46800 1 NZDT}
- {2438172000 43200 0 NZST}
- {2453292000 46800 1 NZDT}
- {2469621600 43200 0 NZST}
- {2484741600 46800 1 NZDT}
- {2501071200 43200 0 NZST}
- {2516191200 46800 1 NZDT}
- {2532520800 43200 0 NZST}
- {2547640800 46800 1 NZDT}
- {2563970400 43200 0 NZST}
- {2579090400 46800 1 NZDT}
- {2596024800 43200 0 NZST}
- {2611144800 46800 1 NZDT}
- {2627474400 43200 0 NZST}
- {2642594400 46800 1 NZDT}
- {2658924000 43200 0 NZST}
- {2674044000 46800 1 NZDT}
- {2690373600 43200 0 NZST}
- {2705493600 46800 1 NZDT}
- {2721823200 43200 0 NZST}
- {2736943200 46800 1 NZDT}
- {2753272800 43200 0 NZST}
- {2768997600 46800 1 NZDT}
- {2785327200 43200 0 NZST}
- {2800447200 46800 1 NZDT}
- {2816776800 43200 0 NZST}
- {2831896800 46800 1 NZDT}
- {2848226400 43200 0 NZST}
- {2863346400 46800 1 NZDT}
- {2879676000 43200 0 NZST}
- {2894796000 46800 1 NZDT}
- {2911125600 43200 0 NZST}
- {2926245600 46800 1 NZDT}
- {2942575200 43200 0 NZST}
- {2958300000 46800 1 NZDT}
- {2974629600 43200 0 NZST}
- {2989749600 46800 1 NZDT}
- {3006079200 43200 0 NZST}
- {3021199200 46800 1 NZDT}
- {3037528800 43200 0 NZST}
- {3052648800 46800 1 NZDT}
- {3068978400 43200 0 NZST}
- {3084098400 46800 1 NZDT}
- {3100428000 43200 0 NZST}
- {3116152800 46800 1 NZDT}
- {3132482400 43200 0 NZST}
- {3147602400 46800 1 NZDT}
- {3163932000 43200 0 NZST}
- {3179052000 46800 1 NZDT}
- {3195381600 43200 0 NZST}
- {3210501600 46800 1 NZDT}
- {3226831200 43200 0 NZST}
- {3241951200 46800 1 NZDT}
- {3258280800 43200 0 NZST}
- {3273400800 46800 1 NZDT}
- {3289730400 43200 0 NZST}
- {3305455200 46800 1 NZDT}
- {3321784800 43200 0 NZST}
- {3336904800 46800 1 NZDT}
- {3353234400 43200 0 NZST}
- {3368354400 46800 1 NZDT}
- {3384684000 43200 0 NZST}
- {3399804000 46800 1 NZDT}
- {3416133600 43200 0 NZST}
- {3431253600 46800 1 NZDT}
- {3447583200 43200 0 NZST}
- {3462703200 46800 1 NZDT}
- {3479637600 43200 0 NZST}
- {3494757600 46800 1 NZDT}
- {3511087200 43200 0 NZST}
- {3526207200 46800 1 NZDT}
- {3542536800 43200 0 NZST}
- {3557656800 46800 1 NZDT}
- {3573986400 43200 0 NZST}
- {3589106400 46800 1 NZDT}
- {3605436000 43200 0 NZST}
- {3620556000 46800 1 NZDT}
- {3636885600 43200 0 NZST}
- {3652610400 46800 1 NZDT}
- {3668940000 43200 0 NZST}
- {3684060000 46800 1 NZDT}
- {3700389600 43200 0 NZST}
- {3715509600 46800 1 NZDT}
- {3731839200 43200 0 NZST}
- {3746959200 46800 1 NZDT}
- {3763288800 43200 0 NZST}
- {3778408800 46800 1 NZDT}
- {3794738400 43200 0 NZST}
- {3809858400 46800 1 NZDT}
- {3826188000 43200 0 NZST}
- {3841912800 46800 1 NZDT}
- {3858242400 43200 0 NZST}
- {3873362400 46800 1 NZDT}
- {3889692000 43200 0 NZST}
- {3904812000 46800 1 NZDT}
- {3921141600 43200 0 NZST}
- {3936261600 46800 1 NZDT}
- {3952591200 43200 0 NZST}
- {3967711200 46800 1 NZDT}
- {3984040800 43200 0 NZST}
- {3999765600 46800 1 NZDT}
- {4016095200 43200 0 NZST}
- {4031215200 46800 1 NZDT}
- {4047544800 43200 0 NZST}
- {4062664800 46800 1 NZDT}
- {4078994400 43200 0 NZST}
- {4094114400 46800 1 NZDT}
+if {![info exists TZData(Pacific/Auckland)]} {
+ LoadTimeZoneFile Pacific/Auckland
}
+set TZData(:Antarctica/McMurdo) $TZData(:Pacific/Auckland)
diff --git a/library/tzdata/Antarctica/Palmer b/library/tzdata/Antarctica/Palmer
index 1e24754..e87b171 100644
--- a/library/tzdata/Antarctica/Palmer
+++ b/library/tzdata/Antarctica/Palmer
@@ -67,188 +67,188 @@ set TZData(:Antarctica/Palmer) {
{1160884800 -10800 1 CLST}
{1173582000 -14400 0 CLT}
{1192334400 -10800 1 CLST}
- {1205031600 -14400 0 CLT}
+ {1206846000 -14400 0 CLT}
{1223784000 -10800 1 CLST}
{1237086000 -14400 0 CLT}
{1255233600 -10800 1 CLST}
- {1268535600 -14400 0 CLT}
+ {1270350000 -14400 0 CLT}
{1286683200 -10800 1 CLST}
- {1299985200 -14400 0 CLT}
- {1318132800 -10800 1 CLST}
- {1331434800 -14400 0 CLT}
- {1350187200 -10800 1 CLST}
- {1362884400 -14400 0 CLT}
- {1381636800 -10800 1 CLST}
- {1394334000 -14400 0 CLT}
- {1413086400 -10800 1 CLST}
- {1426388400 -14400 0 CLT}
- {1444536000 -10800 1 CLST}
- {1457838000 -14400 0 CLT}
- {1475985600 -10800 1 CLST}
- {1489287600 -14400 0 CLT}
- {1508040000 -10800 1 CLST}
- {1520737200 -14400 0 CLT}
- {1539489600 -10800 1 CLST}
- {1552186800 -14400 0 CLT}
- {1570939200 -10800 1 CLST}
- {1584241200 -14400 0 CLT}
- {1602388800 -10800 1 CLST}
- {1615690800 -14400 0 CLT}
- {1633838400 -10800 1 CLST}
- {1647140400 -14400 0 CLT}
- {1665288000 -10800 1 CLST}
- {1678590000 -14400 0 CLT}
- {1697342400 -10800 1 CLST}
- {1710039600 -14400 0 CLT}
- {1728792000 -10800 1 CLST}
- {1741489200 -14400 0 CLT}
- {1760241600 -10800 1 CLST}
- {1773543600 -14400 0 CLT}
- {1791691200 -10800 1 CLST}
- {1804993200 -14400 0 CLT}
- {1823140800 -10800 1 CLST}
- {1836442800 -14400 0 CLT}
- {1855195200 -10800 1 CLST}
- {1867892400 -14400 0 CLT}
- {1886644800 -10800 1 CLST}
- {1899342000 -14400 0 CLT}
- {1918094400 -10800 1 CLST}
- {1930791600 -14400 0 CLT}
- {1949544000 -10800 1 CLST}
- {1962846000 -14400 0 CLT}
- {1980993600 -10800 1 CLST}
- {1994295600 -14400 0 CLT}
- {2012443200 -10800 1 CLST}
- {2025745200 -14400 0 CLT}
- {2044497600 -10800 1 CLST}
- {2057194800 -14400 0 CLT}
- {2075947200 -10800 1 CLST}
- {2088644400 -14400 0 CLT}
- {2107396800 -10800 1 CLST}
- {2120698800 -14400 0 CLT}
- {2138846400 -10800 1 CLST}
- {2152148400 -14400 0 CLT}
- {2170296000 -10800 1 CLST}
- {2183598000 -14400 0 CLT}
- {2201745600 -10800 1 CLST}
- {2215047600 -14400 0 CLT}
- {2233800000 -10800 1 CLST}
- {2246497200 -14400 0 CLT}
- {2265249600 -10800 1 CLST}
- {2277946800 -14400 0 CLT}
- {2296699200 -10800 1 CLST}
- {2310001200 -14400 0 CLT}
- {2328148800 -10800 1 CLST}
- {2341450800 -14400 0 CLT}
- {2359598400 -10800 1 CLST}
- {2372900400 -14400 0 CLT}
- {2391652800 -10800 1 CLST}
- {2404350000 -14400 0 CLT}
- {2423102400 -10800 1 CLST}
- {2435799600 -14400 0 CLT}
- {2454552000 -10800 1 CLST}
- {2467854000 -14400 0 CLT}
- {2486001600 -10800 1 CLST}
- {2499303600 -14400 0 CLT}
- {2517451200 -10800 1 CLST}
- {2530753200 -14400 0 CLT}
- {2548900800 -10800 1 CLST}
- {2562202800 -14400 0 CLT}
- {2580955200 -10800 1 CLST}
- {2593652400 -14400 0 CLT}
- {2612404800 -10800 1 CLST}
- {2625102000 -14400 0 CLT}
- {2643854400 -10800 1 CLST}
- {2657156400 -14400 0 CLT}
- {2675304000 -10800 1 CLST}
- {2688606000 -14400 0 CLT}
- {2706753600 -10800 1 CLST}
- {2720055600 -14400 0 CLT}
- {2738808000 -10800 1 CLST}
- {2751505200 -14400 0 CLT}
- {2770257600 -10800 1 CLST}
- {2782954800 -14400 0 CLT}
- {2801707200 -10800 1 CLST}
- {2814404400 -14400 0 CLT}
- {2833156800 -10800 1 CLST}
- {2846458800 -14400 0 CLT}
- {2864606400 -10800 1 CLST}
- {2877908400 -14400 0 CLT}
- {2896056000 -10800 1 CLST}
- {2909358000 -14400 0 CLT}
- {2928110400 -10800 1 CLST}
- {2940807600 -14400 0 CLT}
- {2959560000 -10800 1 CLST}
- {2972257200 -14400 0 CLT}
- {2991009600 -10800 1 CLST}
- {3004311600 -14400 0 CLT}
- {3022459200 -10800 1 CLST}
- {3035761200 -14400 0 CLT}
- {3053908800 -10800 1 CLST}
- {3067210800 -14400 0 CLT}
- {3085358400 -10800 1 CLST}
- {3098660400 -14400 0 CLT}
- {3117412800 -10800 1 CLST}
- {3130110000 -14400 0 CLT}
- {3148862400 -10800 1 CLST}
- {3161559600 -14400 0 CLT}
- {3180312000 -10800 1 CLST}
- {3193614000 -14400 0 CLT}
- {3211761600 -10800 1 CLST}
- {3225063600 -14400 0 CLT}
- {3243211200 -10800 1 CLST}
- {3256513200 -14400 0 CLT}
- {3275265600 -10800 1 CLST}
- {3287962800 -14400 0 CLT}
- {3306715200 -10800 1 CLST}
- {3319412400 -14400 0 CLT}
- {3338164800 -10800 1 CLST}
- {3351466800 -14400 0 CLT}
- {3369614400 -10800 1 CLST}
- {3382916400 -14400 0 CLT}
- {3401064000 -10800 1 CLST}
- {3414366000 -14400 0 CLT}
- {3432513600 -10800 1 CLST}
- {3445815600 -14400 0 CLT}
- {3464568000 -10800 1 CLST}
- {3477265200 -14400 0 CLT}
- {3496017600 -10800 1 CLST}
- {3508714800 -14400 0 CLT}
- {3527467200 -10800 1 CLST}
- {3540769200 -14400 0 CLT}
- {3558916800 -10800 1 CLST}
- {3572218800 -14400 0 CLT}
- {3590366400 -10800 1 CLST}
- {3603668400 -14400 0 CLT}
- {3622420800 -10800 1 CLST}
- {3635118000 -14400 0 CLT}
- {3653870400 -10800 1 CLST}
- {3666567600 -14400 0 CLT}
- {3685320000 -10800 1 CLST}
- {3698017200 -14400 0 CLT}
- {3716769600 -10800 1 CLST}
- {3730071600 -14400 0 CLT}
- {3748219200 -10800 1 CLST}
- {3761521200 -14400 0 CLT}
- {3779668800 -10800 1 CLST}
- {3792970800 -14400 0 CLT}
- {3811723200 -10800 1 CLST}
- {3824420400 -14400 0 CLT}
- {3843172800 -10800 1 CLST}
- {3855870000 -14400 0 CLT}
- {3874622400 -10800 1 CLST}
- {3887924400 -14400 0 CLT}
- {3906072000 -10800 1 CLST}
- {3919374000 -14400 0 CLT}
- {3937521600 -10800 1 CLST}
- {3950823600 -14400 0 CLT}
- {3968971200 -10800 1 CLST}
- {3982273200 -14400 0 CLT}
- {4001025600 -10800 1 CLST}
- {4013722800 -14400 0 CLT}
- {4032475200 -10800 1 CLST}
- {4045172400 -14400 0 CLT}
- {4063924800 -10800 1 CLST}
- {4077226800 -14400 0 CLT}
- {4095374400 -10800 1 CLST}
+ {1304823600 -14400 0 CLT}
+ {1313899200 -10800 1 CLST}
+ {1335668400 -14400 0 CLT}
+ {1346558400 -10800 1 CLST}
+ {1367118000 -14400 0 CLT}
+ {1378612800 -10800 1 CLST}
+ {1398567600 -14400 0 CLT}
+ {1410062400 -10800 1 CLST}
+ {1430017200 -14400 0 CLT}
+ {1441512000 -10800 1 CLST}
+ {1461466800 -14400 0 CLT}
+ {1472961600 -10800 1 CLST}
+ {1492916400 -14400 0 CLT}
+ {1504411200 -10800 1 CLST}
+ {1524970800 -14400 0 CLT}
+ {1535860800 -10800 1 CLST}
+ {1556420400 -14400 0 CLT}
+ {1567915200 -10800 1 CLST}
+ {1587870000 -14400 0 CLT}
+ {1599364800 -10800 1 CLST}
+ {1619319600 -14400 0 CLT}
+ {1630814400 -10800 1 CLST}
+ {1650769200 -14400 0 CLT}
+ {1662264000 -10800 1 CLST}
+ {1682218800 -14400 0 CLT}
+ {1693713600 -10800 1 CLST}
+ {1714273200 -14400 0 CLT}
+ {1725768000 -10800 1 CLST}
+ {1745722800 -14400 0 CLT}
+ {1757217600 -10800 1 CLST}
+ {1777172400 -14400 0 CLT}
+ {1788667200 -10800 1 CLST}
+ {1808622000 -14400 0 CLT}
+ {1820116800 -10800 1 CLST}
+ {1840071600 -14400 0 CLT}
+ {1851566400 -10800 1 CLST}
+ {1872126000 -14400 0 CLT}
+ {1883016000 -10800 1 CLST}
+ {1903575600 -14400 0 CLT}
+ {1915070400 -10800 1 CLST}
+ {1935025200 -14400 0 CLT}
+ {1946520000 -10800 1 CLST}
+ {1966474800 -14400 0 CLT}
+ {1977969600 -10800 1 CLST}
+ {1997924400 -14400 0 CLT}
+ {2009419200 -10800 1 CLST}
+ {2029374000 -14400 0 CLT}
+ {2040868800 -10800 1 CLST}
+ {2061428400 -14400 0 CLT}
+ {2072318400 -10800 1 CLST}
+ {2092878000 -14400 0 CLT}
+ {2104372800 -10800 1 CLST}
+ {2124327600 -14400 0 CLT}
+ {2135822400 -10800 1 CLST}
+ {2155777200 -14400 0 CLT}
+ {2167272000 -10800 1 CLST}
+ {2187226800 -14400 0 CLT}
+ {2198721600 -10800 1 CLST}
+ {2219281200 -14400 0 CLT}
+ {2230171200 -10800 1 CLST}
+ {2250730800 -14400 0 CLT}
+ {2262225600 -10800 1 CLST}
+ {2282180400 -14400 0 CLT}
+ {2293675200 -10800 1 CLST}
+ {2313630000 -14400 0 CLT}
+ {2325124800 -10800 1 CLST}
+ {2345079600 -14400 0 CLT}
+ {2356574400 -10800 1 CLST}
+ {2376529200 -14400 0 CLT}
+ {2388024000 -10800 1 CLST}
+ {2408583600 -14400 0 CLT}
+ {2419473600 -10800 1 CLST}
+ {2440033200 -14400 0 CLT}
+ {2451528000 -10800 1 CLST}
+ {2471482800 -14400 0 CLT}
+ {2482977600 -10800 1 CLST}
+ {2502932400 -14400 0 CLT}
+ {2514427200 -10800 1 CLST}
+ {2534382000 -14400 0 CLT}
+ {2545876800 -10800 1 CLST}
+ {2565831600 -14400 0 CLT}
+ {2577326400 -10800 1 CLST}
+ {2597886000 -14400 0 CLT}
+ {2609380800 -10800 1 CLST}
+ {2629335600 -14400 0 CLT}
+ {2640830400 -10800 1 CLST}
+ {2660785200 -14400 0 CLT}
+ {2672280000 -10800 1 CLST}
+ {2692234800 -14400 0 CLT}
+ {2703729600 -10800 1 CLST}
+ {2723684400 -14400 0 CLT}
+ {2735179200 -10800 1 CLST}
+ {2755738800 -14400 0 CLT}
+ {2766628800 -10800 1 CLST}
+ {2787188400 -14400 0 CLT}
+ {2798683200 -10800 1 CLST}
+ {2818638000 -14400 0 CLT}
+ {2830132800 -10800 1 CLST}
+ {2850087600 -14400 0 CLT}
+ {2861582400 -10800 1 CLST}
+ {2881537200 -14400 0 CLT}
+ {2893032000 -10800 1 CLST}
+ {2912986800 -14400 0 CLT}
+ {2924481600 -10800 1 CLST}
+ {2945041200 -14400 0 CLT}
+ {2955931200 -10800 1 CLST}
+ {2976490800 -14400 0 CLT}
+ {2987985600 -10800 1 CLST}
+ {3007940400 -14400 0 CLT}
+ {3019435200 -10800 1 CLST}
+ {3039390000 -14400 0 CLT}
+ {3050884800 -10800 1 CLST}
+ {3070839600 -14400 0 CLT}
+ {3082334400 -10800 1 CLST}
+ {3102894000 -14400 0 CLT}
+ {3113784000 -10800 1 CLST}
+ {3134343600 -14400 0 CLT}
+ {3145838400 -10800 1 CLST}
+ {3165793200 -14400 0 CLT}
+ {3177288000 -10800 1 CLST}
+ {3197242800 -14400 0 CLT}
+ {3208737600 -10800 1 CLST}
+ {3228692400 -14400 0 CLT}
+ {3240187200 -10800 1 CLST}
+ {3260142000 -14400 0 CLT}
+ {3271636800 -10800 1 CLST}
+ {3292196400 -14400 0 CLT}
+ {3303086400 -10800 1 CLST}
+ {3323646000 -14400 0 CLT}
+ {3335140800 -10800 1 CLST}
+ {3355095600 -14400 0 CLT}
+ {3366590400 -10800 1 CLST}
+ {3386545200 -14400 0 CLT}
+ {3398040000 -10800 1 CLST}
+ {3417994800 -14400 0 CLT}
+ {3429489600 -10800 1 CLST}
+ {3449444400 -14400 0 CLT}
+ {3460939200 -10800 1 CLST}
+ {3481498800 -14400 0 CLT}
+ {3492993600 -10800 1 CLST}
+ {3512948400 -14400 0 CLT}
+ {3524443200 -10800 1 CLST}
+ {3544398000 -14400 0 CLT}
+ {3555892800 -10800 1 CLST}
+ {3575847600 -14400 0 CLT}
+ {3587342400 -10800 1 CLST}
+ {3607297200 -14400 0 CLT}
+ {3618792000 -10800 1 CLST}
+ {3639351600 -14400 0 CLT}
+ {3650241600 -10800 1 CLST}
+ {3670801200 -14400 0 CLT}
+ {3682296000 -10800 1 CLST}
+ {3702250800 -14400 0 CLT}
+ {3713745600 -10800 1 CLST}
+ {3733700400 -14400 0 CLT}
+ {3745195200 -10800 1 CLST}
+ {3765150000 -14400 0 CLT}
+ {3776644800 -10800 1 CLST}
+ {3796599600 -14400 0 CLT}
+ {3808094400 -10800 1 CLST}
+ {3828654000 -14400 0 CLT}
+ {3839544000 -10800 1 CLST}
+ {3860103600 -14400 0 CLT}
+ {3871598400 -10800 1 CLST}
+ {3891553200 -14400 0 CLT}
+ {3903048000 -10800 1 CLST}
+ {3923002800 -14400 0 CLT}
+ {3934497600 -10800 1 CLST}
+ {3954452400 -14400 0 CLT}
+ {3965947200 -10800 1 CLST}
+ {3986506800 -14400 0 CLT}
+ {3997396800 -10800 1 CLST}
+ {4017956400 -14400 0 CLT}
+ {4029451200 -10800 1 CLST}
+ {4049406000 -14400 0 CLT}
+ {4060900800 -10800 1 CLST}
+ {4080855600 -14400 0 CLT}
+ {4092350400 -10800 1 CLST}
}
diff --git a/library/tzdata/Antarctica/South_Pole b/library/tzdata/Antarctica/South_Pole
index 34d0db1..544bde4 100644
--- a/library/tzdata/Antarctica/South_Pole
+++ b/library/tzdata/Antarctica/South_Pole
@@ -1,5 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-if {![info exists TZData(Antarctica/McMurdo)]} {
- LoadTimeZoneFile Antarctica/McMurdo
+if {![info exists TZData(Pacific/Auckland)]} {
+ LoadTimeZoneFile Pacific/Auckland
}
-set TZData(:Antarctica/South_Pole) $TZData(:Antarctica/McMurdo)
+set TZData(:Antarctica/South_Pole) $TZData(:Pacific/Auckland)
diff --git a/library/tzdata/Asia/Aden b/library/tzdata/Asia/Aden
index e939235..399d9f0 100644
--- a/library/tzdata/Asia/Aden
+++ b/library/tzdata/Asia/Aden
@@ -1,6 +1,6 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Asia/Aden) {
- {-9223372036854775808 10848 0 LMT}
- {-631162848 10800 0 AST}
+ {-9223372036854775808 10794 0 LMT}
+ {-631162794 10800 0 AST}
}
diff --git a/library/tzdata/Asia/Amman b/library/tzdata/Asia/Amman
index bf30508..d5e8616 100644
--- a/library/tzdata/Asia/Amman
+++ b/library/tzdata/Asia/Amman
@@ -70,179 +70,5 @@ set TZData(:Asia/Amman) {
{1301608800 10800 1 EEST}
{1319752800 7200 0 EET}
{1333058400 10800 1 EEST}
- {1351202400 7200 0 EET}
- {1364508000 10800 1 EEST}
- {1382652000 7200 0 EET}
- {1395957600 10800 1 EEST}
- {1414706400 7200 0 EET}
- {1427407200 10800 1 EEST}
- {1446156000 7200 0 EET}
- {1459461600 10800 1 EEST}
- {1477605600 7200 0 EET}
- {1490911200 10800 1 EEST}
- {1509055200 7200 0 EET}
- {1522360800 10800 1 EEST}
- {1540504800 7200 0 EET}
- {1553810400 10800 1 EEST}
- {1571954400 7200 0 EET}
- {1585260000 10800 1 EEST}
- {1604008800 7200 0 EET}
- {1616709600 10800 1 EEST}
- {1635458400 7200 0 EET}
- {1648764000 10800 1 EEST}
- {1666908000 7200 0 EET}
- {1680213600 10800 1 EEST}
- {1698357600 7200 0 EET}
- {1711663200 10800 1 EEST}
- {1729807200 7200 0 EET}
- {1743112800 10800 1 EEST}
- {1761861600 7200 0 EET}
- {1774562400 10800 1 EEST}
- {1793311200 7200 0 EET}
- {1806012000 10800 1 EEST}
- {1824760800 7200 0 EET}
- {1838066400 10800 1 EEST}
- {1856210400 7200 0 EET}
- {1869516000 10800 1 EEST}
- {1887660000 7200 0 EET}
- {1900965600 10800 1 EEST}
- {1919109600 7200 0 EET}
- {1932415200 10800 1 EEST}
- {1951164000 7200 0 EET}
- {1963864800 10800 1 EEST}
- {1982613600 7200 0 EET}
- {1995919200 10800 1 EEST}
- {2014063200 7200 0 EET}
- {2027368800 10800 1 EEST}
- {2045512800 7200 0 EET}
- {2058818400 10800 1 EEST}
- {2076962400 7200 0 EET}
- {2090268000 10800 1 EEST}
- {2109016800 7200 0 EET}
- {2121717600 10800 1 EEST}
- {2140466400 7200 0 EET}
- {2153167200 10800 1 EEST}
- {2171916000 7200 0 EET}
- {2185221600 10800 1 EEST}
- {2203365600 7200 0 EET}
- {2216671200 10800 1 EEST}
- {2234815200 7200 0 EET}
- {2248120800 10800 1 EEST}
- {2266264800 7200 0 EET}
- {2279570400 10800 1 EEST}
- {2298319200 7200 0 EET}
- {2311020000 10800 1 EEST}
- {2329768800 7200 0 EET}
- {2343074400 10800 1 EEST}
- {2361218400 7200 0 EET}
- {2374524000 10800 1 EEST}
- {2392668000 7200 0 EET}
- {2405973600 10800 1 EEST}
- {2424117600 7200 0 EET}
- {2437423200 10800 1 EEST}
- {2455567200 7200 0 EET}
- {2468872800 10800 1 EEST}
- {2487621600 7200 0 EET}
- {2500322400 10800 1 EEST}
- {2519071200 7200 0 EET}
- {2532376800 10800 1 EEST}
- {2550520800 7200 0 EET}
- {2563826400 10800 1 EEST}
- {2581970400 7200 0 EET}
- {2595276000 10800 1 EEST}
- {2613420000 7200 0 EET}
- {2626725600 10800 1 EEST}
- {2645474400 7200 0 EET}
- {2658175200 10800 1 EEST}
- {2676924000 7200 0 EET}
- {2689624800 10800 1 EEST}
- {2708373600 7200 0 EET}
- {2721679200 10800 1 EEST}
- {2739823200 7200 0 EET}
- {2753128800 10800 1 EEST}
- {2771272800 7200 0 EET}
- {2784578400 10800 1 EEST}
- {2802722400 7200 0 EET}
- {2816028000 10800 1 EEST}
- {2834776800 7200 0 EET}
- {2847477600 10800 1 EEST}
- {2866226400 7200 0 EET}
- {2879532000 10800 1 EEST}
- {2897676000 7200 0 EET}
- {2910981600 10800 1 EEST}
- {2929125600 7200 0 EET}
- {2942431200 10800 1 EEST}
- {2960575200 7200 0 EET}
- {2973880800 10800 1 EEST}
- {2992629600 7200 0 EET}
- {3005330400 10800 1 EEST}
- {3024079200 7200 0 EET}
- {3036780000 10800 1 EEST}
- {3055528800 7200 0 EET}
- {3068834400 10800 1 EEST}
- {3086978400 7200 0 EET}
- {3100284000 10800 1 EEST}
- {3118428000 7200 0 EET}
- {3131733600 10800 1 EEST}
- {3149877600 7200 0 EET}
- {3163183200 10800 1 EEST}
- {3181932000 7200 0 EET}
- {3194632800 10800 1 EEST}
- {3213381600 7200 0 EET}
- {3226687200 10800 1 EEST}
- {3244831200 7200 0 EET}
- {3258136800 10800 1 EEST}
- {3276280800 7200 0 EET}
- {3289586400 10800 1 EEST}
- {3307730400 7200 0 EET}
- {3321036000 10800 1 EEST}
- {3339180000 7200 0 EET}
- {3352485600 10800 1 EEST}
- {3371234400 7200 0 EET}
- {3383935200 10800 1 EEST}
- {3402684000 7200 0 EET}
- {3415989600 10800 1 EEST}
- {3434133600 7200 0 EET}
- {3447439200 10800 1 EEST}
- {3465583200 7200 0 EET}
- {3478888800 10800 1 EEST}
- {3497032800 7200 0 EET}
- {3510338400 10800 1 EEST}
- {3529087200 7200 0 EET}
- {3541788000 10800 1 EEST}
- {3560536800 7200 0 EET}
- {3573237600 10800 1 EEST}
- {3591986400 7200 0 EET}
- {3605292000 10800 1 EEST}
- {3623436000 7200 0 EET}
- {3636741600 10800 1 EEST}
- {3654885600 7200 0 EET}
- {3668191200 10800 1 EEST}
- {3686335200 7200 0 EET}
- {3699640800 10800 1 EEST}
- {3718389600 7200 0 EET}
- {3731090400 10800 1 EEST}
- {3749839200 7200 0 EET}
- {3763144800 10800 1 EEST}
- {3781288800 7200 0 EET}
- {3794594400 10800 1 EEST}
- {3812738400 7200 0 EET}
- {3826044000 10800 1 EEST}
- {3844188000 7200 0 EET}
- {3857493600 10800 1 EEST}
- {3876242400 7200 0 EET}
- {3888943200 10800 1 EEST}
- {3907692000 7200 0 EET}
- {3920392800 10800 1 EEST}
- {3939141600 7200 0 EET}
- {3952447200 10800 1 EEST}
- {3970591200 7200 0 EET}
- {3983896800 10800 1 EEST}
- {4002040800 7200 0 EET}
- {4015346400 10800 1 EEST}
- {4033490400 7200 0 EET}
- {4046796000 10800 1 EEST}
- {4065544800 7200 0 EET}
- {4078245600 10800 1 EEST}
- {4096994400 7200 0 EET}
+ {1351202400 10800 0 AST}
}
diff --git a/library/tzdata/Asia/Damascus b/library/tzdata/Asia/Damascus
index 2ea1770..fafef49 100644
--- a/library/tzdata/Asia/Damascus
+++ b/library/tzdata/Asia/Damascus
@@ -101,180 +101,180 @@ set TZData(:Asia/Damascus) {
{1288299600 7200 0 EET}
{1301608800 10800 1 EEST}
{1319749200 7200 0 EET}
- {1333663200 10800 1 EEST}
+ {1333058400 10800 1 EEST}
{1351198800 7200 0 EET}
- {1365112800 10800 1 EEST}
+ {1364508000 10800 1 EEST}
{1382648400 7200 0 EET}
- {1396562400 10800 1 EEST}
+ {1395957600 10800 1 EEST}
{1414702800 7200 0 EET}
- {1428012000 10800 1 EEST}
+ {1427407200 10800 1 EEST}
{1446152400 7200 0 EET}
- {1459461600 10800 1 EEST}
+ {1458856800 10800 1 EEST}
{1477602000 7200 0 EET}
- {1491516000 10800 1 EEST}
+ {1490911200 10800 1 EEST}
{1509051600 7200 0 EET}
- {1522965600 10800 1 EEST}
+ {1522360800 10800 1 EEST}
{1540501200 7200 0 EET}
- {1554415200 10800 1 EEST}
+ {1553810400 10800 1 EEST}
{1571950800 7200 0 EET}
- {1585864800 10800 1 EEST}
+ {1585260000 10800 1 EEST}
{1604005200 7200 0 EET}
- {1617314400 10800 1 EEST}
+ {1616709600 10800 1 EEST}
{1635454800 7200 0 EET}
- {1648764000 10800 1 EEST}
+ {1648159200 10800 1 EEST}
{1666904400 7200 0 EET}
- {1680818400 10800 1 EEST}
+ {1680213600 10800 1 EEST}
{1698354000 7200 0 EET}
- {1712268000 10800 1 EEST}
+ {1711663200 10800 1 EEST}
{1729803600 7200 0 EET}
- {1743717600 10800 1 EEST}
+ {1743112800 10800 1 EEST}
{1761858000 7200 0 EET}
- {1775167200 10800 1 EEST}
+ {1774562400 10800 1 EEST}
{1793307600 7200 0 EET}
- {1806616800 10800 1 EEST}
+ {1806012000 10800 1 EEST}
{1824757200 7200 0 EET}
- {1838671200 10800 1 EEST}
+ {1838066400 10800 1 EEST}
{1856206800 7200 0 EET}
- {1870120800 10800 1 EEST}
+ {1869516000 10800 1 EEST}
{1887656400 7200 0 EET}
- {1901570400 10800 1 EEST}
+ {1900965600 10800 1 EEST}
{1919106000 7200 0 EET}
- {1933020000 10800 1 EEST}
+ {1932415200 10800 1 EEST}
{1951160400 7200 0 EET}
- {1964469600 10800 1 EEST}
+ {1963864800 10800 1 EEST}
{1982610000 7200 0 EET}
- {1995919200 10800 1 EEST}
+ {1995314400 10800 1 EEST}
{2014059600 7200 0 EET}
- {2027973600 10800 1 EEST}
+ {2027368800 10800 1 EEST}
{2045509200 7200 0 EET}
- {2059423200 10800 1 EEST}
+ {2058818400 10800 1 EEST}
{2076958800 7200 0 EET}
- {2090872800 10800 1 EEST}
+ {2090268000 10800 1 EEST}
{2109013200 7200 0 EET}
- {2122322400 10800 1 EEST}
+ {2121717600 10800 1 EEST}
{2140462800 7200 0 EET}
- {2153772000 10800 1 EEST}
+ {2153167200 10800 1 EEST}
{2171912400 7200 0 EET}
- {2185221600 10800 1 EEST}
+ {2184616800 10800 1 EEST}
{2203362000 7200 0 EET}
- {2217276000 10800 1 EEST}
+ {2216671200 10800 1 EEST}
{2234811600 7200 0 EET}
- {2248725600 10800 1 EEST}
+ {2248120800 10800 1 EEST}
{2266261200 7200 0 EET}
- {2280175200 10800 1 EEST}
+ {2279570400 10800 1 EEST}
{2298315600 7200 0 EET}
- {2311624800 10800 1 EEST}
+ {2311020000 10800 1 EEST}
{2329765200 7200 0 EET}
- {2343074400 10800 1 EEST}
+ {2342469600 10800 1 EEST}
{2361214800 7200 0 EET}
- {2375128800 10800 1 EEST}
+ {2374524000 10800 1 EEST}
{2392664400 7200 0 EET}
- {2406578400 10800 1 EEST}
+ {2405973600 10800 1 EEST}
{2424114000 7200 0 EET}
- {2438028000 10800 1 EEST}
+ {2437423200 10800 1 EEST}
{2455563600 7200 0 EET}
- {2469477600 10800 1 EEST}
+ {2468872800 10800 1 EEST}
{2487618000 7200 0 EET}
- {2500927200 10800 1 EEST}
+ {2500322400 10800 1 EEST}
{2519067600 7200 0 EET}
- {2532376800 10800 1 EEST}
+ {2531772000 10800 1 EEST}
{2550517200 7200 0 EET}
- {2564431200 10800 1 EEST}
+ {2563826400 10800 1 EEST}
{2581966800 7200 0 EET}
- {2595880800 10800 1 EEST}
+ {2595276000 10800 1 EEST}
{2613416400 7200 0 EET}
- {2627330400 10800 1 EEST}
+ {2626725600 10800 1 EEST}
{2645470800 7200 0 EET}
- {2658780000 10800 1 EEST}
+ {2658175200 10800 1 EEST}
{2676920400 7200 0 EET}
- {2690229600 10800 1 EEST}
+ {2689624800 10800 1 EEST}
{2708370000 7200 0 EET}
- {2722284000 10800 1 EEST}
+ {2721679200 10800 1 EEST}
{2739819600 7200 0 EET}
- {2753733600 10800 1 EEST}
+ {2753128800 10800 1 EEST}
{2771269200 7200 0 EET}
- {2785183200 10800 1 EEST}
+ {2784578400 10800 1 EEST}
{2802718800 7200 0 EET}
- {2816632800 10800 1 EEST}
+ {2816028000 10800 1 EEST}
{2834773200 7200 0 EET}
- {2848082400 10800 1 EEST}
+ {2847477600 10800 1 EEST}
{2866222800 7200 0 EET}
- {2879532000 10800 1 EEST}
+ {2878927200 10800 1 EEST}
{2897672400 7200 0 EET}
- {2911586400 10800 1 EEST}
+ {2910981600 10800 1 EEST}
{2929122000 7200 0 EET}
- {2943036000 10800 1 EEST}
+ {2942431200 10800 1 EEST}
{2960571600 7200 0 EET}
- {2974485600 10800 1 EEST}
+ {2973880800 10800 1 EEST}
{2992626000 7200 0 EET}
- {3005935200 10800 1 EEST}
+ {3005330400 10800 1 EEST}
{3024075600 7200 0 EET}
- {3037384800 10800 1 EEST}
+ {3036780000 10800 1 EEST}
{3055525200 7200 0 EET}
- {3068834400 10800 1 EEST}
+ {3068229600 10800 1 EEST}
{3086974800 7200 0 EET}
- {3100888800 10800 1 EEST}
+ {3100284000 10800 1 EEST}
{3118424400 7200 0 EET}
- {3132338400 10800 1 EEST}
+ {3131733600 10800 1 EEST}
{3149874000 7200 0 EET}
- {3163788000 10800 1 EEST}
+ {3163183200 10800 1 EEST}
{3181928400 7200 0 EET}
- {3195237600 10800 1 EEST}
+ {3194632800 10800 1 EEST}
{3213378000 7200 0 EET}
- {3226687200 10800 1 EEST}
+ {3226082400 10800 1 EEST}
{3244827600 7200 0 EET}
- {3258741600 10800 1 EEST}
+ {3258136800 10800 1 EEST}
{3276277200 7200 0 EET}
- {3290191200 10800 1 EEST}
+ {3289586400 10800 1 EEST}
{3307726800 7200 0 EET}
- {3321640800 10800 1 EEST}
+ {3321036000 10800 1 EEST}
{3339176400 7200 0 EET}
- {3353090400 10800 1 EEST}
+ {3352485600 10800 1 EEST}
{3371230800 7200 0 EET}
- {3384540000 10800 1 EEST}
+ {3383935200 10800 1 EEST}
{3402680400 7200 0 EET}
- {3415989600 10800 1 EEST}
+ {3415384800 10800 1 EEST}
{3434130000 7200 0 EET}
- {3448044000 10800 1 EEST}
+ {3447439200 10800 1 EEST}
{3465579600 7200 0 EET}
- {3479493600 10800 1 EEST}
+ {3478888800 10800 1 EEST}
{3497029200 7200 0 EET}
- {3510943200 10800 1 EEST}
+ {3510338400 10800 1 EEST}
{3529083600 7200 0 EET}
- {3542392800 10800 1 EEST}
+ {3541788000 10800 1 EEST}
{3560533200 7200 0 EET}
- {3573842400 10800 1 EEST}
+ {3573237600 10800 1 EEST}
{3591982800 7200 0 EET}
- {3605896800 10800 1 EEST}
+ {3605292000 10800 1 EEST}
{3623432400 7200 0 EET}
- {3637346400 10800 1 EEST}
+ {3636741600 10800 1 EEST}
{3654882000 7200 0 EET}
- {3668796000 10800 1 EEST}
+ {3668191200 10800 1 EEST}
{3686331600 7200 0 EET}
- {3700245600 10800 1 EEST}
+ {3699640800 10800 1 EEST}
{3718386000 7200 0 EET}
- {3731695200 10800 1 EEST}
+ {3731090400 10800 1 EEST}
{3749835600 7200 0 EET}
- {3763144800 10800 1 EEST}
+ {3762540000 10800 1 EEST}
{3781285200 7200 0 EET}
- {3795199200 10800 1 EEST}
+ {3794594400 10800 1 EEST}
{3812734800 7200 0 EET}
- {3826648800 10800 1 EEST}
+ {3826044000 10800 1 EEST}
{3844184400 7200 0 EET}
- {3858098400 10800 1 EEST}
+ {3857493600 10800 1 EEST}
{3876238800 7200 0 EET}
- {3889548000 10800 1 EEST}
+ {3888943200 10800 1 EEST}
{3907688400 7200 0 EET}
- {3920997600 10800 1 EEST}
+ {3920392800 10800 1 EEST}
{3939138000 7200 0 EET}
- {3952447200 10800 1 EEST}
+ {3951842400 10800 1 EEST}
{3970587600 7200 0 EET}
- {3984501600 10800 1 EEST}
+ {3983896800 10800 1 EEST}
{4002037200 7200 0 EET}
- {4015951200 10800 1 EEST}
+ {4015346400 10800 1 EEST}
{4033486800 7200 0 EET}
- {4047400800 10800 1 EEST}
+ {4046796000 10800 1 EEST}
{4065541200 7200 0 EET}
- {4078850400 10800 1 EEST}
+ {4078245600 10800 1 EEST}
{4096990800 7200 0 EET}
}
diff --git a/library/tzdata/Asia/Dili b/library/tzdata/Asia/Dili
index 36910fd..f783557 100644
--- a/library/tzdata/Asia/Dili
+++ b/library/tzdata/Asia/Dili
@@ -5,6 +5,6 @@ set TZData(:Asia/Dili) {
{-1830414140 28800 0 TLT}
{-879152400 32400 0 JST}
{-766054800 32400 0 TLT}
- {199897200 28800 0 CIT}
+ {199897200 28800 0 WITA}
{969120000 32400 0 TLT}
}
diff --git a/library/tzdata/Asia/Gaza b/library/tzdata/Asia/Gaza
index f26221e..7d62a96 100644
--- a/library/tzdata/Asia/Gaza
+++ b/library/tzdata/Asia/Gaza
@@ -88,189 +88,191 @@ set TZData(:Asia/Gaza) {
{1158872400 7200 0 EET}
{1175378400 10800 1 EEST}
{1189638000 7200 0 EET}
- {1207000800 10800 1 EEST}
- {1219964400 7200 0 EET}
+ {1206655200 10800 1 EEST}
+ {1219960800 7200 0 EET}
+ {1220220000 7200 0 EET}
{1238104800 10800 1 EEST}
- {1252018800 7200 0 EET}
- {1269640860 10800 1 EEST}
+ {1252015200 7200 0 EET}
+ {1262296800 7200 0 EET}
+ {1269640860 10800 0 EEST}
{1281474000 7200 0 EET}
- {1283472000 7200 0 EET}
- {1301090460 10800 1 EEST}
- {1314918000 7200 0 EET}
- {1333144860 10800 1 EEST}
- {1346972400 7200 0 EET}
- {1364594460 10800 1 EEST}
- {1378422000 7200 0 EET}
- {1396044060 10800 1 EEST}
- {1409871600 7200 0 EET}
- {1427493660 10800 1 EEST}
- {1441321200 7200 0 EET}
- {1458943260 10800 1 EEST}
- {1472770800 7200 0 EET}
- {1490392860 10800 1 EEST}
- {1504220400 7200 0 EET}
- {1522447260 10800 1 EEST}
- {1536274800 7200 0 EET}
- {1553896860 10800 1 EEST}
- {1567724400 7200 0 EET}
- {1585346460 10800 1 EEST}
- {1599174000 7200 0 EET}
- {1616796060 10800 1 EEST}
- {1630623600 7200 0 EET}
- {1648245660 10800 1 EEST}
- {1662073200 7200 0 EET}
- {1679695260 10800 1 EEST}
- {1693522800 7200 0 EET}
- {1711749660 10800 1 EEST}
- {1725577200 7200 0 EET}
- {1743199260 10800 1 EEST}
- {1757026800 7200 0 EET}
- {1774648860 10800 1 EEST}
- {1788476400 7200 0 EET}
- {1806098460 10800 1 EEST}
- {1819926000 7200 0 EET}
- {1837548060 10800 1 EEST}
- {1851375600 7200 0 EET}
- {1869602460 10800 1 EEST}
- {1883430000 7200 0 EET}
- {1901052060 10800 1 EEST}
- {1914879600 7200 0 EET}
- {1932501660 10800 1 EEST}
- {1946329200 7200 0 EET}
- {1963951260 10800 1 EEST}
- {1977778800 7200 0 EET}
- {1995400860 10800 1 EEST}
- {2009228400 7200 0 EET}
- {2026850460 10800 1 EEST}
- {2040678000 7200 0 EET}
- {2058904860 10800 1 EEST}
- {2072732400 7200 0 EET}
- {2090354460 10800 1 EEST}
- {2104182000 7200 0 EET}
- {2121804060 10800 1 EEST}
- {2135631600 7200 0 EET}
- {2153253660 10800 1 EEST}
- {2167081200 7200 0 EET}
- {2184703260 10800 1 EEST}
- {2198530800 7200 0 EET}
- {2216757660 10800 1 EEST}
- {2230585200 7200 0 EET}
- {2248207260 10800 1 EEST}
- {2262034800 7200 0 EET}
- {2279656860 10800 1 EEST}
- {2293484400 7200 0 EET}
- {2311106460 10800 1 EEST}
- {2324934000 7200 0 EET}
- {2342556060 10800 1 EEST}
- {2356383600 7200 0 EET}
- {2374005660 10800 1 EEST}
- {2387833200 7200 0 EET}
- {2406060060 10800 1 EEST}
- {2419887600 7200 0 EET}
- {2437509660 10800 1 EEST}
- {2451337200 7200 0 EET}
- {2468959260 10800 1 EEST}
- {2482786800 7200 0 EET}
- {2500408860 10800 1 EEST}
- {2514236400 7200 0 EET}
- {2531858460 10800 1 EEST}
- {2545686000 7200 0 EET}
- {2563308060 10800 1 EEST}
- {2577135600 7200 0 EET}
- {2595362460 10800 1 EEST}
- {2609190000 7200 0 EET}
- {2626812060 10800 1 EEST}
- {2640639600 7200 0 EET}
- {2658261660 10800 1 EEST}
- {2672089200 7200 0 EET}
- {2689711260 10800 1 EEST}
- {2703538800 7200 0 EET}
- {2721160860 10800 1 EEST}
- {2734988400 7200 0 EET}
- {2753215260 10800 1 EEST}
- {2767042800 7200 0 EET}
- {2784664860 10800 1 EEST}
- {2798492400 7200 0 EET}
- {2816114460 10800 1 EEST}
- {2829942000 7200 0 EET}
- {2847564060 10800 1 EEST}
- {2861391600 7200 0 EET}
- {2879013660 10800 1 EEST}
- {2892841200 7200 0 EET}
- {2910463260 10800 1 EEST}
- {2924290800 7200 0 EET}
- {2942517660 10800 1 EEST}
- {2956345200 7200 0 EET}
- {2973967260 10800 1 EEST}
- {2987794800 7200 0 EET}
- {3005416860 10800 1 EEST}
- {3019244400 7200 0 EET}
- {3036866460 10800 1 EEST}
- {3050694000 7200 0 EET}
- {3068316060 10800 1 EEST}
- {3082143600 7200 0 EET}
- {3100370460 10800 1 EEST}
- {3114198000 7200 0 EET}
- {3131820060 10800 1 EEST}
- {3145647600 7200 0 EET}
- {3163269660 10800 1 EEST}
- {3177097200 7200 0 EET}
- {3194719260 10800 1 EEST}
- {3208546800 7200 0 EET}
- {3226168860 10800 1 EEST}
- {3239996400 7200 0 EET}
- {3257618460 10800 1 EEST}
- {3271446000 7200 0 EET}
- {3289672860 10800 1 EEST}
- {3303500400 7200 0 EET}
- {3321122460 10800 1 EEST}
- {3334950000 7200 0 EET}
- {3352572060 10800 1 EEST}
- {3366399600 7200 0 EET}
- {3384021660 10800 1 EEST}
- {3397849200 7200 0 EET}
- {3415471260 10800 1 EEST}
- {3429298800 7200 0 EET}
- {3446920860 10800 1 EEST}
- {3460748400 7200 0 EET}
- {3478975260 10800 1 EEST}
- {3492802800 7200 0 EET}
- {3510424860 10800 1 EEST}
- {3524252400 7200 0 EET}
- {3541874460 10800 1 EEST}
- {3555702000 7200 0 EET}
- {3573324060 10800 1 EEST}
- {3587151600 7200 0 EET}
- {3604773660 10800 1 EEST}
- {3618601200 7200 0 EET}
- {3636828060 10800 1 EEST}
- {3650655600 7200 0 EET}
- {3668277660 10800 1 EEST}
- {3682105200 7200 0 EET}
- {3699727260 10800 1 EEST}
- {3713554800 7200 0 EET}
- {3731176860 10800 1 EEST}
- {3745004400 7200 0 EET}
- {3762626460 10800 1 EEST}
- {3776454000 7200 0 EET}
- {3794076060 10800 1 EEST}
- {3807903600 7200 0 EET}
- {3826130460 10800 1 EEST}
- {3839958000 7200 0 EET}
- {3857580060 10800 1 EEST}
- {3871407600 7200 0 EET}
- {3889029660 10800 1 EEST}
- {3902857200 7200 0 EET}
- {3920479260 10800 1 EEST}
- {3934306800 7200 0 EET}
- {3951928860 10800 1 EEST}
- {3965756400 7200 0 EET}
- {3983983260 10800 1 EEST}
- {3997810800 7200 0 EET}
- {4015432860 10800 1 EEST}
- {4029260400 7200 0 EET}
- {4046882460 10800 1 EEST}
- {4060710000 7200 0 EET}
- {4078332060 10800 1 EEST}
- {4092159600 7200 0 EET}
+ {1301608860 10800 1 EEST}
+ {1312149600 7200 0 EET}
+ {1325368800 7200 0 EET}
+ {1333058400 10800 1 EEST}
+ {1348178400 7200 0 EET}
+ {1364508000 10800 1 EEST}
+ {1380229200 7200 0 EET}
+ {1395957600 10800 1 EEST}
+ {1411678800 7200 0 EET}
+ {1427407200 10800 1 EEST}
+ {1443128400 7200 0 EET}
+ {1459461600 10800 1 EEST}
+ {1474578000 7200 0 EET}
+ {1490911200 10800 1 EEST}
+ {1506027600 7200 0 EET}
+ {1522360800 10800 1 EEST}
+ {1537477200 7200 0 EET}
+ {1553810400 10800 1 EEST}
+ {1569531600 7200 0 EET}
+ {1585260000 10800 1 EEST}
+ {1600981200 7200 0 EET}
+ {1616709600 10800 1 EEST}
+ {1632430800 7200 0 EET}
+ {1648764000 10800 1 EEST}
+ {1663880400 7200 0 EET}
+ {1680213600 10800 1 EEST}
+ {1695330000 7200 0 EET}
+ {1711663200 10800 1 EEST}
+ {1727384400 7200 0 EET}
+ {1743112800 10800 1 EEST}
+ {1758834000 7200 0 EET}
+ {1774562400 10800 1 EEST}
+ {1790283600 7200 0 EET}
+ {1806012000 10800 1 EEST}
+ {1821733200 7200 0 EET}
+ {1838066400 10800 1 EEST}
+ {1853182800 7200 0 EET}
+ {1869516000 10800 1 EEST}
+ {1884632400 7200 0 EET}
+ {1900965600 10800 1 EEST}
+ {1916686800 7200 0 EET}
+ {1932415200 10800 1 EEST}
+ {1948136400 7200 0 EET}
+ {1963864800 10800 1 EEST}
+ {1979586000 7200 0 EET}
+ {1995919200 10800 1 EEST}
+ {2011035600 7200 0 EET}
+ {2027368800 10800 1 EEST}
+ {2042485200 7200 0 EET}
+ {2058818400 10800 1 EEST}
+ {2073934800 7200 0 EET}
+ {2090268000 10800 1 EEST}
+ {2105989200 7200 0 EET}
+ {2121717600 10800 1 EEST}
+ {2137438800 7200 0 EET}
+ {2153167200 10800 1 EEST}
+ {2168888400 7200 0 EET}
+ {2185221600 10800 1 EEST}
+ {2200338000 7200 0 EET}
+ {2216671200 10800 1 EEST}
+ {2231787600 7200 0 EET}
+ {2248120800 10800 1 EEST}
+ {2263842000 7200 0 EET}
+ {2279570400 10800 1 EEST}
+ {2295291600 7200 0 EET}
+ {2311020000 10800 1 EEST}
+ {2326741200 7200 0 EET}
+ {2343074400 10800 1 EEST}
+ {2358190800 7200 0 EET}
+ {2374524000 10800 1 EEST}
+ {2389640400 7200 0 EET}
+ {2405973600 10800 1 EEST}
+ {2421090000 7200 0 EET}
+ {2437423200 10800 1 EEST}
+ {2453144400 7200 0 EET}
+ {2468872800 10800 1 EEST}
+ {2484594000 7200 0 EET}
+ {2500322400 10800 1 EEST}
+ {2516043600 7200 0 EET}
+ {2532376800 10800 1 EEST}
+ {2547493200 7200 0 EET}
+ {2563826400 10800 1 EEST}
+ {2578942800 7200 0 EET}
+ {2595276000 10800 1 EEST}
+ {2610997200 7200 0 EET}
+ {2626725600 10800 1 EEST}
+ {2642446800 7200 0 EET}
+ {2658175200 10800 1 EEST}
+ {2673896400 7200 0 EET}
+ {2689624800 10800 1 EEST}
+ {2705346000 7200 0 EET}
+ {2721679200 10800 1 EEST}
+ {2736795600 7200 0 EET}
+ {2753128800 10800 1 EEST}
+ {2768245200 7200 0 EET}
+ {2784578400 10800 1 EEST}
+ {2800299600 7200 0 EET}
+ {2816028000 10800 1 EEST}
+ {2831749200 7200 0 EET}
+ {2847477600 10800 1 EEST}
+ {2863198800 7200 0 EET}
+ {2879532000 10800 1 EEST}
+ {2894648400 7200 0 EET}
+ {2910981600 10800 1 EEST}
+ {2926098000 7200 0 EET}
+ {2942431200 10800 1 EEST}
+ {2957547600 7200 0 EET}
+ {2973880800 10800 1 EEST}
+ {2989602000 7200 0 EET}
+ {3005330400 10800 1 EEST}
+ {3021051600 7200 0 EET}
+ {3036780000 10800 1 EEST}
+ {3052501200 7200 0 EET}
+ {3068834400 10800 1 EEST}
+ {3083950800 7200 0 EET}
+ {3100284000 10800 1 EEST}
+ {3115400400 7200 0 EET}
+ {3131733600 10800 1 EEST}
+ {3147454800 7200 0 EET}
+ {3163183200 10800 1 EEST}
+ {3178904400 7200 0 EET}
+ {3194632800 10800 1 EEST}
+ {3210354000 7200 0 EET}
+ {3226687200 10800 1 EEST}
+ {3241803600 7200 0 EET}
+ {3258136800 10800 1 EEST}
+ {3273253200 7200 0 EET}
+ {3289586400 10800 1 EEST}
+ {3304702800 7200 0 EET}
+ {3321036000 10800 1 EEST}
+ {3336757200 7200 0 EET}
+ {3352485600 10800 1 EEST}
+ {3368206800 7200 0 EET}
+ {3383935200 10800 1 EEST}
+ {3399656400 7200 0 EET}
+ {3415989600 10800 1 EEST}
+ {3431106000 7200 0 EET}
+ {3447439200 10800 1 EEST}
+ {3462555600 7200 0 EET}
+ {3478888800 10800 1 EEST}
+ {3494610000 7200 0 EET}
+ {3510338400 10800 1 EEST}
+ {3526059600 7200 0 EET}
+ {3541788000 10800 1 EEST}
+ {3557509200 7200 0 EET}
+ {3573237600 10800 1 EEST}
+ {3588958800 7200 0 EET}
+ {3605292000 10800 1 EEST}
+ {3620408400 7200 0 EET}
+ {3636741600 10800 1 EEST}
+ {3651858000 7200 0 EET}
+ {3668191200 10800 1 EEST}
+ {3683912400 7200 0 EET}
+ {3699640800 10800 1 EEST}
+ {3715362000 7200 0 EET}
+ {3731090400 10800 1 EEST}
+ {3746811600 7200 0 EET}
+ {3763144800 10800 1 EEST}
+ {3778261200 7200 0 EET}
+ {3794594400 10800 1 EEST}
+ {3809710800 7200 0 EET}
+ {3826044000 10800 1 EEST}
+ {3841160400 7200 0 EET}
+ {3857493600 10800 1 EEST}
+ {3873214800 7200 0 EET}
+ {3888943200 10800 1 EEST}
+ {3904664400 7200 0 EET}
+ {3920392800 10800 1 EEST}
+ {3936114000 7200 0 EET}
+ {3952447200 10800 1 EEST}
+ {3967563600 7200 0 EET}
+ {3983896800 10800 1 EEST}
+ {3999013200 7200 0 EET}
+ {4015346400 10800 1 EEST}
+ {4031067600 7200 0 EET}
+ {4046796000 10800 1 EEST}
+ {4062517200 7200 0 EET}
+ {4078245600 10800 1 EEST}
+ {4093966800 7200 0 EET}
}
diff --git a/library/tzdata/Asia/Hebron b/library/tzdata/Asia/Hebron
new file mode 100644
index 0000000..1333d5a
--- /dev/null
+++ b/library/tzdata/Asia/Hebron
@@ -0,0 +1,277 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Hebron) {
+ {-9223372036854775808 8423 0 LMT}
+ {-2185410023 7200 0 EET}
+ {-933645600 10800 1 EET}
+ {-857358000 7200 0 EET}
+ {-844300800 10800 1 EET}
+ {-825822000 7200 0 EET}
+ {-812685600 10800 1 EET}
+ {-794199600 7200 0 EET}
+ {-779853600 10800 1 EET}
+ {-762656400 7200 0 EET}
+ {-748310400 10800 1 EET}
+ {-731127600 7200 0 EET}
+ {-682653600 7200 0 EET}
+ {-399088800 10800 1 EEST}
+ {-386650800 7200 0 EET}
+ {-368330400 10800 1 EEST}
+ {-355114800 7200 0 EET}
+ {-336790800 10800 1 EEST}
+ {-323654400 7200 0 EET}
+ {-305168400 10800 1 EEST}
+ {-292032000 7200 0 EET}
+ {-273632400 10800 1 EEST}
+ {-260496000 7200 0 EET}
+ {-242096400 10800 1 EEST}
+ {-228960000 7200 0 EET}
+ {-210560400 10800 1 EEST}
+ {-197424000 7200 0 EET}
+ {-178938000 10800 1 EEST}
+ {-165801600 7200 0 EET}
+ {-147402000 10800 1 EEST}
+ {-134265600 7200 0 EET}
+ {-115866000 10800 1 EEST}
+ {-102643200 7200 0 EET}
+ {-84330000 10800 1 EEST}
+ {-81313200 10800 0 IST}
+ {142376400 10800 1 IDT}
+ {150843600 7200 0 IST}
+ {167176800 10800 1 IDT}
+ {178664400 7200 0 IST}
+ {482277600 10800 1 IDT}
+ {495579600 7200 0 IST}
+ {516751200 10800 1 IDT}
+ {526424400 7200 0 IST}
+ {545436000 10800 1 IDT}
+ {558478800 7200 0 IST}
+ {576540000 10800 1 IDT}
+ {589237200 7200 0 IST}
+ {609890400 10800 1 IDT}
+ {620773200 7200 0 IST}
+ {638316000 10800 1 IDT}
+ {651618000 7200 0 IST}
+ {669765600 10800 1 IDT}
+ {683672400 7200 0 IST}
+ {701820000 10800 1 IDT}
+ {715726800 7200 0 IST}
+ {733701600 10800 1 IDT}
+ {747176400 7200 0 IST}
+ {765151200 10800 1 IDT}
+ {778021200 7200 0 IST}
+ {796600800 10800 1 IDT}
+ {810075600 7200 0 IST}
+ {820447200 7200 0 EET}
+ {828655200 10800 1 EEST}
+ {843170400 7200 0 EET}
+ {860104800 10800 1 EEST}
+ {874620000 7200 0 EET}
+ {891554400 10800 1 EEST}
+ {906069600 7200 0 EET}
+ {915141600 7200 0 EET}
+ {924213600 10800 1 EEST}
+ {939934800 7200 0 EET}
+ {956268000 10800 1 EEST}
+ {971989200 7200 0 EET}
+ {987717600 10800 1 EEST}
+ {1003438800 7200 0 EET}
+ {1019167200 10800 1 EEST}
+ {1034888400 7200 0 EET}
+ {1050616800 10800 1 EEST}
+ {1066338000 7200 0 EET}
+ {1082066400 10800 1 EEST}
+ {1096581600 7200 0 EET}
+ {1113516000 10800 1 EEST}
+ {1128380400 7200 0 EET}
+ {1143842400 10800 1 EEST}
+ {1158872400 7200 0 EET}
+ {1175378400 10800 1 EEST}
+ {1189638000 7200 0 EET}
+ {1206655200 10800 1 EEST}
+ {1220216400 7200 0 EET}
+ {1238104800 10800 1 EEST}
+ {1252015200 7200 0 EET}
+ {1269554400 10800 1 EEST}
+ {1281474000 7200 0 EET}
+ {1301608860 10800 1 EEST}
+ {1312146000 7200 0 EET}
+ {1314655200 10800 1 EEST}
+ {1317330000 7200 0 EET}
+ {1333058400 10800 1 EEST}
+ {1348178400 7200 0 EET}
+ {1364508000 10800 1 EEST}
+ {1380229200 7200 0 EET}
+ {1395957600 10800 1 EEST}
+ {1411678800 7200 0 EET}
+ {1427407200 10800 1 EEST}
+ {1443128400 7200 0 EET}
+ {1459461600 10800 1 EEST}
+ {1474578000 7200 0 EET}
+ {1490911200 10800 1 EEST}
+ {1506027600 7200 0 EET}
+ {1522360800 10800 1 EEST}
+ {1537477200 7200 0 EET}
+ {1553810400 10800 1 EEST}
+ {1569531600 7200 0 EET}
+ {1585260000 10800 1 EEST}
+ {1600981200 7200 0 EET}
+ {1616709600 10800 1 EEST}
+ {1632430800 7200 0 EET}
+ {1648764000 10800 1 EEST}
+ {1663880400 7200 0 EET}
+ {1680213600 10800 1 EEST}
+ {1695330000 7200 0 EET}
+ {1711663200 10800 1 EEST}
+ {1727384400 7200 0 EET}
+ {1743112800 10800 1 EEST}
+ {1758834000 7200 0 EET}
+ {1774562400 10800 1 EEST}
+ {1790283600 7200 0 EET}
+ {1806012000 10800 1 EEST}
+ {1821733200 7200 0 EET}
+ {1838066400 10800 1 EEST}
+ {1853182800 7200 0 EET}
+ {1869516000 10800 1 EEST}
+ {1884632400 7200 0 EET}
+ {1900965600 10800 1 EEST}
+ {1916686800 7200 0 EET}
+ {1932415200 10800 1 EEST}
+ {1948136400 7200 0 EET}
+ {1963864800 10800 1 EEST}
+ {1979586000 7200 0 EET}
+ {1995919200 10800 1 EEST}
+ {2011035600 7200 0 EET}
+ {2027368800 10800 1 EEST}
+ {2042485200 7200 0 EET}
+ {2058818400 10800 1 EEST}
+ {2073934800 7200 0 EET}
+ {2090268000 10800 1 EEST}
+ {2105989200 7200 0 EET}
+ {2121717600 10800 1 EEST}
+ {2137438800 7200 0 EET}
+ {2153167200 10800 1 EEST}
+ {2168888400 7200 0 EET}
+ {2185221600 10800 1 EEST}
+ {2200338000 7200 0 EET}
+ {2216671200 10800 1 EEST}
+ {2231787600 7200 0 EET}
+ {2248120800 10800 1 EEST}
+ {2263842000 7200 0 EET}
+ {2279570400 10800 1 EEST}
+ {2295291600 7200 0 EET}
+ {2311020000 10800 1 EEST}
+ {2326741200 7200 0 EET}
+ {2343074400 10800 1 EEST}
+ {2358190800 7200 0 EET}
+ {2374524000 10800 1 EEST}
+ {2389640400 7200 0 EET}
+ {2405973600 10800 1 EEST}
+ {2421090000 7200 0 EET}
+ {2437423200 10800 1 EEST}
+ {2453144400 7200 0 EET}
+ {2468872800 10800 1 EEST}
+ {2484594000 7200 0 EET}
+ {2500322400 10800 1 EEST}
+ {2516043600 7200 0 EET}
+ {2532376800 10800 1 EEST}
+ {2547493200 7200 0 EET}
+ {2563826400 10800 1 EEST}
+ {2578942800 7200 0 EET}
+ {2595276000 10800 1 EEST}
+ {2610997200 7200 0 EET}
+ {2626725600 10800 1 EEST}
+ {2642446800 7200 0 EET}
+ {2658175200 10800 1 EEST}
+ {2673896400 7200 0 EET}
+ {2689624800 10800 1 EEST}
+ {2705346000 7200 0 EET}
+ {2721679200 10800 1 EEST}
+ {2736795600 7200 0 EET}
+ {2753128800 10800 1 EEST}
+ {2768245200 7200 0 EET}
+ {2784578400 10800 1 EEST}
+ {2800299600 7200 0 EET}
+ {2816028000 10800 1 EEST}
+ {2831749200 7200 0 EET}
+ {2847477600 10800 1 EEST}
+ {2863198800 7200 0 EET}
+ {2879532000 10800 1 EEST}
+ {2894648400 7200 0 EET}
+ {2910981600 10800 1 EEST}
+ {2926098000 7200 0 EET}
+ {2942431200 10800 1 EEST}
+ {2957547600 7200 0 EET}
+ {2973880800 10800 1 EEST}
+ {2989602000 7200 0 EET}
+ {3005330400 10800 1 EEST}
+ {3021051600 7200 0 EET}
+ {3036780000 10800 1 EEST}
+ {3052501200 7200 0 EET}
+ {3068834400 10800 1 EEST}
+ {3083950800 7200 0 EET}
+ {3100284000 10800 1 EEST}
+ {3115400400 7200 0 EET}
+ {3131733600 10800 1 EEST}
+ {3147454800 7200 0 EET}
+ {3163183200 10800 1 EEST}
+ {3178904400 7200 0 EET}
+ {3194632800 10800 1 EEST}
+ {3210354000 7200 0 EET}
+ {3226687200 10800 1 EEST}
+ {3241803600 7200 0 EET}
+ {3258136800 10800 1 EEST}
+ {3273253200 7200 0 EET}
+ {3289586400 10800 1 EEST}
+ {3304702800 7200 0 EET}
+ {3321036000 10800 1 EEST}
+ {3336757200 7200 0 EET}
+ {3352485600 10800 1 EEST}
+ {3368206800 7200 0 EET}
+ {3383935200 10800 1 EEST}
+ {3399656400 7200 0 EET}
+ {3415989600 10800 1 EEST}
+ {3431106000 7200 0 EET}
+ {3447439200 10800 1 EEST}
+ {3462555600 7200 0 EET}
+ {3478888800 10800 1 EEST}
+ {3494610000 7200 0 EET}
+ {3510338400 10800 1 EEST}
+ {3526059600 7200 0 EET}
+ {3541788000 10800 1 EEST}
+ {3557509200 7200 0 EET}
+ {3573237600 10800 1 EEST}
+ {3588958800 7200 0 EET}
+ {3605292000 10800 1 EEST}
+ {3620408400 7200 0 EET}
+ {3636741600 10800 1 EEST}
+ {3651858000 7200 0 EET}
+ {3668191200 10800 1 EEST}
+ {3683912400 7200 0 EET}
+ {3699640800 10800 1 EEST}
+ {3715362000 7200 0 EET}
+ {3731090400 10800 1 EEST}
+ {3746811600 7200 0 EET}
+ {3763144800 10800 1 EEST}
+ {3778261200 7200 0 EET}
+ {3794594400 10800 1 EEST}
+ {3809710800 7200 0 EET}
+ {3826044000 10800 1 EEST}
+ {3841160400 7200 0 EET}
+ {3857493600 10800 1 EEST}
+ {3873214800 7200 0 EET}
+ {3888943200 10800 1 EEST}
+ {3904664400 7200 0 EET}
+ {3920392800 10800 1 EEST}
+ {3936114000 7200 0 EET}
+ {3952447200 10800 1 EEST}
+ {3967563600 7200 0 EET}
+ {3983896800 10800 1 EEST}
+ {3999013200 7200 0 EET}
+ {4015346400 10800 1 EEST}
+ {4031067600 7200 0 EET}
+ {4046796000 10800 1 EEST}
+ {4062517200 7200 0 EET}
+ {4078245600 10800 1 EEST}
+ {4093966800 7200 0 EET}
+}
diff --git a/library/tzdata/Asia/Hong_Kong b/library/tzdata/Asia/Hong_Kong
index 928cde6..fcf98a6 100644
--- a/library/tzdata/Asia/Hong_Kong
+++ b/library/tzdata/Asia/Hong_Kong
@@ -1,8 +1,8 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Asia/Hong_Kong) {
- {-9223372036854775808 27396 0 LMT}
- {-2056692996 28800 0 HKT}
+ {-9223372036854775808 27402 0 LMT}
+ {-2056693002 28800 0 HKT}
{-907389000 32400 1 HKST}
{-891667800 28800 0 HKT}
{-884246400 32400 0 JST}
diff --git a/library/tzdata/Asia/Jakarta b/library/tzdata/Asia/Jakarta
index 27033e8..75cd659 100644
--- a/library/tzdata/Asia/Jakarta
+++ b/library/tzdata/Asia/Jakarta
@@ -2,12 +2,12 @@
set TZData(:Asia/Jakarta) {
{-9223372036854775808 25632 0 LMT}
- {-3231299232 25632 0 JMT}
+ {-3231299232 25632 0 BMT}
{-1451719200 26400 0 JAVT}
- {-1172906400 27000 0 WIT}
+ {-1172906400 27000 0 WIB}
{-876641400 32400 0 JST}
- {-766054800 27000 0 WIT}
- {-683883000 28800 0 WIT}
- {-620812800 27000 0 WIT}
- {-189415800 25200 0 WIT}
+ {-766054800 27000 0 WIB}
+ {-683883000 28800 0 WIB}
+ {-620812800 27000 0 WIB}
+ {-189415800 25200 0 WIB}
}
diff --git a/library/tzdata/Asia/Jayapura b/library/tzdata/Asia/Jayapura
index 893da8b..a71228f 100644
--- a/library/tzdata/Asia/Jayapura
+++ b/library/tzdata/Asia/Jayapura
@@ -2,7 +2,7 @@
set TZData(:Asia/Jayapura) {
{-9223372036854775808 33768 0 LMT}
- {-1172913768 32400 0 EIT}
+ {-1172913768 32400 0 WIT}
{-799491600 34200 0 CST}
- {-189423000 32400 0 EIT}
+ {-189423000 32400 0 WIT}
}
diff --git a/library/tzdata/Asia/Jerusalem b/library/tzdata/Asia/Jerusalem
index 48e213d..7662680 100644
--- a/library/tzdata/Asia/Jerusalem
+++ b/library/tzdata/Asia/Jerusalem
@@ -1,8 +1,8 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Asia/Jerusalem) {
- {-9223372036854775808 8456 0 LMT}
- {-2840149256 8440 0 JMT}
+ {-9223372036854775808 8454 0 LMT}
+ {-2840149254 8440 0 JMT}
{-1641003640 7200 0 IST}
{-933645600 10800 1 IDT}
{-857358000 7200 0 IST}
@@ -96,53 +96,177 @@ set TZData(:Asia/Jerusalem) {
{1333065600 10800 1 IDT}
{1348354800 7200 0 IST}
{1364515200 10800 1 IDT}
- {1378594800 7200 0 IST}
+ {1382828400 7200 0 IST}
{1395964800 10800 1 IDT}
- {1411858800 7200 0 IST}
+ {1414278000 7200 0 IST}
{1427414400 10800 1 IDT}
- {1442703600 7200 0 IST}
- {1459468800 10800 1 IDT}
- {1475967600 7200 0 IST}
- {1490918400 10800 1 IDT}
- {1506207600 7200 0 IST}
- {1522368000 10800 1 IDT}
- {1537052400 7200 0 IST}
+ {1445727600 7200 0 IST}
+ {1458864000 10800 1 IDT}
+ {1477782000 7200 0 IST}
+ {1490313600 10800 1 IDT}
+ {1509231600 7200 0 IST}
+ {1521763200 10800 1 IDT}
+ {1540681200 7200 0 IST}
{1553817600 10800 1 IDT}
- {1570316400 7200 0 IST}
+ {1572130800 7200 0 IST}
{1585267200 10800 1 IDT}
- {1601161200 7200 0 IST}
+ {1603580400 7200 0 IST}
{1616716800 10800 1 IDT}
- {1631401200 7200 0 IST}
- {1648771200 10800 1 IDT}
- {1664665200 7200 0 IST}
- {1680220800 10800 1 IDT}
- {1695510000 7200 0 IST}
+ {1635634800 7200 0 IST}
+ {1648166400 10800 1 IDT}
+ {1667084400 7200 0 IST}
+ {1679616000 10800 1 IDT}
+ {1698534000 7200 0 IST}
{1711670400 10800 1 IDT}
- {1728169200 7200 0 IST}
+ {1729983600 7200 0 IST}
{1743120000 10800 1 IDT}
- {1759014000 7200 0 IST}
+ {1761433200 7200 0 IST}
{1774569600 10800 1 IDT}
- {1789858800 7200 0 IST}
+ {1792882800 7200 0 IST}
{1806019200 10800 1 IDT}
- {1823122800 7200 0 IST}
- {1838073600 10800 1 IDT}
- {1853362800 7200 0 IST}
- {1869523200 10800 1 IDT}
- {1884207600 7200 0 IST}
+ {1824937200 7200 0 IST}
+ {1837468800 10800 1 IDT}
+ {1856386800 7200 0 IST}
+ {1868918400 10800 1 IDT}
+ {1887836400 7200 0 IST}
{1900972800 10800 1 IDT}
- {1917471600 7200 0 IST}
+ {1919286000 7200 0 IST}
{1932422400 10800 1 IDT}
- {1947711600 7200 0 IST}
+ {1950735600 7200 0 IST}
{1963872000 10800 1 IDT}
- {1978556400 7200 0 IST}
- {1995926400 10800 1 IDT}
- {2011820400 7200 0 IST}
- {2027376000 10800 1 IDT}
- {2042060400 7200 0 IST}
- {2058825600 10800 1 IDT}
- {2075324400 7200 0 IST}
+ {1982790000 7200 0 IST}
+ {1995321600 10800 1 IDT}
+ {2014239600 7200 0 IST}
+ {2026771200 10800 1 IDT}
+ {2045689200 7200 0 IST}
+ {2058220800 10800 1 IDT}
+ {2077138800 7200 0 IST}
{2090275200 10800 1 IDT}
- {2106169200 7200 0 IST}
+ {2108588400 7200 0 IST}
{2121724800 10800 1 IDT}
- {2136409200 7200 0 IST}
+ {2140038000 7200 0 IST}
+ {2153174400 10800 1 IDT}
+ {2172092400 7200 0 IST}
+ {2184624000 10800 1 IDT}
+ {2203542000 7200 0 IST}
+ {2216073600 10800 1 IDT}
+ {2234991600 7200 0 IST}
+ {2248128000 10800 1 IDT}
+ {2266441200 7200 0 IST}
+ {2279577600 10800 1 IDT}
+ {2297890800 7200 0 IST}
+ {2311027200 10800 1 IDT}
+ {2329340400 7200 0 IST}
+ {2342476800 10800 1 IDT}
+ {2361394800 7200 0 IST}
+ {2373926400 10800 1 IDT}
+ {2392844400 7200 0 IST}
+ {2405376000 10800 1 IDT}
+ {2424294000 7200 0 IST}
+ {2437430400 10800 1 IDT}
+ {2455743600 7200 0 IST}
+ {2468880000 10800 1 IDT}
+ {2487193200 7200 0 IST}
+ {2500329600 10800 1 IDT}
+ {2519247600 7200 0 IST}
+ {2531779200 10800 1 IDT}
+ {2550697200 7200 0 IST}
+ {2563228800 10800 1 IDT}
+ {2582146800 7200 0 IST}
+ {2595283200 10800 1 IDT}
+ {2613596400 7200 0 IST}
+ {2626732800 10800 1 IDT}
+ {2645046000 7200 0 IST}
+ {2658182400 10800 1 IDT}
+ {2676495600 7200 0 IST}
+ {2689632000 10800 1 IDT}
+ {2708550000 7200 0 IST}
+ {2721081600 10800 1 IDT}
+ {2739999600 7200 0 IST}
+ {2752531200 10800 1 IDT}
+ {2771449200 7200 0 IST}
+ {2784585600 10800 1 IDT}
+ {2802898800 7200 0 IST}
+ {2816035200 10800 1 IDT}
+ {2834348400 7200 0 IST}
+ {2847484800 10800 1 IDT}
+ {2866402800 7200 0 IST}
+ {2878934400 10800 1 IDT}
+ {2897852400 7200 0 IST}
+ {2910384000 10800 1 IDT}
+ {2929302000 7200 0 IST}
+ {2941833600 10800 1 IDT}
+ {2960751600 7200 0 IST}
+ {2973888000 10800 1 IDT}
+ {2992201200 7200 0 IST}
+ {3005337600 10800 1 IDT}
+ {3023650800 7200 0 IST}
+ {3036787200 10800 1 IDT}
+ {3055705200 7200 0 IST}
+ {3068236800 10800 1 IDT}
+ {3087154800 7200 0 IST}
+ {3099686400 10800 1 IDT}
+ {3118604400 7200 0 IST}
+ {3131740800 10800 1 IDT}
+ {3150054000 7200 0 IST}
+ {3163190400 10800 1 IDT}
+ {3181503600 7200 0 IST}
+ {3194640000 10800 1 IDT}
+ {3212953200 7200 0 IST}
+ {3226089600 10800 1 IDT}
+ {3245007600 7200 0 IST}
+ {3257539200 10800 1 IDT}
+ {3276457200 7200 0 IST}
+ {3288988800 10800 1 IDT}
+ {3307906800 7200 0 IST}
+ {3321043200 10800 1 IDT}
+ {3339356400 7200 0 IST}
+ {3352492800 10800 1 IDT}
+ {3370806000 7200 0 IST}
+ {3383942400 10800 1 IDT}
+ {3402860400 7200 0 IST}
+ {3415392000 10800 1 IDT}
+ {3434310000 7200 0 IST}
+ {3446841600 10800 1 IDT}
+ {3465759600 7200 0 IST}
+ {3478896000 10800 1 IDT}
+ {3497209200 7200 0 IST}
+ {3510345600 10800 1 IDT}
+ {3528658800 7200 0 IST}
+ {3541795200 10800 1 IDT}
+ {3560108400 7200 0 IST}
+ {3573244800 10800 1 IDT}
+ {3592162800 7200 0 IST}
+ {3604694400 10800 1 IDT}
+ {3623612400 7200 0 IST}
+ {3636144000 10800 1 IDT}
+ {3655062000 7200 0 IST}
+ {3668198400 10800 1 IDT}
+ {3686511600 7200 0 IST}
+ {3699648000 10800 1 IDT}
+ {3717961200 7200 0 IST}
+ {3731097600 10800 1 IDT}
+ {3750015600 7200 0 IST}
+ {3762547200 10800 1 IDT}
+ {3781465200 7200 0 IST}
+ {3793996800 10800 1 IDT}
+ {3812914800 7200 0 IST}
+ {3825446400 10800 1 IDT}
+ {3844364400 7200 0 IST}
+ {3857500800 10800 1 IDT}
+ {3875814000 7200 0 IST}
+ {3888950400 10800 1 IDT}
+ {3907263600 7200 0 IST}
+ {3920400000 10800 1 IDT}
+ {3939318000 7200 0 IST}
+ {3951849600 10800 1 IDT}
+ {3970767600 7200 0 IST}
+ {3983299200 10800 1 IDT}
+ {4002217200 7200 0 IST}
+ {4015353600 10800 1 IDT}
+ {4033666800 7200 0 IST}
+ {4046803200 10800 1 IDT}
+ {4065116400 7200 0 IST}
+ {4078252800 10800 1 IDT}
+ {4096566000 7200 0 IST}
}
diff --git a/library/tzdata/Asia/Khandyga b/library/tzdata/Asia/Khandyga
new file mode 100644
index 0000000..2464b9f
--- /dev/null
+++ b/library/tzdata/Asia/Khandyga
@@ -0,0 +1,72 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Khandyga) {
+ {-9223372036854775808 32533 0 LMT}
+ {-1579424533 28800 0 YAKT}
+ {-1247558400 32400 0 YAKMMTT}
+ {354898800 36000 1 YAKST}
+ {370706400 32400 0 YAKT}
+ {386434800 36000 1 YAKST}
+ {402242400 32400 0 YAKT}
+ {417970800 36000 1 YAKST}
+ {433778400 32400 0 YAKT}
+ {449593200 36000 1 YAKST}
+ {465325200 32400 0 YAKT}
+ {481050000 36000 1 YAKST}
+ {496774800 32400 0 YAKT}
+ {512499600 36000 1 YAKST}
+ {528224400 32400 0 YAKT}
+ {543949200 36000 1 YAKST}
+ {559674000 32400 0 YAKT}
+ {575398800 36000 1 YAKST}
+ {591123600 32400 0 YAKT}
+ {606848400 36000 1 YAKST}
+ {622573200 32400 0 YAKT}
+ {638298000 36000 1 YAKST}
+ {654627600 32400 0 YAKT}
+ {670352400 28800 0 YAKMMTT}
+ {670356000 32400 1 YAKST}
+ {686080800 28800 0 YAKT}
+ {695757600 32400 0 YAKMMTT}
+ {701791200 36000 1 YAKST}
+ {717512400 32400 0 YAKT}
+ {733251600 36000 1 YAKST}
+ {748976400 32400 0 YAKT}
+ {764701200 36000 1 YAKST}
+ {780426000 32400 0 YAKT}
+ {796150800 36000 1 YAKST}
+ {811875600 32400 0 YAKT}
+ {828205200 36000 1 YAKST}
+ {846349200 32400 0 YAKT}
+ {859654800 36000 1 YAKST}
+ {877798800 32400 0 YAKT}
+ {891104400 36000 1 YAKST}
+ {909248400 32400 0 YAKT}
+ {922554000 36000 1 YAKST}
+ {941302800 32400 0 YAKT}
+ {954003600 36000 1 YAKST}
+ {972752400 32400 0 YAKT}
+ {985453200 36000 1 YAKST}
+ {1004202000 32400 0 YAKT}
+ {1017507600 36000 1 YAKST}
+ {1035651600 32400 0 YAKT}
+ {1048957200 36000 1 YAKST}
+ {1067101200 32400 0 YAKT}
+ {1072882800 36000 0 VLAMMTT}
+ {1080403200 39600 1 VLAST}
+ {1099152000 36000 0 VLAT}
+ {1111852800 39600 1 VLAST}
+ {1130601600 36000 0 VLAT}
+ {1143302400 39600 1 VLAST}
+ {1162051200 36000 0 VLAT}
+ {1174752000 39600 1 VLAST}
+ {1193500800 36000 0 VLAT}
+ {1206806400 39600 1 VLAST}
+ {1224950400 36000 0 VLAT}
+ {1238256000 39600 1 VLAST}
+ {1256400000 36000 0 VLAT}
+ {1269705600 39600 1 VLAST}
+ {1288454400 36000 0 VLAT}
+ {1301155200 39600 0 VLAT}
+ {1315832400 36000 0 YAKT}
+}
diff --git a/library/tzdata/Asia/Makassar b/library/tzdata/Asia/Makassar
index aa604b4..be947f3 100644
--- a/library/tzdata/Asia/Makassar
+++ b/library/tzdata/Asia/Makassar
@@ -3,7 +3,7 @@
set TZData(:Asia/Makassar) {
{-9223372036854775808 28656 0 LMT}
{-1577951856 28656 0 MMT}
- {-1172908656 28800 0 CIT}
+ {-1172908656 28800 0 WITA}
{-880272000 32400 0 JST}
- {-766054800 28800 0 CIT}
+ {-766054800 28800 0 WITA}
}
diff --git a/library/tzdata/Asia/Muscat b/library/tzdata/Asia/Muscat
index 21b5873..a69b880 100644
--- a/library/tzdata/Asia/Muscat
+++ b/library/tzdata/Asia/Muscat
@@ -1,6 +1,6 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Asia/Muscat) {
- {-9223372036854775808 14060 0 LMT}
- {-1577937260 14400 0 GST}
+ {-9223372036854775808 14064 0 LMT}
+ {-1577937264 14400 0 GST}
}
diff --git a/library/tzdata/Asia/Pontianak b/library/tzdata/Asia/Pontianak
index f3567dd..728b552 100644
--- a/library/tzdata/Asia/Pontianak
+++ b/library/tzdata/Asia/Pontianak
@@ -3,11 +3,11 @@
set TZData(:Asia/Pontianak) {
{-9223372036854775808 26240 0 LMT}
{-1946186240 26240 0 PMT}
- {-1172906240 27000 0 WIT}
+ {-1172906240 27000 0 WIB}
{-881220600 32400 0 JST}
- {-766054800 27000 0 WIT}
- {-683883000 28800 0 WIT}
- {-620812800 27000 0 WIT}
- {-189415800 28800 0 CIT}
- {567964800 25200 0 WIT}
+ {-766054800 27000 0 WIB}
+ {-683883000 28800 0 WIB}
+ {-620812800 27000 0 WIB}
+ {-189415800 28800 0 WITA}
+ {567964800 25200 0 WIB}
}
diff --git a/library/tzdata/Asia/Rangoon b/library/tzdata/Asia/Rangoon
index 2b8c4fa..4f3ac02 100644
--- a/library/tzdata/Asia/Rangoon
+++ b/library/tzdata/Asia/Rangoon
@@ -2,8 +2,8 @@
set TZData(:Asia/Rangoon) {
{-9223372036854775808 23080 0 LMT}
- {-2840163880 23076 0 RMT}
- {-1577946276 23400 0 BURT}
+ {-2840163880 23080 0 RMT}
+ {-1577946280 23400 0 BURT}
{-873268200 32400 0 JST}
{-778410000 23400 0 MMT}
}
diff --git a/library/tzdata/Asia/Shanghai b/library/tzdata/Asia/Shanghai
index aa7dc58..4b3cc3b 100644
--- a/library/tzdata/Asia/Shanghai
+++ b/library/tzdata/Asia/Shanghai
@@ -1,8 +1,8 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Asia/Shanghai) {
- {-9223372036854775808 29152 0 LMT}
- {-1325491552 28800 0 CST}
+ {-9223372036854775808 29157 0 LMT}
+ {-1325491557 28800 0 CST}
{-933494400 32400 1 CDT}
{-923130000 28800 0 CST}
{-908784000 32400 1 CDT}
diff --git a/library/tzdata/Asia/Ust-Nera b/library/tzdata/Asia/Ust-Nera
new file mode 100644
index 0000000..c8de7a5
--- /dev/null
+++ b/library/tzdata/Asia/Ust-Nera
@@ -0,0 +1,70 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Ust-Nera) {
+ {-9223372036854775808 34374 0 LMT}
+ {-1579426374 28800 0 YAKT}
+ {354898800 43200 0 MAGST}
+ {370699200 39600 0 MAGT}
+ {386427600 43200 1 MAGST}
+ {402235200 39600 0 MAGT}
+ {417963600 43200 1 MAGST}
+ {433771200 39600 0 MAGT}
+ {449586000 43200 1 MAGST}
+ {465318000 39600 0 MAGT}
+ {481042800 43200 1 MAGST}
+ {496767600 39600 0 MAGT}
+ {512492400 43200 1 MAGST}
+ {528217200 39600 0 MAGT}
+ {543942000 43200 1 MAGST}
+ {559666800 39600 0 MAGT}
+ {575391600 43200 1 MAGST}
+ {591116400 39600 0 MAGT}
+ {606841200 43200 1 MAGST}
+ {622566000 39600 0 MAGT}
+ {638290800 43200 1 MAGST}
+ {654620400 39600 0 MAGT}
+ {670345200 36000 0 MAGMMTT}
+ {670348800 39600 1 MAGST}
+ {686073600 36000 0 MAGT}
+ {695750400 39600 0 MAGMMTT}
+ {701784000 43200 1 MAGST}
+ {717505200 39600 0 MAGT}
+ {733244400 43200 1 MAGST}
+ {748969200 39600 0 MAGT}
+ {764694000 43200 1 MAGST}
+ {780418800 39600 0 MAGT}
+ {796143600 43200 1 MAGST}
+ {811868400 39600 0 MAGT}
+ {828198000 43200 1 MAGST}
+ {846342000 39600 0 MAGT}
+ {859647600 43200 1 MAGST}
+ {877791600 39600 0 MAGT}
+ {891097200 43200 1 MAGST}
+ {909241200 39600 0 MAGT}
+ {922546800 43200 1 MAGST}
+ {941295600 39600 0 MAGT}
+ {953996400 43200 1 MAGST}
+ {972745200 39600 0 MAGT}
+ {985446000 43200 1 MAGST}
+ {1004194800 39600 0 MAGT}
+ {1017500400 43200 1 MAGST}
+ {1035644400 39600 0 MAGT}
+ {1048950000 43200 1 MAGST}
+ {1067094000 39600 0 MAGT}
+ {1080399600 43200 1 MAGST}
+ {1099148400 39600 0 MAGT}
+ {1111849200 43200 1 MAGST}
+ {1130598000 39600 0 MAGT}
+ {1143298800 43200 1 MAGST}
+ {1162047600 39600 0 MAGT}
+ {1174748400 43200 1 MAGST}
+ {1193497200 39600 0 MAGT}
+ {1206802800 43200 1 MAGST}
+ {1224946800 39600 0 MAGT}
+ {1238252400 43200 1 MAGST}
+ {1256396400 39600 0 MAGT}
+ {1269702000 43200 1 MAGST}
+ {1288450800 39600 0 MAGT}
+ {1301151600 43200 0 MAGT}
+ {1315828800 39600 0 VLAT}
+}
diff --git a/library/tzdata/Asia/Yerevan b/library/tzdata/Asia/Yerevan
index cd70b4f..22008ef 100644
--- a/library/tzdata/Asia/Yerevan
+++ b/library/tzdata/Asia/Yerevan
@@ -66,180 +66,5 @@ set TZData(:Asia/Yerevan) {
{1288476000 14400 0 AMT}
{1301176800 18000 1 AMST}
{1319925600 14400 0 AMT}
- {1332626400 18000 1 AMST}
- {1351375200 14400 0 AMT}
- {1364680800 18000 1 AMST}
- {1382824800 14400 0 AMT}
- {1396130400 18000 1 AMST}
- {1414274400 14400 0 AMT}
- {1427580000 18000 1 AMST}
- {1445724000 14400 0 AMT}
- {1459029600 18000 1 AMST}
- {1477778400 14400 0 AMT}
- {1490479200 18000 1 AMST}
- {1509228000 14400 0 AMT}
- {1521928800 18000 1 AMST}
- {1540677600 14400 0 AMT}
- {1553983200 18000 1 AMST}
- {1572127200 14400 0 AMT}
- {1585432800 18000 1 AMST}
- {1603576800 14400 0 AMT}
- {1616882400 18000 1 AMST}
- {1635631200 14400 0 AMT}
- {1648332000 18000 1 AMST}
- {1667080800 14400 0 AMT}
- {1679781600 18000 1 AMST}
- {1698530400 14400 0 AMT}
- {1711836000 18000 1 AMST}
- {1729980000 14400 0 AMT}
- {1743285600 18000 1 AMST}
- {1761429600 14400 0 AMT}
- {1774735200 18000 1 AMST}
- {1792879200 14400 0 AMT}
- {1806184800 18000 1 AMST}
- {1824933600 14400 0 AMT}
- {1837634400 18000 1 AMST}
- {1856383200 14400 0 AMT}
- {1869084000 18000 1 AMST}
- {1887832800 14400 0 AMT}
- {1901138400 18000 1 AMST}
- {1919282400 14400 0 AMT}
- {1932588000 18000 1 AMST}
- {1950732000 14400 0 AMT}
- {1964037600 18000 1 AMST}
- {1982786400 14400 0 AMT}
- {1995487200 18000 1 AMST}
- {2014236000 14400 0 AMT}
- {2026936800 18000 1 AMST}
- {2045685600 14400 0 AMT}
- {2058386400 18000 1 AMST}
- {2077135200 14400 0 AMT}
- {2090440800 18000 1 AMST}
- {2108584800 14400 0 AMT}
- {2121890400 18000 1 AMST}
- {2140034400 14400 0 AMT}
- {2153340000 18000 1 AMST}
- {2172088800 14400 0 AMT}
- {2184789600 18000 1 AMST}
- {2203538400 14400 0 AMT}
- {2216239200 18000 1 AMST}
- {2234988000 14400 0 AMT}
- {2248293600 18000 1 AMST}
- {2266437600 14400 0 AMT}
- {2279743200 18000 1 AMST}
- {2297887200 14400 0 AMT}
- {2311192800 18000 1 AMST}
- {2329336800 14400 0 AMT}
- {2342642400 18000 1 AMST}
- {2361391200 14400 0 AMT}
- {2374092000 18000 1 AMST}
- {2392840800 14400 0 AMT}
- {2405541600 18000 1 AMST}
- {2424290400 14400 0 AMT}
- {2437596000 18000 1 AMST}
- {2455740000 14400 0 AMT}
- {2469045600 18000 1 AMST}
- {2487189600 14400 0 AMT}
- {2500495200 18000 1 AMST}
- {2519244000 14400 0 AMT}
- {2531944800 18000 1 AMST}
- {2550693600 14400 0 AMT}
- {2563394400 18000 1 AMST}
- {2582143200 14400 0 AMT}
- {2595448800 18000 1 AMST}
- {2613592800 14400 0 AMT}
- {2626898400 18000 1 AMST}
- {2645042400 14400 0 AMT}
- {2658348000 18000 1 AMST}
- {2676492000 14400 0 AMT}
- {2689797600 18000 1 AMST}
- {2708546400 14400 0 AMT}
- {2721247200 18000 1 AMST}
- {2739996000 14400 0 AMT}
- {2752696800 18000 1 AMST}
- {2771445600 14400 0 AMT}
- {2784751200 18000 1 AMST}
- {2802895200 14400 0 AMT}
- {2816200800 18000 1 AMST}
- {2834344800 14400 0 AMT}
- {2847650400 18000 1 AMST}
- {2866399200 14400 0 AMT}
- {2879100000 18000 1 AMST}
- {2897848800 14400 0 AMT}
- {2910549600 18000 1 AMST}
- {2929298400 14400 0 AMT}
- {2941999200 18000 1 AMST}
- {2960748000 14400 0 AMT}
- {2974053600 18000 1 AMST}
- {2992197600 14400 0 AMT}
- {3005503200 18000 1 AMST}
- {3023647200 14400 0 AMT}
- {3036952800 18000 1 AMST}
- {3055701600 14400 0 AMT}
- {3068402400 18000 1 AMST}
- {3087151200 14400 0 AMT}
- {3099852000 18000 1 AMST}
- {3118600800 14400 0 AMT}
- {3131906400 18000 1 AMST}
- {3150050400 14400 0 AMT}
- {3163356000 18000 1 AMST}
- {3181500000 14400 0 AMT}
- {3194805600 18000 1 AMST}
- {3212949600 14400 0 AMT}
- {3226255200 18000 1 AMST}
- {3245004000 14400 0 AMT}
- {3257704800 18000 1 AMST}
- {3276453600 14400 0 AMT}
- {3289154400 18000 1 AMST}
- {3307903200 14400 0 AMT}
- {3321208800 18000 1 AMST}
- {3339352800 14400 0 AMT}
- {3352658400 18000 1 AMST}
- {3370802400 14400 0 AMT}
- {3384108000 18000 1 AMST}
- {3402856800 14400 0 AMT}
- {3415557600 18000 1 AMST}
- {3434306400 14400 0 AMT}
- {3447007200 18000 1 AMST}
- {3465756000 14400 0 AMT}
- {3479061600 18000 1 AMST}
- {3497205600 14400 0 AMT}
- {3510511200 18000 1 AMST}
- {3528655200 14400 0 AMT}
- {3541960800 18000 1 AMST}
- {3560104800 14400 0 AMT}
- {3573410400 18000 1 AMST}
- {3592159200 14400 0 AMT}
- {3604860000 18000 1 AMST}
- {3623608800 14400 0 AMT}
- {3636309600 18000 1 AMST}
- {3655058400 14400 0 AMT}
- {3668364000 18000 1 AMST}
- {3686508000 14400 0 AMT}
- {3699813600 18000 1 AMST}
- {3717957600 14400 0 AMT}
- {3731263200 18000 1 AMST}
- {3750012000 14400 0 AMT}
- {3762712800 18000 1 AMST}
- {3781461600 14400 0 AMT}
- {3794162400 18000 1 AMST}
- {3812911200 14400 0 AMT}
- {3825612000 18000 1 AMST}
- {3844360800 14400 0 AMT}
- {3857666400 18000 1 AMST}
- {3875810400 14400 0 AMT}
- {3889116000 18000 1 AMST}
- {3907260000 14400 0 AMT}
- {3920565600 18000 1 AMST}
- {3939314400 14400 0 AMT}
- {3952015200 18000 1 AMST}
- {3970764000 14400 0 AMT}
- {3983464800 18000 1 AMST}
- {4002213600 14400 0 AMT}
- {4015519200 18000 1 AMST}
- {4033663200 14400 0 AMT}
- {4046968800 18000 1 AMST}
- {4065112800 14400 0 AMT}
- {4078418400 18000 1 AMST}
- {4096562400 14400 0 AMT}
+ {1332626400 14400 0 AMT}
}
diff --git a/library/tzdata/Atlantic/Bermuda b/library/tzdata/Atlantic/Bermuda
index e8b165a..2d4d983 100644
--- a/library/tzdata/Atlantic/Bermuda
+++ b/library/tzdata/Atlantic/Bermuda
@@ -1,8 +1,8 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Atlantic/Bermuda) {
- {-9223372036854775808 -15544 0 LMT}
- {-1262281256 -14400 0 AST}
+ {-9223372036854775808 -15558 0 LMT}
+ {-1262281242 -14400 0 AST}
{136360800 -10800 0 ADT}
{152082000 -14400 0 AST}
{167810400 -10800 1 ADT}
diff --git a/library/tzdata/Atlantic/Faroe b/library/tzdata/Atlantic/Faroe
index d2c314a..d2c314a 100755..100644
--- a/library/tzdata/Atlantic/Faroe
+++ b/library/tzdata/Atlantic/Faroe
diff --git a/library/tzdata/Atlantic/Stanley b/library/tzdata/Atlantic/Stanley
index 545b91c..c287238 100644
--- a/library/tzdata/Atlantic/Stanley
+++ b/library/tzdata/Atlantic/Stanley
@@ -71,182 +71,5 @@ set TZData(:Atlantic/Stanley) {
{1240117200 -14400 0 FKT}
{1252216800 -10800 1 FKST}
{1271566800 -14400 0 FKT}
- {1283666400 -10800 1 FKST}
- {1315112400 -10800 1 FKST}
- {1334466000 -14400 0 FKT}
- {1346565600 -10800 1 FKST}
- {1366520400 -14400 0 FKT}
- {1378015200 -10800 1 FKST}
- {1397970000 -14400 0 FKT}
- {1410069600 -10800 1 FKST}
- {1429419600 -14400 0 FKT}
- {1441519200 -10800 1 FKST}
- {1460869200 -14400 0 FKT}
- {1472968800 -10800 1 FKST}
- {1492318800 -14400 0 FKT}
- {1504418400 -10800 1 FKST}
- {1523768400 -14400 0 FKT}
- {1535868000 -10800 1 FKST}
- {1555822800 -14400 0 FKT}
- {1567317600 -10800 1 FKST}
- {1587272400 -14400 0 FKT}
- {1599372000 -10800 1 FKST}
- {1618722000 -14400 0 FKT}
- {1630821600 -10800 1 FKST}
- {1650171600 -14400 0 FKT}
- {1662271200 -10800 1 FKST}
- {1681621200 -14400 0 FKT}
- {1693720800 -10800 1 FKST}
- {1713675600 -14400 0 FKT}
- {1725170400 -10800 1 FKST}
- {1745125200 -14400 0 FKT}
- {1757224800 -10800 1 FKST}
- {1776574800 -14400 0 FKT}
- {1788674400 -10800 1 FKST}
- {1808024400 -14400 0 FKT}
- {1820124000 -10800 1 FKST}
- {1839474000 -14400 0 FKT}
- {1851573600 -10800 1 FKST}
- {1870923600 -14400 0 FKT}
- {1883023200 -10800 1 FKST}
- {1902978000 -14400 0 FKT}
- {1914472800 -10800 1 FKST}
- {1934427600 -14400 0 FKT}
- {1946527200 -10800 1 FKST}
- {1965877200 -14400 0 FKT}
- {1977976800 -10800 1 FKST}
- {1997326800 -14400 0 FKT}
- {2009426400 -10800 1 FKST}
- {2028776400 -14400 0 FKT}
- {2040876000 -10800 1 FKST}
- {2060226000 -14400 0 FKT}
- {2072325600 -10800 1 FKST}
- {2092280400 -14400 0 FKT}
- {2104380000 -10800 1 FKST}
- {2123730000 -14400 0 FKT}
- {2135829600 -10800 1 FKST}
- {2155179600 -14400 0 FKT}
- {2167279200 -10800 1 FKST}
- {2186629200 -14400 0 FKT}
- {2198728800 -10800 1 FKST}
- {2218078800 -14400 0 FKT}
- {2230178400 -10800 1 FKST}
- {2250133200 -14400 0 FKT}
- {2261628000 -10800 1 FKST}
- {2281582800 -14400 0 FKT}
- {2293682400 -10800 1 FKST}
- {2313032400 -14400 0 FKT}
- {2325132000 -10800 1 FKST}
- {2344482000 -14400 0 FKT}
- {2356581600 -10800 1 FKST}
- {2375931600 -14400 0 FKT}
- {2388031200 -10800 1 FKST}
- {2407381200 -14400 0 FKT}
- {2419480800 -10800 1 FKST}
- {2439435600 -14400 0 FKT}
- {2450930400 -10800 1 FKST}
- {2470885200 -14400 0 FKT}
- {2482984800 -10800 1 FKST}
- {2502334800 -14400 0 FKT}
- {2514434400 -10800 1 FKST}
- {2533784400 -14400 0 FKT}
- {2545884000 -10800 1 FKST}
- {2565234000 -14400 0 FKT}
- {2577333600 -10800 1 FKST}
- {2597288400 -14400 0 FKT}
- {2608783200 -10800 1 FKST}
- {2628738000 -14400 0 FKT}
- {2640837600 -10800 1 FKST}
- {2660187600 -14400 0 FKT}
- {2672287200 -10800 1 FKST}
- {2691637200 -14400 0 FKT}
- {2703736800 -10800 1 FKST}
- {2723086800 -14400 0 FKT}
- {2735186400 -10800 1 FKST}
- {2754536400 -14400 0 FKT}
- {2766636000 -10800 1 FKST}
- {2786590800 -14400 0 FKT}
- {2798085600 -10800 1 FKST}
- {2818040400 -14400 0 FKT}
- {2830140000 -10800 1 FKST}
- {2849490000 -14400 0 FKT}
- {2861589600 -10800 1 FKST}
- {2880939600 -14400 0 FKT}
- {2893039200 -10800 1 FKST}
- {2912389200 -14400 0 FKT}
- {2924488800 -10800 1 FKST}
- {2943838800 -14400 0 FKT}
- {2955938400 -10800 1 FKST}
- {2975893200 -14400 0 FKT}
- {2987992800 -10800 1 FKST}
- {3007342800 -14400 0 FKT}
- {3019442400 -10800 1 FKST}
- {3038792400 -14400 0 FKT}
- {3050892000 -10800 1 FKST}
- {3070242000 -14400 0 FKT}
- {3082341600 -10800 1 FKST}
- {3101691600 -14400 0 FKT}
- {3113791200 -10800 1 FKST}
- {3133746000 -14400 0 FKT}
- {3145240800 -10800 1 FKST}
- {3165195600 -14400 0 FKT}
- {3177295200 -10800 1 FKST}
- {3196645200 -14400 0 FKT}
- {3208744800 -10800 1 FKST}
- {3228094800 -14400 0 FKT}
- {3240194400 -10800 1 FKST}
- {3259544400 -14400 0 FKT}
- {3271644000 -10800 1 FKST}
- {3290994000 -14400 0 FKT}
- {3303093600 -10800 1 FKST}
- {3323048400 -14400 0 FKT}
- {3334543200 -10800 1 FKST}
- {3354498000 -14400 0 FKT}
- {3366597600 -10800 1 FKST}
- {3385947600 -14400 0 FKT}
- {3398047200 -10800 1 FKST}
- {3417397200 -14400 0 FKT}
- {3429496800 -10800 1 FKST}
- {3448846800 -14400 0 FKT}
- {3460946400 -10800 1 FKST}
- {3480901200 -14400 0 FKT}
- {3492396000 -10800 1 FKST}
- {3512350800 -14400 0 FKT}
- {3524450400 -10800 1 FKST}
- {3543800400 -14400 0 FKT}
- {3555900000 -10800 1 FKST}
- {3575250000 -14400 0 FKT}
- {3587349600 -10800 1 FKST}
- {3606699600 -14400 0 FKT}
- {3618799200 -10800 1 FKST}
- {3638149200 -14400 0 FKT}
- {3650248800 -10800 1 FKST}
- {3670203600 -14400 0 FKT}
- {3681698400 -10800 1 FKST}
- {3701653200 -14400 0 FKT}
- {3713752800 -10800 1 FKST}
- {3733102800 -14400 0 FKT}
- {3745202400 -10800 1 FKST}
- {3764552400 -14400 0 FKT}
- {3776652000 -10800 1 FKST}
- {3796002000 -14400 0 FKT}
- {3808101600 -10800 1 FKST}
- {3827451600 -14400 0 FKT}
- {3839551200 -10800 1 FKST}
- {3859506000 -14400 0 FKT}
- {3871605600 -10800 1 FKST}
- {3890955600 -14400 0 FKT}
- {3903055200 -10800 1 FKST}
- {3922405200 -14400 0 FKT}
- {3934504800 -10800 1 FKST}
- {3953854800 -14400 0 FKT}
- {3965954400 -10800 1 FKST}
- {3985304400 -14400 0 FKT}
- {3997404000 -10800 1 FKST}
- {4017358800 -14400 0 FKT}
- {4028853600 -10800 1 FKST}
- {4048808400 -14400 0 FKT}
- {4060908000 -10800 1 FKST}
- {4080258000 -14400 0 FKT}
- {4092357600 -10800 1 FKST}
+ {1283662800 -10800 0 FKST}
}
diff --git a/library/tzdata/Australia/Eucla b/library/tzdata/Australia/Eucla
index 0f8ed4d..0f8ed4d 100755..100644
--- a/library/tzdata/Australia/Eucla
+++ b/library/tzdata/Australia/Eucla
diff --git a/library/tzdata/Europe/Busingen b/library/tzdata/Europe/Busingen
new file mode 100644
index 0000000..62abc29
--- /dev/null
+++ b/library/tzdata/Europe/Busingen
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Zurich)]} {
+ LoadTimeZoneFile Europe/Zurich
+}
+set TZData(:Europe/Busingen) $TZData(:Europe/Zurich)
diff --git a/library/tzdata/Europe/Guernsey b/library/tzdata/Europe/Guernsey
index 4372c64..4372c64 100755..100644
--- a/library/tzdata/Europe/Guernsey
+++ b/library/tzdata/Europe/Guernsey
diff --git a/library/tzdata/Europe/Isle_of_Man b/library/tzdata/Europe/Isle_of_Man
index 870ac45..870ac45 100755..100644
--- a/library/tzdata/Europe/Isle_of_Man
+++ b/library/tzdata/Europe/Isle_of_Man
diff --git a/library/tzdata/Europe/Jersey b/library/tzdata/Europe/Jersey
index e4da512..e4da512 100755..100644
--- a/library/tzdata/Europe/Jersey
+++ b/library/tzdata/Europe/Jersey
diff --git a/library/tzdata/Europe/Kaliningrad b/library/tzdata/Europe/Kaliningrad
index 02b45d4..d5be459 100644
--- a/library/tzdata/Europe/Kaliningrad
+++ b/library/tzdata/Europe/Kaliningrad
@@ -80,5 +80,5 @@ set TZData(:Europe/Kaliningrad) {
{1256428800 7200 0 EET}
{1269734400 10800 1 EEST}
{1288483200 7200 0 EET}
- {1301184000 10800 0 EET}
+ {1301184000 10800 0 FET}
}
diff --git a/library/tzdata/Europe/Minsk b/library/tzdata/Europe/Minsk
index d7d9434..1adcff8 100644
--- a/library/tzdata/Europe/Minsk
+++ b/library/tzdata/Europe/Minsk
@@ -70,182 +70,5 @@ set TZData(:Europe/Minsk) {
{1256428800 7200 0 EET}
{1269734400 10800 1 EEST}
{1288483200 7200 0 EET}
- {1301184000 10800 1 EEST}
- {1319932800 7200 0 EET}
- {1332633600 10800 1 EEST}
- {1351382400 7200 0 EET}
- {1364688000 10800 1 EEST}
- {1382832000 7200 0 EET}
- {1396137600 10800 1 EEST}
- {1414281600 7200 0 EET}
- {1427587200 10800 1 EEST}
- {1445731200 7200 0 EET}
- {1459036800 10800 1 EEST}
- {1477785600 7200 0 EET}
- {1490486400 10800 1 EEST}
- {1509235200 7200 0 EET}
- {1521936000 10800 1 EEST}
- {1540684800 7200 0 EET}
- {1553990400 10800 1 EEST}
- {1572134400 7200 0 EET}
- {1585440000 10800 1 EEST}
- {1603584000 7200 0 EET}
- {1616889600 10800 1 EEST}
- {1635638400 7200 0 EET}
- {1648339200 10800 1 EEST}
- {1667088000 7200 0 EET}
- {1679788800 10800 1 EEST}
- {1698537600 7200 0 EET}
- {1711843200 10800 1 EEST}
- {1729987200 7200 0 EET}
- {1743292800 10800 1 EEST}
- {1761436800 7200 0 EET}
- {1774742400 10800 1 EEST}
- {1792886400 7200 0 EET}
- {1806192000 10800 1 EEST}
- {1824940800 7200 0 EET}
- {1837641600 10800 1 EEST}
- {1856390400 7200 0 EET}
- {1869091200 10800 1 EEST}
- {1887840000 7200 0 EET}
- {1901145600 10800 1 EEST}
- {1919289600 7200 0 EET}
- {1932595200 10800 1 EEST}
- {1950739200 7200 0 EET}
- {1964044800 10800 1 EEST}
- {1982793600 7200 0 EET}
- {1995494400 10800 1 EEST}
- {2014243200 7200 0 EET}
- {2026944000 10800 1 EEST}
- {2045692800 7200 0 EET}
- {2058393600 10800 1 EEST}
- {2077142400 7200 0 EET}
- {2090448000 10800 1 EEST}
- {2108592000 7200 0 EET}
- {2121897600 10800 1 EEST}
- {2140041600 7200 0 EET}
- {2153347200 10800 1 EEST}
- {2172096000 7200 0 EET}
- {2184796800 10800 1 EEST}
- {2203545600 7200 0 EET}
- {2216246400 10800 1 EEST}
- {2234995200 7200 0 EET}
- {2248300800 10800 1 EEST}
- {2266444800 7200 0 EET}
- {2279750400 10800 1 EEST}
- {2297894400 7200 0 EET}
- {2311200000 10800 1 EEST}
- {2329344000 7200 0 EET}
- {2342649600 10800 1 EEST}
- {2361398400 7200 0 EET}
- {2374099200 10800 1 EEST}
- {2392848000 7200 0 EET}
- {2405548800 10800 1 EEST}
- {2424297600 7200 0 EET}
- {2437603200 10800 1 EEST}
- {2455747200 7200 0 EET}
- {2469052800 10800 1 EEST}
- {2487196800 7200 0 EET}
- {2500502400 10800 1 EEST}
- {2519251200 7200 0 EET}
- {2531952000 10800 1 EEST}
- {2550700800 7200 0 EET}
- {2563401600 10800 1 EEST}
- {2582150400 7200 0 EET}
- {2595456000 10800 1 EEST}
- {2613600000 7200 0 EET}
- {2626905600 10800 1 EEST}
- {2645049600 7200 0 EET}
- {2658355200 10800 1 EEST}
- {2676499200 7200 0 EET}
- {2689804800 10800 1 EEST}
- {2708553600 7200 0 EET}
- {2721254400 10800 1 EEST}
- {2740003200 7200 0 EET}
- {2752704000 10800 1 EEST}
- {2771452800 7200 0 EET}
- {2784758400 10800 1 EEST}
- {2802902400 7200 0 EET}
- {2816208000 10800 1 EEST}
- {2834352000 7200 0 EET}
- {2847657600 10800 1 EEST}
- {2866406400 7200 0 EET}
- {2879107200 10800 1 EEST}
- {2897856000 7200 0 EET}
- {2910556800 10800 1 EEST}
- {2929305600 7200 0 EET}
- {2942006400 10800 1 EEST}
- {2960755200 7200 0 EET}
- {2974060800 10800 1 EEST}
- {2992204800 7200 0 EET}
- {3005510400 10800 1 EEST}
- {3023654400 7200 0 EET}
- {3036960000 10800 1 EEST}
- {3055708800 7200 0 EET}
- {3068409600 10800 1 EEST}
- {3087158400 7200 0 EET}
- {3099859200 10800 1 EEST}
- {3118608000 7200 0 EET}
- {3131913600 10800 1 EEST}
- {3150057600 7200 0 EET}
- {3163363200 10800 1 EEST}
- {3181507200 7200 0 EET}
- {3194812800 10800 1 EEST}
- {3212956800 7200 0 EET}
- {3226262400 10800 1 EEST}
- {3245011200 7200 0 EET}
- {3257712000 10800 1 EEST}
- {3276460800 7200 0 EET}
- {3289161600 10800 1 EEST}
- {3307910400 7200 0 EET}
- {3321216000 10800 1 EEST}
- {3339360000 7200 0 EET}
- {3352665600 10800 1 EEST}
- {3370809600 7200 0 EET}
- {3384115200 10800 1 EEST}
- {3402864000 7200 0 EET}
- {3415564800 10800 1 EEST}
- {3434313600 7200 0 EET}
- {3447014400 10800 1 EEST}
- {3465763200 7200 0 EET}
- {3479068800 10800 1 EEST}
- {3497212800 7200 0 EET}
- {3510518400 10800 1 EEST}
- {3528662400 7200 0 EET}
- {3541968000 10800 1 EEST}
- {3560112000 7200 0 EET}
- {3573417600 10800 1 EEST}
- {3592166400 7200 0 EET}
- {3604867200 10800 1 EEST}
- {3623616000 7200 0 EET}
- {3636316800 10800 1 EEST}
- {3655065600 7200 0 EET}
- {3668371200 10800 1 EEST}
- {3686515200 7200 0 EET}
- {3699820800 10800 1 EEST}
- {3717964800 7200 0 EET}
- {3731270400 10800 1 EEST}
- {3750019200 7200 0 EET}
- {3762720000 10800 1 EEST}
- {3781468800 7200 0 EET}
- {3794169600 10800 1 EEST}
- {3812918400 7200 0 EET}
- {3825619200 10800 1 EEST}
- {3844368000 7200 0 EET}
- {3857673600 10800 1 EEST}
- {3875817600 7200 0 EET}
- {3889123200 10800 1 EEST}
- {3907267200 7200 0 EET}
- {3920572800 10800 1 EEST}
- {3939321600 7200 0 EET}
- {3952022400 10800 1 EEST}
- {3970771200 7200 0 EET}
- {3983472000 10800 1 EEST}
- {4002220800 7200 0 EET}
- {4015526400 10800 1 EEST}
- {4033670400 7200 0 EET}
- {4046976000 10800 1 EEST}
- {4065120000 7200 0 EET}
- {4078425600 10800 1 EEST}
- {4096569600 7200 0 EET}
+ {1301184000 10800 0 FET}
}
diff --git a/library/tzdata/Europe/Podgorica b/library/tzdata/Europe/Podgorica
index f4f9066..f4f9066 100755..100644
--- a/library/tzdata/Europe/Podgorica
+++ b/library/tzdata/Europe/Podgorica
diff --git a/library/tzdata/Europe/Vaduz b/library/tzdata/Europe/Vaduz
index 3118331..095e018 100644
--- a/library/tzdata/Europe/Vaduz
+++ b/library/tzdata/Europe/Vaduz
@@ -1,245 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-
-set TZData(:Europe/Vaduz) {
- {-9223372036854775808 2284 0 LMT}
- {-2385247084 3600 0 CET}
- {347151600 3600 0 CET}
- {354675600 7200 1 CEST}
- {370400400 3600 0 CET}
- {386125200 7200 1 CEST}
- {401850000 3600 0 CET}
- {417574800 7200 1 CEST}
- {433299600 3600 0 CET}
- {449024400 7200 1 CEST}
- {465354000 3600 0 CET}
- {481078800 7200 1 CEST}
- {496803600 3600 0 CET}
- {512528400 7200 1 CEST}
- {528253200 3600 0 CET}
- {543978000 7200 1 CEST}
- {559702800 3600 0 CET}
- {575427600 7200 1 CEST}
- {591152400 3600 0 CET}
- {606877200 7200 1 CEST}
- {622602000 3600 0 CET}
- {638326800 7200 1 CEST}
- {654656400 3600 0 CET}
- {670381200 7200 1 CEST}
- {686106000 3600 0 CET}
- {701830800 7200 1 CEST}
- {717555600 3600 0 CET}
- {733280400 7200 1 CEST}
- {749005200 3600 0 CET}
- {764730000 7200 1 CEST}
- {780454800 3600 0 CET}
- {796179600 7200 1 CEST}
- {811904400 3600 0 CET}
- {828234000 7200 1 CEST}
- {846378000 3600 0 CET}
- {859683600 7200 1 CEST}
- {877827600 3600 0 CET}
- {891133200 7200 1 CEST}
- {909277200 3600 0 CET}
- {922582800 7200 1 CEST}
- {941331600 3600 0 CET}
- {954032400 7200 1 CEST}
- {972781200 3600 0 CET}
- {985482000 7200 1 CEST}
- {1004230800 3600 0 CET}
- {1017536400 7200 1 CEST}
- {1035680400 3600 0 CET}
- {1048986000 7200 1 CEST}
- {1067130000 3600 0 CET}
- {1080435600 7200 1 CEST}
- {1099184400 3600 0 CET}
- {1111885200 7200 1 CEST}
- {1130634000 3600 0 CET}
- {1143334800 7200 1 CEST}
- {1162083600 3600 0 CET}
- {1174784400 7200 1 CEST}
- {1193533200 3600 0 CET}
- {1206838800 7200 1 CEST}
- {1224982800 3600 0 CET}
- {1238288400 7200 1 CEST}
- {1256432400 3600 0 CET}
- {1269738000 7200 1 CEST}
- {1288486800 3600 0 CET}
- {1301187600 7200 1 CEST}
- {1319936400 3600 0 CET}
- {1332637200 7200 1 CEST}
- {1351386000 3600 0 CET}
- {1364691600 7200 1 CEST}
- {1382835600 3600 0 CET}
- {1396141200 7200 1 CEST}
- {1414285200 3600 0 CET}
- {1427590800 7200 1 CEST}
- {1445734800 3600 0 CET}
- {1459040400 7200 1 CEST}
- {1477789200 3600 0 CET}
- {1490490000 7200 1 CEST}
- {1509238800 3600 0 CET}
- {1521939600 7200 1 CEST}
- {1540688400 3600 0 CET}
- {1553994000 7200 1 CEST}
- {1572138000 3600 0 CET}
- {1585443600 7200 1 CEST}
- {1603587600 3600 0 CET}
- {1616893200 7200 1 CEST}
- {1635642000 3600 0 CET}
- {1648342800 7200 1 CEST}
- {1667091600 3600 0 CET}
- {1679792400 7200 1 CEST}
- {1698541200 3600 0 CET}
- {1711846800 7200 1 CEST}
- {1729990800 3600 0 CET}
- {1743296400 7200 1 CEST}
- {1761440400 3600 0 CET}
- {1774746000 7200 1 CEST}
- {1792890000 3600 0 CET}
- {1806195600 7200 1 CEST}
- {1824944400 3600 0 CET}
- {1837645200 7200 1 CEST}
- {1856394000 3600 0 CET}
- {1869094800 7200 1 CEST}
- {1887843600 3600 0 CET}
- {1901149200 7200 1 CEST}
- {1919293200 3600 0 CET}
- {1932598800 7200 1 CEST}
- {1950742800 3600 0 CET}
- {1964048400 7200 1 CEST}
- {1982797200 3600 0 CET}
- {1995498000 7200 1 CEST}
- {2014246800 3600 0 CET}
- {2026947600 7200 1 CEST}
- {2045696400 3600 0 CET}
- {2058397200 7200 1 CEST}
- {2077146000 3600 0 CET}
- {2090451600 7200 1 CEST}
- {2108595600 3600 0 CET}
- {2121901200 7200 1 CEST}
- {2140045200 3600 0 CET}
- {2153350800 7200 1 CEST}
- {2172099600 3600 0 CET}
- {2184800400 7200 1 CEST}
- {2203549200 3600 0 CET}
- {2216250000 7200 1 CEST}
- {2234998800 3600 0 CET}
- {2248304400 7200 1 CEST}
- {2266448400 3600 0 CET}
- {2279754000 7200 1 CEST}
- {2297898000 3600 0 CET}
- {2311203600 7200 1 CEST}
- {2329347600 3600 0 CET}
- {2342653200 7200 1 CEST}
- {2361402000 3600 0 CET}
- {2374102800 7200 1 CEST}
- {2392851600 3600 0 CET}
- {2405552400 7200 1 CEST}
- {2424301200 3600 0 CET}
- {2437606800 7200 1 CEST}
- {2455750800 3600 0 CET}
- {2469056400 7200 1 CEST}
- {2487200400 3600 0 CET}
- {2500506000 7200 1 CEST}
- {2519254800 3600 0 CET}
- {2531955600 7200 1 CEST}
- {2550704400 3600 0 CET}
- {2563405200 7200 1 CEST}
- {2582154000 3600 0 CET}
- {2595459600 7200 1 CEST}
- {2613603600 3600 0 CET}
- {2626909200 7200 1 CEST}
- {2645053200 3600 0 CET}
- {2658358800 7200 1 CEST}
- {2676502800 3600 0 CET}
- {2689808400 7200 1 CEST}
- {2708557200 3600 0 CET}
- {2721258000 7200 1 CEST}
- {2740006800 3600 0 CET}
- {2752707600 7200 1 CEST}
- {2771456400 3600 0 CET}
- {2784762000 7200 1 CEST}
- {2802906000 3600 0 CET}
- {2816211600 7200 1 CEST}
- {2834355600 3600 0 CET}
- {2847661200 7200 1 CEST}
- {2866410000 3600 0 CET}
- {2879110800 7200 1 CEST}
- {2897859600 3600 0 CET}
- {2910560400 7200 1 CEST}
- {2929309200 3600 0 CET}
- {2942010000 7200 1 CEST}
- {2960758800 3600 0 CET}
- {2974064400 7200 1 CEST}
- {2992208400 3600 0 CET}
- {3005514000 7200 1 CEST}
- {3023658000 3600 0 CET}
- {3036963600 7200 1 CEST}
- {3055712400 3600 0 CET}
- {3068413200 7200 1 CEST}
- {3087162000 3600 0 CET}
- {3099862800 7200 1 CEST}
- {3118611600 3600 0 CET}
- {3131917200 7200 1 CEST}
- {3150061200 3600 0 CET}
- {3163366800 7200 1 CEST}
- {3181510800 3600 0 CET}
- {3194816400 7200 1 CEST}
- {3212960400 3600 0 CET}
- {3226266000 7200 1 CEST}
- {3245014800 3600 0 CET}
- {3257715600 7200 1 CEST}
- {3276464400 3600 0 CET}
- {3289165200 7200 1 CEST}
- {3307914000 3600 0 CET}
- {3321219600 7200 1 CEST}
- {3339363600 3600 0 CET}
- {3352669200 7200 1 CEST}
- {3370813200 3600 0 CET}
- {3384118800 7200 1 CEST}
- {3402867600 3600 0 CET}
- {3415568400 7200 1 CEST}
- {3434317200 3600 0 CET}
- {3447018000 7200 1 CEST}
- {3465766800 3600 0 CET}
- {3479072400 7200 1 CEST}
- {3497216400 3600 0 CET}
- {3510522000 7200 1 CEST}
- {3528666000 3600 0 CET}
- {3541971600 7200 1 CEST}
- {3560115600 3600 0 CET}
- {3573421200 7200 1 CEST}
- {3592170000 3600 0 CET}
- {3604870800 7200 1 CEST}
- {3623619600 3600 0 CET}
- {3636320400 7200 1 CEST}
- {3655069200 3600 0 CET}
- {3668374800 7200 1 CEST}
- {3686518800 3600 0 CET}
- {3699824400 7200 1 CEST}
- {3717968400 3600 0 CET}
- {3731274000 7200 1 CEST}
- {3750022800 3600 0 CET}
- {3762723600 7200 1 CEST}
- {3781472400 3600 0 CET}
- {3794173200 7200 1 CEST}
- {3812922000 3600 0 CET}
- {3825622800 7200 1 CEST}
- {3844371600 3600 0 CET}
- {3857677200 7200 1 CEST}
- {3875821200 3600 0 CET}
- {3889126800 7200 1 CEST}
- {3907270800 3600 0 CET}
- {3920576400 7200 1 CEST}
- {3939325200 3600 0 CET}
- {3952026000 7200 1 CEST}
- {3970774800 3600 0 CET}
- {3983475600 7200 1 CEST}
- {4002224400 3600 0 CET}
- {4015530000 7200 1 CEST}
- {4033674000 3600 0 CET}
- {4046979600 7200 1 CEST}
- {4065123600 3600 0 CET}
- {4078429200 7200 1 CEST}
- {4096573200 3600 0 CET}
+if {![info exists TZData(Europe/Zurich)]} {
+ LoadTimeZoneFile Europe/Zurich
}
+set TZData(:Europe/Vaduz) $TZData(:Europe/Zurich)
diff --git a/library/tzdata/Europe/Vienna b/library/tzdata/Europe/Vienna
index 41d744d..95283eb 100644
--- a/library/tzdata/Europe/Vienna
+++ b/library/tzdata/Europe/Vienna
@@ -1,8 +1,8 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Europe/Vienna) {
- {-9223372036854775808 3920 0 LMT}
- {-2422055120 3600 0 CET}
+ {-9223372036854775808 3921 0 LMT}
+ {-2422055121 3600 0 CET}
{-1693706400 7200 1 CEST}
{-1680483600 3600 0 CET}
{-1663455600 7200 1 CEST}
diff --git a/library/tzdata/Europe/Volgograd b/library/tzdata/Europe/Volgograd
index c3f148f..c3f148f 100755..100644
--- a/library/tzdata/Europe/Volgograd
+++ b/library/tzdata/Europe/Volgograd
diff --git a/library/tzdata/Europe/Zurich b/library/tzdata/Europe/Zurich
index 33831c3..87a20db 100644
--- a/library/tzdata/Europe/Zurich
+++ b/library/tzdata/Europe/Zurich
@@ -2,8 +2,8 @@
set TZData(:Europe/Zurich) {
{-9223372036854775808 2048 0 LMT}
- {-3827954048 1784 0 BMT}
- {-2385246584 3600 0 CET}
+ {-3675198848 1786 0 BMT}
+ {-2385246586 3600 0 CET}
{-904435200 7200 1 CEST}
{-891129600 3600 0 CET}
{-872985600 7200 1 CEST}
diff --git a/library/tzdata/Pacific/Apia b/library/tzdata/Pacific/Apia
index 25b047d..e6f33ad 100644
--- a/library/tzdata/Pacific/Apia
+++ b/library/tzdata/Pacific/Apia
@@ -7,4 +7,182 @@ set TZData(:Pacific/Apia) {
{-631110600 -39600 0 WST}
{1285498800 -36000 1 WSDT}
{1301752800 -39600 0 WST}
+ {1316872800 -36000 1 WSDT}
+ {1325239200 50400 1 WSDT}
+ {1333202400 46800 0 WST}
+ {1348927200 50400 1 WSDT}
+ {1365256800 46800 0 WST}
+ {1380376800 50400 1 WSDT}
+ {1396706400 46800 0 WST}
+ {1411826400 50400 1 WSDT}
+ {1428156000 46800 0 WST}
+ {1443276000 50400 1 WSDT}
+ {1459605600 46800 0 WST}
+ {1474725600 50400 1 WSDT}
+ {1491055200 46800 0 WST}
+ {1506175200 50400 1 WSDT}
+ {1522504800 46800 0 WST}
+ {1538229600 50400 1 WSDT}
+ {1554559200 46800 0 WST}
+ {1569679200 50400 1 WSDT}
+ {1586008800 46800 0 WST}
+ {1601128800 50400 1 WSDT}
+ {1617458400 46800 0 WST}
+ {1632578400 50400 1 WSDT}
+ {1648908000 46800 0 WST}
+ {1664028000 50400 1 WSDT}
+ {1680357600 46800 0 WST}
+ {1695477600 50400 1 WSDT}
+ {1712412000 46800 0 WST}
+ {1727532000 50400 1 WSDT}
+ {1743861600 46800 0 WST}
+ {1758981600 50400 1 WSDT}
+ {1775311200 46800 0 WST}
+ {1790431200 50400 1 WSDT}
+ {1806760800 46800 0 WST}
+ {1821880800 50400 1 WSDT}
+ {1838210400 46800 0 WST}
+ {1853330400 50400 1 WSDT}
+ {1869660000 46800 0 WST}
+ {1885384800 50400 1 WSDT}
+ {1901714400 46800 0 WST}
+ {1916834400 50400 1 WSDT}
+ {1933164000 46800 0 WST}
+ {1948284000 50400 1 WSDT}
+ {1964613600 46800 0 WST}
+ {1979733600 50400 1 WSDT}
+ {1996063200 46800 0 WST}
+ {2011183200 50400 1 WSDT}
+ {2027512800 46800 0 WST}
+ {2042632800 50400 1 WSDT}
+ {2058962400 46800 0 WST}
+ {2074687200 50400 1 WSDT}
+ {2091016800 46800 0 WST}
+ {2106136800 50400 1 WSDT}
+ {2122466400 46800 0 WST}
+ {2137586400 50400 1 WSDT}
+ {2153916000 46800 0 WST}
+ {2169036000 50400 1 WSDT}
+ {2185365600 46800 0 WST}
+ {2200485600 50400 1 WSDT}
+ {2216815200 46800 0 WST}
+ {2232540000 50400 1 WSDT}
+ {2248869600 46800 0 WST}
+ {2263989600 50400 1 WSDT}
+ {2280319200 46800 0 WST}
+ {2295439200 50400 1 WSDT}
+ {2311768800 46800 0 WST}
+ {2326888800 50400 1 WSDT}
+ {2343218400 46800 0 WST}
+ {2358338400 50400 1 WSDT}
+ {2374668000 46800 0 WST}
+ {2389788000 50400 1 WSDT}
+ {2406117600 46800 0 WST}
+ {2421842400 50400 1 WSDT}
+ {2438172000 46800 0 WST}
+ {2453292000 50400 1 WSDT}
+ {2469621600 46800 0 WST}
+ {2484741600 50400 1 WSDT}
+ {2501071200 46800 0 WST}
+ {2516191200 50400 1 WSDT}
+ {2532520800 46800 0 WST}
+ {2547640800 50400 1 WSDT}
+ {2563970400 46800 0 WST}
+ {2579090400 50400 1 WSDT}
+ {2596024800 46800 0 WST}
+ {2611144800 50400 1 WSDT}
+ {2627474400 46800 0 WST}
+ {2642594400 50400 1 WSDT}
+ {2658924000 46800 0 WST}
+ {2674044000 50400 1 WSDT}
+ {2690373600 46800 0 WST}
+ {2705493600 50400 1 WSDT}
+ {2721823200 46800 0 WST}
+ {2736943200 50400 1 WSDT}
+ {2753272800 46800 0 WST}
+ {2768997600 50400 1 WSDT}
+ {2785327200 46800 0 WST}
+ {2800447200 50400 1 WSDT}
+ {2816776800 46800 0 WST}
+ {2831896800 50400 1 WSDT}
+ {2848226400 46800 0 WST}
+ {2863346400 50400 1 WSDT}
+ {2879676000 46800 0 WST}
+ {2894796000 50400 1 WSDT}
+ {2911125600 46800 0 WST}
+ {2926245600 50400 1 WSDT}
+ {2942575200 46800 0 WST}
+ {2958300000 50400 1 WSDT}
+ {2974629600 46800 0 WST}
+ {2989749600 50400 1 WSDT}
+ {3006079200 46800 0 WST}
+ {3021199200 50400 1 WSDT}
+ {3037528800 46800 0 WST}
+ {3052648800 50400 1 WSDT}
+ {3068978400 46800 0 WST}
+ {3084098400 50400 1 WSDT}
+ {3100428000 46800 0 WST}
+ {3116152800 50400 1 WSDT}
+ {3132482400 46800 0 WST}
+ {3147602400 50400 1 WSDT}
+ {3163932000 46800 0 WST}
+ {3179052000 50400 1 WSDT}
+ {3195381600 46800 0 WST}
+ {3210501600 50400 1 WSDT}
+ {3226831200 46800 0 WST}
+ {3241951200 50400 1 WSDT}
+ {3258280800 46800 0 WST}
+ {3273400800 50400 1 WSDT}
+ {3289730400 46800 0 WST}
+ {3305455200 50400 1 WSDT}
+ {3321784800 46800 0 WST}
+ {3336904800 50400 1 WSDT}
+ {3353234400 46800 0 WST}
+ {3368354400 50400 1 WSDT}
+ {3384684000 46800 0 WST}
+ {3399804000 50400 1 WSDT}
+ {3416133600 46800 0 WST}
+ {3431253600 50400 1 WSDT}
+ {3447583200 46800 0 WST}
+ {3462703200 50400 1 WSDT}
+ {3479637600 46800 0 WST}
+ {3494757600 50400 1 WSDT}
+ {3511087200 46800 0 WST}
+ {3526207200 50400 1 WSDT}
+ {3542536800 46800 0 WST}
+ {3557656800 50400 1 WSDT}
+ {3573986400 46800 0 WST}
+ {3589106400 50400 1 WSDT}
+ {3605436000 46800 0 WST}
+ {3620556000 50400 1 WSDT}
+ {3636885600 46800 0 WST}
+ {3652610400 50400 1 WSDT}
+ {3668940000 46800 0 WST}
+ {3684060000 50400 1 WSDT}
+ {3700389600 46800 0 WST}
+ {3715509600 50400 1 WSDT}
+ {3731839200 46800 0 WST}
+ {3746959200 50400 1 WSDT}
+ {3763288800 46800 0 WST}
+ {3778408800 50400 1 WSDT}
+ {3794738400 46800 0 WST}
+ {3809858400 50400 1 WSDT}
+ {3826188000 46800 0 WST}
+ {3841912800 50400 1 WSDT}
+ {3858242400 46800 0 WST}
+ {3873362400 50400 1 WSDT}
+ {3889692000 46800 0 WST}
+ {3904812000 50400 1 WSDT}
+ {3921141600 46800 0 WST}
+ {3936261600 50400 1 WSDT}
+ {3952591200 46800 0 WST}
+ {3967711200 50400 1 WSDT}
+ {3984040800 46800 0 WST}
+ {3999765600 50400 1 WSDT}
+ {4016095200 46800 0 WST}
+ {4031215200 50400 1 WSDT}
+ {4047544800 46800 0 WST}
+ {4062664800 50400 1 WSDT}
+ {4078994400 46800 0 WST}
+ {4094114400 50400 1 WSDT}
}
diff --git a/library/tzdata/Pacific/Easter b/library/tzdata/Pacific/Easter
index f8e63a8..000c6d1 100644
--- a/library/tzdata/Pacific/Easter
+++ b/library/tzdata/Pacific/Easter
@@ -96,180 +96,180 @@ set TZData(:Pacific/Easter) {
{1286683200 -18000 1 EASST}
{1304823600 -21600 0 EAST}
{1313899200 -18000 1 EASST}
- {1331434800 -21600 0 EAST}
- {1350187200 -18000 1 EASST}
- {1362884400 -21600 0 EAST}
- {1381636800 -18000 1 EASST}
- {1394334000 -21600 0 EAST}
- {1413086400 -18000 1 EASST}
- {1426388400 -21600 0 EAST}
- {1444536000 -18000 1 EASST}
- {1457838000 -21600 0 EAST}
- {1475985600 -18000 1 EASST}
- {1489287600 -21600 0 EAST}
- {1508040000 -18000 1 EASST}
- {1520737200 -21600 0 EAST}
- {1539489600 -18000 1 EASST}
- {1552186800 -21600 0 EAST}
- {1570939200 -18000 1 EASST}
- {1584241200 -21600 0 EAST}
- {1602388800 -18000 1 EASST}
- {1615690800 -21600 0 EAST}
- {1633838400 -18000 1 EASST}
- {1647140400 -21600 0 EAST}
- {1665288000 -18000 1 EASST}
- {1678590000 -21600 0 EAST}
- {1697342400 -18000 1 EASST}
- {1710039600 -21600 0 EAST}
- {1728792000 -18000 1 EASST}
- {1741489200 -21600 0 EAST}
- {1760241600 -18000 1 EASST}
- {1773543600 -21600 0 EAST}
- {1791691200 -18000 1 EASST}
- {1804993200 -21600 0 EAST}
- {1823140800 -18000 1 EASST}
- {1836442800 -21600 0 EAST}
- {1855195200 -18000 1 EASST}
- {1867892400 -21600 0 EAST}
- {1886644800 -18000 1 EASST}
- {1899342000 -21600 0 EAST}
- {1918094400 -18000 1 EASST}
- {1930791600 -21600 0 EAST}
- {1949544000 -18000 1 EASST}
- {1962846000 -21600 0 EAST}
- {1980993600 -18000 1 EASST}
- {1994295600 -21600 0 EAST}
- {2012443200 -18000 1 EASST}
- {2025745200 -21600 0 EAST}
- {2044497600 -18000 1 EASST}
- {2057194800 -21600 0 EAST}
- {2075947200 -18000 1 EASST}
- {2088644400 -21600 0 EAST}
- {2107396800 -18000 1 EASST}
- {2120698800 -21600 0 EAST}
- {2138846400 -18000 1 EASST}
- {2152148400 -21600 0 EAST}
- {2170296000 -18000 1 EASST}
- {2183598000 -21600 0 EAST}
- {2201745600 -18000 1 EASST}
- {2215047600 -21600 0 EAST}
- {2233800000 -18000 1 EASST}
- {2246497200 -21600 0 EAST}
- {2265249600 -18000 1 EASST}
- {2277946800 -21600 0 EAST}
- {2296699200 -18000 1 EASST}
- {2310001200 -21600 0 EAST}
- {2328148800 -18000 1 EASST}
- {2341450800 -21600 0 EAST}
- {2359598400 -18000 1 EASST}
- {2372900400 -21600 0 EAST}
- {2391652800 -18000 1 EASST}
- {2404350000 -21600 0 EAST}
- {2423102400 -18000 1 EASST}
- {2435799600 -21600 0 EAST}
- {2454552000 -18000 1 EASST}
- {2467854000 -21600 0 EAST}
- {2486001600 -18000 1 EASST}
- {2499303600 -21600 0 EAST}
- {2517451200 -18000 1 EASST}
- {2530753200 -21600 0 EAST}
- {2548900800 -18000 1 EASST}
- {2562202800 -21600 0 EAST}
- {2580955200 -18000 1 EASST}
- {2593652400 -21600 0 EAST}
- {2612404800 -18000 1 EASST}
- {2625102000 -21600 0 EAST}
- {2643854400 -18000 1 EASST}
- {2657156400 -21600 0 EAST}
- {2675304000 -18000 1 EASST}
- {2688606000 -21600 0 EAST}
- {2706753600 -18000 1 EASST}
- {2720055600 -21600 0 EAST}
- {2738808000 -18000 1 EASST}
- {2751505200 -21600 0 EAST}
- {2770257600 -18000 1 EASST}
- {2782954800 -21600 0 EAST}
- {2801707200 -18000 1 EASST}
- {2814404400 -21600 0 EAST}
- {2833156800 -18000 1 EASST}
- {2846458800 -21600 0 EAST}
- {2864606400 -18000 1 EASST}
- {2877908400 -21600 0 EAST}
- {2896056000 -18000 1 EASST}
- {2909358000 -21600 0 EAST}
- {2928110400 -18000 1 EASST}
- {2940807600 -21600 0 EAST}
- {2959560000 -18000 1 EASST}
- {2972257200 -21600 0 EAST}
- {2991009600 -18000 1 EASST}
- {3004311600 -21600 0 EAST}
- {3022459200 -18000 1 EASST}
- {3035761200 -21600 0 EAST}
- {3053908800 -18000 1 EASST}
- {3067210800 -21600 0 EAST}
- {3085358400 -18000 1 EASST}
- {3098660400 -21600 0 EAST}
- {3117412800 -18000 1 EASST}
- {3130110000 -21600 0 EAST}
- {3148862400 -18000 1 EASST}
- {3161559600 -21600 0 EAST}
- {3180312000 -18000 1 EASST}
- {3193614000 -21600 0 EAST}
- {3211761600 -18000 1 EASST}
- {3225063600 -21600 0 EAST}
- {3243211200 -18000 1 EASST}
- {3256513200 -21600 0 EAST}
- {3275265600 -18000 1 EASST}
- {3287962800 -21600 0 EAST}
- {3306715200 -18000 1 EASST}
- {3319412400 -21600 0 EAST}
- {3338164800 -18000 1 EASST}
- {3351466800 -21600 0 EAST}
- {3369614400 -18000 1 EASST}
- {3382916400 -21600 0 EAST}
- {3401064000 -18000 1 EASST}
- {3414366000 -21600 0 EAST}
- {3432513600 -18000 1 EASST}
- {3445815600 -21600 0 EAST}
- {3464568000 -18000 1 EASST}
- {3477265200 -21600 0 EAST}
- {3496017600 -18000 1 EASST}
- {3508714800 -21600 0 EAST}
- {3527467200 -18000 1 EASST}
- {3540769200 -21600 0 EAST}
- {3558916800 -18000 1 EASST}
- {3572218800 -21600 0 EAST}
- {3590366400 -18000 1 EASST}
- {3603668400 -21600 0 EAST}
- {3622420800 -18000 1 EASST}
- {3635118000 -21600 0 EAST}
- {3653870400 -18000 1 EASST}
- {3666567600 -21600 0 EAST}
- {3685320000 -18000 1 EASST}
- {3698017200 -21600 0 EAST}
- {3716769600 -18000 1 EASST}
- {3730071600 -21600 0 EAST}
- {3748219200 -18000 1 EASST}
- {3761521200 -21600 0 EAST}
- {3779668800 -18000 1 EASST}
- {3792970800 -21600 0 EAST}
- {3811723200 -18000 1 EASST}
- {3824420400 -21600 0 EAST}
- {3843172800 -18000 1 EASST}
- {3855870000 -21600 0 EAST}
- {3874622400 -18000 1 EASST}
- {3887924400 -21600 0 EAST}
- {3906072000 -18000 1 EASST}
- {3919374000 -21600 0 EAST}
- {3937521600 -18000 1 EASST}
- {3950823600 -21600 0 EAST}
- {3968971200 -18000 1 EASST}
- {3982273200 -21600 0 EAST}
- {4001025600 -18000 1 EASST}
- {4013722800 -21600 0 EAST}
- {4032475200 -18000 1 EASST}
- {4045172400 -21600 0 EAST}
- {4063924800 -18000 1 EASST}
- {4077226800 -21600 0 EAST}
- {4095374400 -18000 1 EASST}
+ {1335668400 -21600 0 EAST}
+ {1346558400 -18000 1 EASST}
+ {1367118000 -21600 0 EAST}
+ {1378612800 -18000 1 EASST}
+ {1398567600 -21600 0 EAST}
+ {1410062400 -18000 1 EASST}
+ {1430017200 -21600 0 EAST}
+ {1441512000 -18000 1 EASST}
+ {1461466800 -21600 0 EAST}
+ {1472961600 -18000 1 EASST}
+ {1492916400 -21600 0 EAST}
+ {1504411200 -18000 1 EASST}
+ {1524970800 -21600 0 EAST}
+ {1535860800 -18000 1 EASST}
+ {1556420400 -21600 0 EAST}
+ {1567915200 -18000 1 EASST}
+ {1587870000 -21600 0 EAST}
+ {1599364800 -18000 1 EASST}
+ {1619319600 -21600 0 EAST}
+ {1630814400 -18000 1 EASST}
+ {1650769200 -21600 0 EAST}
+ {1662264000 -18000 1 EASST}
+ {1682218800 -21600 0 EAST}
+ {1693713600 -18000 1 EASST}
+ {1714273200 -21600 0 EAST}
+ {1725768000 -18000 1 EASST}
+ {1745722800 -21600 0 EAST}
+ {1757217600 -18000 1 EASST}
+ {1777172400 -21600 0 EAST}
+ {1788667200 -18000 1 EASST}
+ {1808622000 -21600 0 EAST}
+ {1820116800 -18000 1 EASST}
+ {1840071600 -21600 0 EAST}
+ {1851566400 -18000 1 EASST}
+ {1872126000 -21600 0 EAST}
+ {1883016000 -18000 1 EASST}
+ {1903575600 -21600 0 EAST}
+ {1915070400 -18000 1 EASST}
+ {1935025200 -21600 0 EAST}
+ {1946520000 -18000 1 EASST}
+ {1966474800 -21600 0 EAST}
+ {1977969600 -18000 1 EASST}
+ {1997924400 -21600 0 EAST}
+ {2009419200 -18000 1 EASST}
+ {2029374000 -21600 0 EAST}
+ {2040868800 -18000 1 EASST}
+ {2061428400 -21600 0 EAST}
+ {2072318400 -18000 1 EASST}
+ {2092878000 -21600 0 EAST}
+ {2104372800 -18000 1 EASST}
+ {2124327600 -21600 0 EAST}
+ {2135822400 -18000 1 EASST}
+ {2155777200 -21600 0 EAST}
+ {2167272000 -18000 1 EASST}
+ {2187226800 -21600 0 EAST}
+ {2198721600 -18000 1 EASST}
+ {2219281200 -21600 0 EAST}
+ {2230171200 -18000 1 EASST}
+ {2250730800 -21600 0 EAST}
+ {2262225600 -18000 1 EASST}
+ {2282180400 -21600 0 EAST}
+ {2293675200 -18000 1 EASST}
+ {2313630000 -21600 0 EAST}
+ {2325124800 -18000 1 EASST}
+ {2345079600 -21600 0 EAST}
+ {2356574400 -18000 1 EASST}
+ {2376529200 -21600 0 EAST}
+ {2388024000 -18000 1 EASST}
+ {2408583600 -21600 0 EAST}
+ {2419473600 -18000 1 EASST}
+ {2440033200 -21600 0 EAST}
+ {2451528000 -18000 1 EASST}
+ {2471482800 -21600 0 EAST}
+ {2482977600 -18000 1 EASST}
+ {2502932400 -21600 0 EAST}
+ {2514427200 -18000 1 EASST}
+ {2534382000 -21600 0 EAST}
+ {2545876800 -18000 1 EASST}
+ {2565831600 -21600 0 EAST}
+ {2577326400 -18000 1 EASST}
+ {2597886000 -21600 0 EAST}
+ {2609380800 -18000 1 EASST}
+ {2629335600 -21600 0 EAST}
+ {2640830400 -18000 1 EASST}
+ {2660785200 -21600 0 EAST}
+ {2672280000 -18000 1 EASST}
+ {2692234800 -21600 0 EAST}
+ {2703729600 -18000 1 EASST}
+ {2723684400 -21600 0 EAST}
+ {2735179200 -18000 1 EASST}
+ {2755738800 -21600 0 EAST}
+ {2766628800 -18000 1 EASST}
+ {2787188400 -21600 0 EAST}
+ {2798683200 -18000 1 EASST}
+ {2818638000 -21600 0 EAST}
+ {2830132800 -18000 1 EASST}
+ {2850087600 -21600 0 EAST}
+ {2861582400 -18000 1 EASST}
+ {2881537200 -21600 0 EAST}
+ {2893032000 -18000 1 EASST}
+ {2912986800 -21600 0 EAST}
+ {2924481600 -18000 1 EASST}
+ {2945041200 -21600 0 EAST}
+ {2955931200 -18000 1 EASST}
+ {2976490800 -21600 0 EAST}
+ {2987985600 -18000 1 EASST}
+ {3007940400 -21600 0 EAST}
+ {3019435200 -18000 1 EASST}
+ {3039390000 -21600 0 EAST}
+ {3050884800 -18000 1 EASST}
+ {3070839600 -21600 0 EAST}
+ {3082334400 -18000 1 EASST}
+ {3102894000 -21600 0 EAST}
+ {3113784000 -18000 1 EASST}
+ {3134343600 -21600 0 EAST}
+ {3145838400 -18000 1 EASST}
+ {3165793200 -21600 0 EAST}
+ {3177288000 -18000 1 EASST}
+ {3197242800 -21600 0 EAST}
+ {3208737600 -18000 1 EASST}
+ {3228692400 -21600 0 EAST}
+ {3240187200 -18000 1 EASST}
+ {3260142000 -21600 0 EAST}
+ {3271636800 -18000 1 EASST}
+ {3292196400 -21600 0 EAST}
+ {3303086400 -18000 1 EASST}
+ {3323646000 -21600 0 EAST}
+ {3335140800 -18000 1 EASST}
+ {3355095600 -21600 0 EAST}
+ {3366590400 -18000 1 EASST}
+ {3386545200 -21600 0 EAST}
+ {3398040000 -18000 1 EASST}
+ {3417994800 -21600 0 EAST}
+ {3429489600 -18000 1 EASST}
+ {3449444400 -21600 0 EAST}
+ {3460939200 -18000 1 EASST}
+ {3481498800 -21600 0 EAST}
+ {3492993600 -18000 1 EASST}
+ {3512948400 -21600 0 EAST}
+ {3524443200 -18000 1 EASST}
+ {3544398000 -21600 0 EAST}
+ {3555892800 -18000 1 EASST}
+ {3575847600 -21600 0 EAST}
+ {3587342400 -18000 1 EASST}
+ {3607297200 -21600 0 EAST}
+ {3618792000 -18000 1 EASST}
+ {3639351600 -21600 0 EAST}
+ {3650241600 -18000 1 EASST}
+ {3670801200 -21600 0 EAST}
+ {3682296000 -18000 1 EASST}
+ {3702250800 -21600 0 EAST}
+ {3713745600 -18000 1 EASST}
+ {3733700400 -21600 0 EAST}
+ {3745195200 -18000 1 EASST}
+ {3765150000 -21600 0 EAST}
+ {3776644800 -18000 1 EASST}
+ {3796599600 -21600 0 EAST}
+ {3808094400 -18000 1 EASST}
+ {3828654000 -21600 0 EAST}
+ {3839544000 -18000 1 EASST}
+ {3860103600 -21600 0 EAST}
+ {3871598400 -18000 1 EASST}
+ {3891553200 -21600 0 EAST}
+ {3903048000 -18000 1 EASST}
+ {3923002800 -21600 0 EAST}
+ {3934497600 -18000 1 EASST}
+ {3954452400 -21600 0 EAST}
+ {3965947200 -18000 1 EASST}
+ {3986506800 -21600 0 EAST}
+ {3997396800 -18000 1 EASST}
+ {4017956400 -21600 0 EAST}
+ {4029451200 -18000 1 EASST}
+ {4049406000 -21600 0 EAST}
+ {4060900800 -18000 1 EASST}
+ {4080855600 -21600 0 EAST}
+ {4092350400 -18000 1 EASST}
}
diff --git a/library/tzdata/Pacific/Fakaofo b/library/tzdata/Pacific/Fakaofo
index 7420639..6ec98eb 100644
--- a/library/tzdata/Pacific/Fakaofo
+++ b/library/tzdata/Pacific/Fakaofo
@@ -2,5 +2,6 @@
set TZData(:Pacific/Fakaofo) {
{-9223372036854775808 -41096 0 LMT}
- {-2177411704 -36000 0 TKT}
+ {-2177411704 -39600 0 TKT}
+ {1325242800 46800 0 TKT}
}
diff --git a/library/tzdata/Pacific/Fiji b/library/tzdata/Pacific/Fiji
index 3b7aabe..454ee87 100644
--- a/library/tzdata/Pacific/Fiji
+++ b/library/tzdata/Pacific/Fiji
@@ -1,8 +1,8 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Pacific/Fiji) {
- {-9223372036854775808 42820 0 LMT}
- {-1709985220 43200 0 FJT}
+ {-9223372036854775808 42944 0 LMT}
+ {-1709985344 43200 0 FJT}
{909842400 46800 1 FJST}
{920124000 43200 0 FJT}
{941896800 46800 1 FJST}
@@ -11,4 +11,181 @@ set TZData(:Pacific/Fiji) {
{1269698400 43200 0 FJT}
{1287842400 46800 1 FJST}
{1299333600 43200 0 FJT}
+ {1319292000 46800 1 FJST}
+ {1327154400 43200 0 FJT}
+ {1350741600 46800 1 FJST}
+ {1358604000 43200 0 FJT}
+ {1382796000 46800 1 FJST}
+ {1390053600 43200 0 FJT}
+ {1414245600 46800 1 FJST}
+ {1421503200 43200 0 FJT}
+ {1445695200 46800 1 FJST}
+ {1453557600 43200 0 FJT}
+ {1477144800 46800 1 FJST}
+ {1485007200 43200 0 FJT}
+ {1508594400 46800 1 FJST}
+ {1516456800 43200 0 FJT}
+ {1540044000 46800 1 FJST}
+ {1547906400 43200 0 FJT}
+ {1572098400 46800 1 FJST}
+ {1579356000 43200 0 FJT}
+ {1603548000 46800 1 FJST}
+ {1611410400 43200 0 FJT}
+ {1634997600 46800 1 FJST}
+ {1642860000 43200 0 FJT}
+ {1666447200 46800 1 FJST}
+ {1674309600 43200 0 FJT}
+ {1697896800 46800 1 FJST}
+ {1705759200 43200 0 FJT}
+ {1729951200 46800 1 FJST}
+ {1737208800 43200 0 FJT}
+ {1761400800 46800 1 FJST}
+ {1768658400 43200 0 FJT}
+ {1792850400 46800 1 FJST}
+ {1800712800 43200 0 FJT}
+ {1824300000 46800 1 FJST}
+ {1832162400 43200 0 FJT}
+ {1855749600 46800 1 FJST}
+ {1863612000 43200 0 FJT}
+ {1887199200 46800 1 FJST}
+ {1895061600 43200 0 FJT}
+ {1919253600 46800 1 FJST}
+ {1926511200 43200 0 FJT}
+ {1950703200 46800 1 FJST}
+ {1957960800 43200 0 FJT}
+ {1982152800 46800 1 FJST}
+ {1990015200 43200 0 FJT}
+ {2013602400 46800 1 FJST}
+ {2021464800 43200 0 FJT}
+ {2045052000 46800 1 FJST}
+ {2052914400 43200 0 FJT}
+ {2076501600 46800 1 FJST}
+ {2084364000 43200 0 FJT}
+ {2108556000 46800 1 FJST}
+ {2115813600 43200 0 FJT}
+ {2140005600 46800 1 FJST}
+ {2147868000 43200 0 FJT}
+ {2171455200 46800 1 FJST}
+ {2179317600 43200 0 FJT}
+ {2202904800 46800 1 FJST}
+ {2210767200 43200 0 FJT}
+ {2234354400 46800 1 FJST}
+ {2242216800 43200 0 FJT}
+ {2266408800 46800 1 FJST}
+ {2273666400 43200 0 FJT}
+ {2297858400 46800 1 FJST}
+ {2305116000 43200 0 FJT}
+ {2329308000 46800 1 FJST}
+ {2337170400 43200 0 FJT}
+ {2360757600 46800 1 FJST}
+ {2368620000 43200 0 FJT}
+ {2392207200 46800 1 FJST}
+ {2400069600 43200 0 FJT}
+ {2423656800 46800 1 FJST}
+ {2431519200 43200 0 FJT}
+ {2455711200 46800 1 FJST}
+ {2462968800 43200 0 FJT}
+ {2487160800 46800 1 FJST}
+ {2495023200 43200 0 FJT}
+ {2518610400 46800 1 FJST}
+ {2526472800 43200 0 FJT}
+ {2550060000 46800 1 FJST}
+ {2557922400 43200 0 FJT}
+ {2581509600 46800 1 FJST}
+ {2589372000 43200 0 FJT}
+ {2613564000 46800 1 FJST}
+ {2620821600 43200 0 FJT}
+ {2645013600 46800 1 FJST}
+ {2652271200 43200 0 FJT}
+ {2676463200 46800 1 FJST}
+ {2684325600 43200 0 FJT}
+ {2707912800 46800 1 FJST}
+ {2715775200 43200 0 FJT}
+ {2739362400 46800 1 FJST}
+ {2747224800 43200 0 FJT}
+ {2770812000 46800 1 FJST}
+ {2778674400 43200 0 FJT}
+ {2802866400 46800 1 FJST}
+ {2810124000 43200 0 FJT}
+ {2834316000 46800 1 FJST}
+ {2841573600 43200 0 FJT}
+ {2865765600 46800 1 FJST}
+ {2873628000 43200 0 FJT}
+ {2897215200 46800 1 FJST}
+ {2905077600 43200 0 FJT}
+ {2928664800 46800 1 FJST}
+ {2936527200 43200 0 FJT}
+ {2960114400 46800 1 FJST}
+ {2967976800 43200 0 FJT}
+ {2992168800 46800 1 FJST}
+ {2999426400 43200 0 FJT}
+ {3023618400 46800 1 FJST}
+ {3031480800 43200 0 FJT}
+ {3055068000 46800 1 FJST}
+ {3062930400 43200 0 FJT}
+ {3086517600 46800 1 FJST}
+ {3094380000 43200 0 FJT}
+ {3117967200 46800 1 FJST}
+ {3125829600 43200 0 FJT}
+ {3150021600 46800 1 FJST}
+ {3157279200 43200 0 FJT}
+ {3181471200 46800 1 FJST}
+ {3188728800 43200 0 FJT}
+ {3212920800 46800 1 FJST}
+ {3220783200 43200 0 FJT}
+ {3244370400 46800 1 FJST}
+ {3252232800 43200 0 FJT}
+ {3275820000 46800 1 FJST}
+ {3283682400 43200 0 FJT}
+ {3307269600 46800 1 FJST}
+ {3315132000 43200 0 FJT}
+ {3339324000 46800 1 FJST}
+ {3346581600 43200 0 FJT}
+ {3370773600 46800 1 FJST}
+ {3378636000 43200 0 FJT}
+ {3402223200 46800 1 FJST}
+ {3410085600 43200 0 FJT}
+ {3433672800 46800 1 FJST}
+ {3441535200 43200 0 FJT}
+ {3465122400 46800 1 FJST}
+ {3472984800 43200 0 FJT}
+ {3497176800 46800 1 FJST}
+ {3504434400 43200 0 FJT}
+ {3528626400 46800 1 FJST}
+ {3535884000 43200 0 FJT}
+ {3560076000 46800 1 FJST}
+ {3567938400 43200 0 FJT}
+ {3591525600 46800 1 FJST}
+ {3599388000 43200 0 FJT}
+ {3622975200 46800 1 FJST}
+ {3630837600 43200 0 FJT}
+ {3654424800 46800 1 FJST}
+ {3662287200 43200 0 FJT}
+ {3686479200 46800 1 FJST}
+ {3693736800 43200 0 FJT}
+ {3717928800 46800 1 FJST}
+ {3725186400 43200 0 FJT}
+ {3749378400 46800 1 FJST}
+ {3757240800 43200 0 FJT}
+ {3780828000 46800 1 FJST}
+ {3788690400 43200 0 FJT}
+ {3812277600 46800 1 FJST}
+ {3820140000 43200 0 FJT}
+ {3843727200 46800 1 FJST}
+ {3851589600 43200 0 FJT}
+ {3875781600 46800 1 FJST}
+ {3883039200 43200 0 FJT}
+ {3907231200 46800 1 FJST}
+ {3915093600 43200 0 FJT}
+ {3938680800 46800 1 FJST}
+ {3946543200 43200 0 FJT}
+ {3970130400 46800 1 FJST}
+ {3977992800 43200 0 FJT}
+ {4001580000 46800 1 FJST}
+ {4009442400 43200 0 FJT}
+ {4033634400 46800 1 FJST}
+ {4040892000 43200 0 FJT}
+ {4065084000 46800 1 FJST}
+ {4072341600 43200 0 FJT}
+ {4096533600 46800 1 FJST}
}
diff --git a/library/tzdata/Pacific/Honolulu b/library/tzdata/Pacific/Honolulu
index e24b096..5e70598 100644
--- a/library/tzdata/Pacific/Honolulu
+++ b/library/tzdata/Pacific/Honolulu
@@ -6,5 +6,6 @@ set TZData(:Pacific/Honolulu) {
{-1157283000 -34200 1 HDT}
{-1155436200 -37800 0 HST}
{-880198200 -34200 1 HDT}
+ {-765376200 -37800 0 HST}
{-712150200 -36000 0 HST}
}
diff --git a/library/tzdata/Pacific/Johnston b/library/tzdata/Pacific/Johnston
index 7f9fee4..21ab39a 100644
--- a/library/tzdata/Pacific/Johnston
+++ b/library/tzdata/Pacific/Johnston
@@ -1,5 +1,5 @@
# created by tools/tclZIC.tcl - do not edit
-
-set TZData(:Pacific/Johnston) {
- {-9223372036854775808 -36000 0 HST}
+if {![info exists TZData(Pacific/Honolulu)]} {
+ LoadTimeZoneFile Pacific/Honolulu
}
+set TZData(:Pacific/Johnston) $TZData(:Pacific/Honolulu)
diff --git a/library/word.tcl b/library/word.tcl
index 16a4638..b8f34a5 100644
--- a/library/word.tcl
+++ b/library/word.tcl
@@ -67,7 +67,7 @@ namespace eval ::tcl {
proc tcl_wordBreakAfter {str start} {
variable ::tcl::WordBreakRE
set result {-1 -1}
- regexp -indices -start $start $WordBreakRE(after) $str result
+ regexp -indices -start $start -- $WordBreakRE(after) $str result
return [lindex $result 1]
}
@@ -85,7 +85,7 @@ proc tcl_wordBreakAfter {str start} {
proc tcl_wordBreakBefore {str start} {
variable ::tcl::WordBreakRE
set result {-1 -1}
- regexp -indices $WordBreakRE(before) [string range $str 0 $start] result
+ regexp -indices -- $WordBreakRE(before) [string range $str 0 $start] result
return [lindex $result 1]
}
@@ -104,7 +104,7 @@ proc tcl_wordBreakBefore {str start} {
proc tcl_endOfWord {str start} {
variable ::tcl::WordBreakRE
set result {-1 -1}
- regexp -indices -start $start $WordBreakRE(end) $str result
+ regexp -indices -start $start -- $WordBreakRE(end) $str result
return [lindex $result 1]
}
@@ -122,7 +122,7 @@ proc tcl_endOfWord {str start} {
proc tcl_startOfNextWord {str start} {
variable ::tcl::WordBreakRE
set result {-1 -1}
- regexp -indices -start $start $WordBreakRE(next) $str result
+ regexp -indices -start $start -- $WordBreakRE(next) $str result
return [lindex $result 1]
}
@@ -138,7 +138,7 @@ proc tcl_startOfNextWord {str start} {
proc tcl_startOfPreviousWord {str start} {
variable ::tcl::WordBreakRE
set word {-1 -1}
- regexp -indices $WordBreakRE(previous) [string range $str 0 $start-1] \
+ regexp -indices -- $WordBreakRE(previous) [string range $str 0 $start-1] \
result word
return [lindex $word 0]
}
diff --git a/macosx/README b/macosx/README
index 6b944ca..bcffde3 100644
--- a/macosx/README
+++ b/macosx/README
@@ -20,8 +20,8 @@ before asking on the list, many questions have already been answered).
http://wiki.tcl.tk/_/ref?N=3753
http://wiki.tcl.tk/_/ref?N=8361
-- Please report bugs with Tcl or Tk on Mac OS X to the sourceforge bug trackers:
- http://tcl.sourceforge.net/
+- Please report bugs with Tcl on Mac OS X to the tracker:
+ http://core.tcl.tk/tcl/reportlist
2. Using Tcl on Mac OS X
------------------------
diff --git a/macosx/Tcl.xcode/project.pbxproj b/macosx/Tcl.xcode/project.pbxproj
index 6801d54..a2a703b 100644
--- a/macosx/Tcl.xcode/project.pbxproj
+++ b/macosx/Tcl.xcode/project.pbxproj
@@ -787,7 +787,6 @@
F96D443208F272B8004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
F96D443308F272B8004A47F5 /* regexpTestLib.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpTestLib.tcl; sourceTree = "<group>"; };
F96D443508F272B8004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
- F96D443608F272B8004A47F5 /* tcl.wse.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.wse.in; sourceTree = "<group>"; };
F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "tcltk-man2html.tcl"; sourceTree = "<group>"; };
F96D443A08F272B9004A47F5 /* tclZIC.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclZIC.tcl; sourceTree = "<group>"; };
F96D443B08F272B9004A47F5 /* uniClass.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniClass.tcl; sourceTree = "<group>"; };
@@ -1686,7 +1685,6 @@
F96D443208F272B8004A47F5 /* README */,
F96D443308F272B8004A47F5 /* regexpTestLib.tcl */,
F96D443508F272B8004A47F5 /* tcl.hpj.in */,
- F96D443608F272B8004A47F5 /* tcl.wse.in */,
F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */,
F96D443A08F272B9004A47F5 /* tclZIC.tcl */,
F92D7F100DE777240033A13A /* tsdPerf.tcl */,
diff --git a/macosx/Tcl.xcodeproj/project.pbxproj b/macosx/Tcl.xcodeproj/project.pbxproj
index b37f2e3..9c18ac0 100644
--- a/macosx/Tcl.xcodeproj/project.pbxproj
+++ b/macosx/Tcl.xcodeproj/project.pbxproj
@@ -787,7 +787,6 @@
F96D443208F272B8004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
F96D443308F272B8004A47F5 /* regexpTestLib.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpTestLib.tcl; sourceTree = "<group>"; };
F96D443508F272B8004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
- F96D443608F272B8004A47F5 /* tcl.wse.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.wse.in; sourceTree = "<group>"; };
F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "tcltk-man2html.tcl"; sourceTree = "<group>"; };
F96D443A08F272B9004A47F5 /* tclZIC.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclZIC.tcl; sourceTree = "<group>"; };
F96D443B08F272B9004A47F5 /* uniClass.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniClass.tcl; sourceTree = "<group>"; };
@@ -1686,7 +1685,6 @@
F96D443208F272B8004A47F5 /* README */,
F96D443308F272B8004A47F5 /* regexpTestLib.tcl */,
F96D443508F272B8004A47F5 /* tcl.hpj.in */,
- F96D443608F272B8004A47F5 /* tcl.wse.in */,
F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */,
F96D443A08F272B9004A47F5 /* tclZIC.tcl */,
F92D7F100DE777240033A13A /* tsdPerf.tcl */,
diff --git a/macosx/tclMacOSXFCmd.c b/macosx/tclMacOSXFCmd.c
index 9193c1a..8ecfd0b 100644
--- a/macosx/tclMacOSXFCmd.c
+++ b/macosx/tclMacOSXFCmd.c
@@ -148,8 +148,9 @@ TclMacOSXGetFileAttribute(
result = TclpObjStat(fileName, &statBuf);
if (result != 0) {
- Tcl_AppendResult(interp, "could not read \"", TclGetString(fileName),
- "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not read \"%s\": %s",
+ TclGetString(fileName), Tcl_PosixError(interp)));
return TCL_ERROR;
}
@@ -159,8 +160,8 @@ TclMacOSXGetFileAttribute(
*/
errno = EISDIR;
- Tcl_AppendResult(interp, "invalid attribute: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid attribute: %s", Tcl_PosixError(interp)));
return TCL_ERROR;
}
@@ -175,8 +176,9 @@ TclMacOSXGetFileAttribute(
result = getattrlist(native, &alist, &finfo, sizeof(fileinfobuf), 0);
if (result != 0) {
- Tcl_AppendResult(interp, "could not read attributes of \"",
- TclGetString(fileName), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not read attributes of \"%s\": %s",
+ TclGetString(fileName), Tcl_PosixError(interp)));
return TCL_ERROR;
}
@@ -199,10 +201,11 @@ TclMacOSXGetFileAttribute(
}
return TCL_OK;
#else
- Tcl_AppendResult(interp, "Mac OS X file attributes not supported", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "Mac OS X file attributes not supported", -1));
Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL);
return TCL_ERROR;
-#endif
+#endif /* HAVE_GETATTRLIST */
}
/*
@@ -241,8 +244,9 @@ TclMacOSXSetFileAttribute(
result = TclpObjStat(fileName, &statBuf);
if (result != 0) {
- Tcl_AppendResult(interp, "could not read \"", TclGetString(fileName),
- "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not read \"%s\": %s",
+ TclGetString(fileName), Tcl_PosixError(interp)));
return TCL_ERROR;
}
@@ -252,8 +256,8 @@ TclMacOSXSetFileAttribute(
*/
errno = EISDIR;
- Tcl_AppendResult(interp, "invalid attribute: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid attribute: %s", Tcl_PosixError(interp)));
return TCL_ERROR;
}
@@ -268,8 +272,9 @@ TclMacOSXSetFileAttribute(
result = getattrlist(native, &alist, &finfo, sizeof(fileinfobuf), 0);
if (result != 0) {
- Tcl_AppendResult(interp, "could not read attributes of \"",
- TclGetString(fileName), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not read attributes of \"%s\": %s",
+ TclGetString(fileName), Tcl_PosixError(interp)));
return TCL_ERROR;
}
@@ -306,9 +311,9 @@ TclMacOSXSetFileAttribute(
&finfo.data, sizeof(finfo.data), 0);
if (result != 0) {
- Tcl_AppendResult(interp, "could not set attributes of \"",
- TclGetString(fileName), "\": ", Tcl_PosixError(interp),
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not set attributes of \"%s\": %s",
+ TclGetString(fileName), Tcl_PosixError(interp)));
return TCL_ERROR;
}
} else {
@@ -328,8 +333,8 @@ TclMacOSXSetFileAttribute(
*/
if (newRsrcForkSize != 0) {
- Tcl_AppendResult(interp,
- "setting nonzero rsrclength not supported", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "setting nonzero rsrclength not supported", -1));
Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL);
return TCL_ERROR;
}
@@ -360,17 +365,17 @@ TclMacOSXSetFileAttribute(
Tcl_DStringFree(&ds);
if (result != 0) {
- Tcl_AppendResult(interp,
- "could not truncate resource fork of \"",
- TclGetString(fileName), "\": ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not truncate resource fork of \"%s\": %s",
+ TclGetString(fileName), Tcl_PosixError(interp)));
return TCL_ERROR;
}
}
}
return TCL_OK;
#else
- Tcl_AppendResult(interp, "Mac OS X file attributes not supported", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "Mac OS X file attributes not supported", -1));
Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL);
return TCL_ERROR;
#endif
@@ -573,7 +578,7 @@ GetOSTypeFromObj(
int result = TCL_OK;
if (objPtr->typePtr != &tclOSTypeType) {
- result = tclOSTypeType.setFromAnyProc(interp, objPtr);
+ result = SetOSTypeFromAny(interp, objPtr);
}
*osTypePtr = (OSType) objPtr->internalRep.longValue;
return result;
@@ -603,7 +608,7 @@ NewOSTypeObj(
Tcl_Obj *objPtr;
TclNewObj(objPtr);
- Tcl_InvalidateStringRep(objPtr);
+ TclInvalidateStringRep(objPtr);
objPtr->internalRep.longValue = (long) osType;
objPtr->typePtr = &tclOSTypeType;
return objPtr;
@@ -640,8 +645,8 @@ SetOSTypeFromAny(
if (Tcl_DStringLength(&ds) > 4) {
if (interp) {
- Tcl_AppendResult(interp, "expected Macintosh OS type but got \"",
- string, "\": ", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "expected Macintosh OS type but got \"%s\": ", string));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "MAC_OSTYPE", NULL);
}
result = TCL_ERROR;
diff --git a/pkgs/README b/pkgs/README
index e2b33f5..868bd4f 100644
--- a/pkgs/README
+++ b/pkgs/README
@@ -1 +1,57 @@
-Add notes here about bundling packages with Tcl.
+
+The 'pkgs' subdirectory of the Tcl source code distribution is meant to be
+a place where the source code distribution of Tcl packages may be placed so
+that they are built, installed, and tested along with Tcl. As originally
+distributed, Tcl re-distributes a number of packages in this location. The
+build systems for Tcl are written so that additional packages may be added,
+or the original packages removed in any number and still have all packages
+present get built, installed, and tested along with Tcl.
+
+In order for a package to work properly under the pkgs subdirectory, it
+needs to conform to the following conventions.
+
+ All files of the package need to be contained in (subdirs of ...) a
+ single subdirectory of the "pkgs" directrory.
+
+ In that subdirectory of "pkgs" there must be an executable file named
+ "configure". When the program "configure" is run, it should generate
+ a file "Makefile" in the current working directory. The "configure"
+ program should be able to accept as command line arguments all the
+ arguments that can be passed to the master unix/configure program. It
+ should also accept the --with-tcl= and --with-tclinclude= options in
+ the conventional way.
+
+ The generated "Makefile" must be one suitable for controlling the operations
+ of a `make` program. The following targets must be defined:
+
+ <default>: Perform a build of the runtime components of the
+ package from sources.
+
+ install: Copy the runtime components of the package into their
+ installed location. Must respect the DESTDIR variable
+ for determining the installation location.
+
+ test: Run the test suite of the package. Must respect the
+ TCLSH_PROG, TESTFLAGS variables.
+
+ clean: Delete all files generated by the default build target.
+
+ distclean: Delete all generated files.
+
+ dist: Produce a copy of the package's source code distribution.
+ Must respect the DIST_ROOT variable determining where to
+ write the generated directory.
+
+Packages that are written to make use of the Tcl Extension Architecture (TEA)
+and that make use of the tclconfig collection of support files, should
+conform to these conventions without further efforts.
+
+These conventions are subject to revision and refinement over time to
+better support the needs of the build system. Efforts will be made to
+keep the TEA support scripts consistent with the demands of this system.
+
+In addition, it is requested that packages also support building with
+Microsoft Visual Studio tools. This means the file win/makefile.vc
+should be included, suitable for use by the nmake program, defining the
+targets <default>, install, test, and clean.
+
diff --git a/pkgs/package.list.txt b/pkgs/package.list.txt
new file mode 100644
index 0000000..0d5dcf8
--- /dev/null
+++ b/pkgs/package.list.txt
@@ -0,0 +1,35 @@
+# This file contains the mapping of directory names to package names for
+# documentation purposes. Each non-blank non-comment line is a two-element
+# list that says a possible name of directory (multiple lines may be needed
+# because of capitalization issues) and the documentation name of the package
+# to match. Pseudo-numeric suffixes are interpreted as version numbers.
+
+# [incr Tcl]
+itcl {[incr Tcl]}
+Itcl {[incr Tcl]}
+
+# SQLite
+Sqlite SQLite3
+sqlite SQLite3
+Sqlite3 SQLite3
+sqlite3 SQLite3
+
+# Thread
+Thread Thread
+thread Thread
+
+# Tcl Database Connectivity
+tdbc TDBC
+Tdbc TDBC
+TDBC TDBC
+# Drivers for TDBC
+Tdbcmysql tdbc::mysql
+tdbcmysql tdbc::mysql
+Tdbcodbc tdbc::odbc
+tdbcodbc tdbc::odbc
+Tdbcpostgres tdbc::postgres
+tdbcpostgres tdbc::postgres
+Tdbcsqlite3 tdbc::sqlite3
+tdbcsqlite3 tdbc::sqlite3
+Tdbcsqlite tdbc::sqlite3
+tdbcsqlite tdbc::sqlite3
diff --git a/tests/all.tcl b/tests/all.tcl
index d01a54d..05d3024 100644
--- a/tests/all.tcl
+++ b/tests/all.tcl
@@ -10,8 +10,10 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+package prefer latest
package require Tcl 8.5
package require tcltest 2.2
namespace import tcltest::*
configure {*}$argv -testdir [file dir [info script]]
runAllTests
+proc exit args {}
diff --git a/tests/assemble.test b/tests/assemble.test
index 7d4e5d1..b0487e6 100644
--- a/tests/assemble.test
+++ b/tests/assemble.test
@@ -175,8 +175,7 @@ test assemble-4.1 {syntax error} {
-match glob
-result {1 {extra characters after close-brace} {extra characters after close-brace
while executing
-"{}extra
- "
+"{}e"
("assemble" body, line 2)*}}
}
test assemble-4.2 {null command} {
diff --git a/tests/assocd.test b/tests/assocd.test
index 1ca1c9b..edf55c4 100644
--- a/tests/assocd.test
+++ b/tests/assocd.test
@@ -11,10 +11,11 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest
- namespace import -force ::tcltest::*
-}
+package require tcltest 2
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
testConstraint testgetassocdata [llength [info commands testgetassocdata]]
testConstraint testsetassocdata [llength [info commands testsetassocdata]]
@@ -33,15 +34,21 @@ test assocd-1.4 {testing setting assoc data} testsetassocdata {
testsetassocdata abc "abc d e f"
} ""
-test assocd-2.1 {testing getting assoc data} testgetassocdata {
- testgetassocdata a
-} 2
-test assocd-2.2 {testing getting assoc data} testgetassocdata {
- testgetassocdata 123
-} 456
-test assocd-2.3 {testing getting assoc data} testgetassocdata {
+test assocd-2.1 {testing getting assoc data} -setup {
+ testsetassocdata a 2
+} -constraints {testgetassocdata} -body {
+ testgetassocdata a
+} -result 2
+test assocd-2.2 {testing getting assoc data} -setup {
+ testsetassocdata 123 456
+} -constraints {testgetassocdata} -body {
+ testgetassocdata 123
+} -result 456
+test assocd-2.3 {testing getting assoc data} -setup {
+ testsetassocdata abc "abc d e f"
+} -constraints {testgetassocdata} -body {
testgetassocdata abc
-} {abc d e f}
+} -result "abc d e f"
test assocd-2.4 {testing getting assoc data} testgetassocdata {
testgetassocdata xxx
} ""
@@ -57,5 +64,5 @@ test assocd-3.3 {testing deleting assoc data} testdelassocdata {
} {0 {}}
# cleanup
-::tcltest::cleanupTests
+cleanupTests
return
diff --git a/tests/async.test b/tests/async.test
index db21333..cb67cc2 100644
--- a/tests/async.test
+++ b/tests/async.test
@@ -16,10 +16,11 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testasync [llength [info commands testasync]]
-testConstraint threaded [expr {
- [info exists ::tcl_platform(threaded)] && $::tcl_platform(threaded)
-}]
+testConstraint threaded [::tcl::pkgconfig get threaded]
proc async1 {result code} {
global aresult acode
@@ -196,7 +197,7 @@ test async-4.3 {async interrupting loop-less bytecode sequence} -constraints {
set aresult {Async event not delivered}
testasync marklater $handle
set i 0
- } [string repeat {;incr i;} 1500000] {
+ } "[string repeat {;incr i;} 1500000]after 10;" {
return $aresult
}]] $hm
} -result {test pattern} -cleanup {
diff --git a/tests/autoMkindex.test b/tests/autoMkindex.test
index 8f29131..4721553 100644
--- a/tests/autoMkindex.test
+++ b/tests/autoMkindex.test
@@ -236,6 +236,38 @@ test autoMkindex-3.3 {auto_mkindex_parser::command} -setup {
# Reset initCommands to avoid trashing other tests
AutoMkindexTestReset
} -result "{::buried::mycmd4 $element} {::buried::mycmd5 $element} {mycmd6 $element}"
+makeFile {
+
+namespace eval wok {
+ namespace ensemble create -subcommands {commands vars}
+
+ proc commands {{pattern *}} {
+ puts [join [lsort -dictionary [info commands $pattern]] \n]
+ }
+
+ proc vars {{pattern *}} {
+ puts [join [lsort -dictionary [info vars $pattern]] \n]
+ }
+
+}
+
+} ensemblecommands.tcl
+
+test autoMkindex-3.4 {ensemble commands in tclIndex} {
+ file delete tclIndex
+ auto_mkindex . ensemblecommands.tcl
+ set f [open tclIndex r]
+ set dat [list]
+ foreach r [split [string trim [read $f]] "\n"] {
+ if {[string match {set auto_index*} $r]} {
+ lappend dat $r
+ }
+ }
+ set result [lsort $dat]
+ close $f
+ set result
+} {{set auto_index(::wok::commands) [list source [file join $dir ensemblecommands.tcl]]} {set auto_index(::wok::vars) [list source [file join $dir ensemblecommands.tcl]]} {set auto_index(wok) [list source [file join $dir ensemblecommands.tcl]]}}
+removeFile ensemblecommands.tcl
test autoMkindex-4.1 {platform independent source commands} -setup {
file delete tclIndex
diff --git a/tests/basic.test b/tests/basic.test
index e072bea..1a0037c 100644
--- a/tests/basic.test
+++ b/tests/basic.test
@@ -16,7 +16,10 @@
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
package require tcltest 2
-namespace import -force ::tcltest::*
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
testConstraint testevalex [llength [info commands testevalex]]
testConstraint testcmdtoken [llength [info commands testcmdtoken]]
@@ -28,7 +31,7 @@ catch {interp delete test_interp}
catch {rename p ""}
catch {rename q ""}
catch {rename cmd ""}
-catch {unset x}
+unset -nocomplain x
test basic-1.1 {Tcl_CreateInterp, creates interp's global namespace} {
catch {interp delete test_interp}
@@ -264,14 +267,24 @@ test basic-18.4 {TclRenameCommand, bad new name} {
}
rename test_ns_basic::p :::george::martha
} {}
-test basic-18.5 {TclRenameCommand, new name must not already exist} {
+test basic-18.5 {TclRenameCommand, new name must not already exist} -setup {
+ if {![llength [info commands :::george::martha]]} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_basic {
+ proc p {} {
+ return "p in [namespace current]"
+ }
+ }
+ rename test_ns_basic::p :::george::martha
+ }
+} -body {
namespace eval test_ns_basic {
proc q {} {
return 42
}
}
list [catch {rename test_ns_basic::q :::george::martha} msg] $msg
-} {1 {can't rename to ":::george::martha": command already exists}}
+} -result {1 {can't rename to ":::george::martha": command already exists}}
test basic-18.6 {TclRenameCommand, check for command shadowing by newly renamed cmd} {
catch {namespace delete {*}[namespace children :: test_ns_*]}
catch {rename p ""}
@@ -299,7 +312,7 @@ test basic-20.1 {Tcl_GetCommandInfo, names for commands created inside namespace
catch {namespace delete {*}[namespace children :: test_ns_*]}
catch {rename p ""}
catch {rename q ""}
- catch {unset x}
+ unset -nocomplain x
set x [namespace eval test_ns_basic::test_ns_basic2 {
# the following creates a cmd in the global namespace
testcmdtoken create p
@@ -352,7 +365,7 @@ test basic-23.1 {Tcl_DeleteCommand} {emptyTest} {
test basic-24.1 {Tcl_DeleteCommandFromToken, invalidate all compiled code if cmd has compile proc} {
catch {interp delete test_interp}
- catch {unset x}
+ unset -nocomplain x
interp create test_interp
interp eval test_interp {
proc useSet {} {
@@ -424,7 +437,7 @@ test basic-26.1 {Tcl_EvalObj: preserve object while evaling it} -setup {
# string would have been freed, leaving garbage bytes for the error
# message.
set f [open $fName w]
- fileevent $f writable "fileevent $f writable {}; error foo"
+ chan event $f writable "chan event $f writable {}; error foo"
set x {}
vwait x
close $f
@@ -544,8 +557,8 @@ test basic-46.1 {Tcl_AllowExceptions: exception return not allowed} {stdio} {
catch {close $f}
set res [catch {
set f [open |[list [interpreter]] w+]
- fconfigure $f -buffering line
- puts $f {fconfigure stdout -buffering line}
+ chan configure $f -buffering line
+ puts $f {chan configure stdout -buffering line}
puts $f continue
puts $f {puts $::errorInfo}
puts $f {puts DONE}
@@ -969,6 +982,6 @@ catch {rename p ""}
catch {rename q ""}
catch {rename cmd ""}
catch {rename value:at: ""}
-catch {unset x}
-::tcltest::cleanupTests
+unset -nocomplain x
+cleanupTests
return
diff --git a/tests/binary.test b/tests/binary.test
index 8b2880b..40b1315 100644
--- a/tests/binary.test
+++ b/tests/binary.test
@@ -1582,38 +1582,46 @@ test binary-40.4 {ScanNumber: NaN} -body {
list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff d arg1] $arg1
} -match glob -result {1 -NaN*}
-test binary-41.1 {ScanNumber: word alignment} {
- unset -nocomplain arg1; unset arg2
+test binary-41.1 {ScanNumber: word alignment} -setup {
+ unset -nocomplain arg1 arg2
+} -body {
list [binary scan \x01\x01\x00 c1s1 arg1 arg2] $arg1 $arg2
-} {2 1 1}
-test binary-41.2 {ScanNumber: word alignment} {
- unset -nocomplain arg1; unset arg2
+} -result {2 1 1}
+test binary-41.2 {ScanNumber: word alignment} -setup {
+ unset -nocomplain arg1 arg2
+} -body {
list [binary scan \x01\x00\x01 c1S1 arg1 arg2] $arg1 $arg2
-} {2 1 1}
-test binary-41.3 {ScanNumber: word alignment} {
- unset -nocomplain arg1; unset arg2
+} -result {2 1 1}
+test binary-41.3 {ScanNumber: word alignment} -setup {
+ unset -nocomplain arg1 arg2
+} -body {
list [binary scan \x01\x01\x00\x00\x00 c1i1 arg1 arg2] $arg1 $arg2
-} {2 1 1}
-test binary-41.4 {ScanNumber: word alignment} {
- unset -nocomplain arg1; unset arg2
+} -result {2 1 1}
+test binary-41.4 {ScanNumber: word alignment} -setup {
+ unset -nocomplain arg1 arg2
+} -body {
list [binary scan \x01\x00\x00\x00\x01 c1I1 arg1 arg2] $arg1 $arg2
-} {2 1 1}
-test binary-41.5 {ScanNumber: word alignment} bigEndian {
- unset -nocomplain arg1; unset arg2
+} -result {2 1 1}
+test binary-41.5 {ScanNumber: word alignment} -setup {
+ unset -nocomplain arg1 arg2
+} -constraints bigEndian -body {
list [binary scan \x01\x3f\xcc\xcc\xcd c1f1 arg1 arg2] $arg1 $arg2
-} {2 1 1.600000023841858}
-test binary-41.6 {ScanNumber: word alignment} littleEndian {
- unset -nocomplain arg1; unset arg2
+} -result {2 1 1.600000023841858}
+test binary-41.6 {ScanNumber: word alignment} -setup {
+ unset -nocomplain arg1 arg2
+} -constraints littleEndian -body {
list [binary scan \x01\xcd\xcc\xcc\x3f c1f1 arg1 arg2] $arg1 $arg2
-} {2 1 1.600000023841858}
-test binary-41.7 {ScanNumber: word alignment} bigEndian {
- unset -nocomplain arg1; unset arg2
+} -result {2 1 1.600000023841858}
+test binary-41.7 {ScanNumber: word alignment} -setup {
+ unset -nocomplain arg1 arg2
+} -constraints bigEndian -body {
list [binary scan \x01\x3f\xf9\x99\x99\x99\x99\x99\x9a c1d1 arg1 arg2] $arg1 $arg2
-} {2 1 1.6}
-test binary-41.8 {ScanNumber: word alignment} littleEndian {
- unset -nocomplain arg1; unset arg2
+} -result {2 1 1.6}
+test binary-41.8 {ScanNumber: word alignment} -setup {
+ unset -nocomplain arg1 arg2
+} -constraints littleEndian -body {
list [binary scan \x01\x9a\x99\x99\x99\x99\x99\xf9\x3f c1d1 arg1 arg2] $arg1 $arg2
-} {2 1 1.6}
+} -result {2 1 1.6}
test binary-42.1 {Tcl_BinaryObjCmd: bad arguments} -constraints {} -body {
binary ?
@@ -2381,6 +2389,23 @@ test binary-63.4 {NaN} ieeeFloatingPoint {
format 0x%016lx [expr {$w & 0xfff3ffffffffffff}]
} 0x7ff3123456789abc
+# Make sure TclParseNumber() rejects invalid nan-hex formats [Bug 3402540]
+test binary-63.5 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan(
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.6 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan()
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.7 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan(g)
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.8 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan(1,2)
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.9 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan(1234567890abcd)
+} -returnCodes error -match glob -result {expected floating-point number*}
+
test binary-64.1 {NaN} -constraints ieeeFloatingPoint -body {
binary scan [binary format w 0x7ff8000000000000] q d
set d
@@ -2474,6 +2499,34 @@ test binary-71.9 {binary decode hex} -body {
test binary-71.10 {binary decode hex} -body {
string length [binary decode hex " "]
} -result 0
+test binary-71.11 {binary decode hex: Bug b98fa55285} -body {
+ apply {{} {
+ set str "137b6f95e7519389e7c4b36599781e2ccf492699649249aae43fbe8c26\n"
+ set decoded [binary decode hex $str]
+ list [string length $decoded] [scan [string index $decoded end] %c]
+ }}
+} -result {29 38}
+test binary-71.12 {binary decode hex: Bug b98fa55285 cross check} -body {
+ apply {{} {
+ set str "137b6f95e7519389e7c4b36599781e2ccf492699649249aae43fbe8c2\n"
+ set decoded [binary decode hex $str]
+ list [string length $decoded] [scan [string index $decoded end] %c]
+ }}
+} -result {28 140}
+test binary-71.13 {binary decode hex: Bug b98fa55285 cross check} -body {
+ apply {{} {
+ set str "137b6f95e7519389e7c4b36599781e2ccf492699649249aae43fbe8c2\n\n"
+ set decoded [binary decode hex $str]
+ list [string length $decoded] [scan [string index $decoded end] %c]
+ }}
+} -result {28 140}
+test binary-71.14 {binary decode hex: Bug b98fa55285 cross check} -body {
+ apply {{} {
+ set str "137b6f95e7519389e7c4b36599781e2ccf492699649249aae43fbe8c2\n\n\n"
+ set decoded [binary decode hex $str]
+ list [string length $decoded] [scan [string index $decoded end] %c]
+ }}
+} -result {28 140}
test binary-72.1 {binary encode base64} -body {
binary encode base64
@@ -2625,111 +2678,143 @@ test binary-73.23 {binary decode base64} -body {
test binary-73.24 {binary decode base64} -body {
string length [binary decode base64 " "]
} -result 0
+test binary-73.25 {binary decode base64} -body {
+ list [string length [set r [binary decode base64 WA==\n]]] $r
+} -result {1 X}
+test binary-73.26 {binary decode base64} -body {
+ list [string length [set r [binary decode base64 WFk=\n]]] $r
+} -result {2 XY}
+test binary-73.27 {binary decode base64} -body {
+ list [string length [set r [binary decode base64 WFla\n]]] $r
+} -result {3 XYZ}
+test binary-73.28 {binary decode base64} -body {
+ list [string length [set r [binary decode base64 -strict WA==\n]]] $r
+} -returnCodes error -match glob -result {invalid base64 character *}
+test binary-73.29 {binary decode base64} -body {
+ list [string length [set r [binary decode base64 -strict WFk=\n]]] $r
+} -returnCodes error -match glob -result {invalid base64 character *}
+test binary-73.30 {binary decode base64} -body {
+ list [string length [set r [binary decode base64 -strict WFla\n]]] $r
+} -returnCodes error -match glob -result {invalid base64 character *}
+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-74.1 {binary encode uuencode} -body {
binary encode uuencode
} -returnCodes error -match glob -result "wrong # args: *"
test binary-74.2 {binary encode uuencode} -body {
binary encode uuencode abc
-} -result {86)C}
+} -result {#86)C
+}
test binary-74.3 {binary encode uuencode} -body {
binary encode uuencode {}
} -result {}
test binary-74.4 {binary encode uuencode} -body {
binary encode uuencode [string repeat abc 20]
-} -result [string repeat 86)C 20]
+} -result "M[string repeat 86)C 15]\n/[string repeat 86)C 5]\n"
test binary-74.5 {binary encode uuencode} -body {
binary encode uuencode \0\1\2\3\4\0\1\2\3
-} -result "``\$\"`P0``0(#"
+} -result ")``\$\"`P0``0(#\n"
test binary-74.6 {binary encode uuencode} -body {
binary encode uuencode \0
-} -result {````}
+} -result {!``
+}
test binary-74.7 {binary encode uuencode} -body {
binary encode uuencode \0\0
-} -result {````}
+} -result "\"```
+"
test binary-74.8 {binary encode uuencode} -body {
binary encode uuencode \0\0\0
-} -result {````}
+} -result {#````
+}
test binary-74.9 {binary encode uuencode} -body {
binary encode uuencode \0\0\0\0
-} -result {````````}
-test binary-74.10 {binary encode uuencode} -body {
- binary encode uuencode -maxlen 0 -wrapchar | abcabcabc
-} -result {86)C86)C86)C}
-test binary-74.11 {binary encode uuencode} -body {
- binary encode uuencode -maxlen 1 -wrapchar | abcabcabc
-} -result {8|6|)|C|8|6|)|C|8|6|)|C}
+} -result {$``````
+}
+test binary-74.10 {binary encode uuencode} -returnCodes error -body {
+ binary encode uuencode -foo 30 abcabcabc
+} -result {bad option "-foo": must be -maxlen or -wrapchar}
+test binary-74.11 {binary encode uuencode} -returnCodes error -body {
+ binary encode uuencode -maxlen 1 abcabcabc
+} -result {line length out of range}
+test binary-74.12 {binary encode uuencode} -body {
+ binary encode uuencode -maxlen 3 -wrapchar | abcabcabc
+} -result {!80|!8@|!8P|!80|!8@|!8P|!80|!8@|!8P|}
test binary-75.1 {binary decode uuencode} -body {
binary decode uuencode
} -returnCodes error -match glob -result "wrong # args: *"
test binary-75.2 {binary decode uuencode} -body {
- binary decode uuencode 86)C
+ binary decode uuencode "#86)C\n"
} -result {abc}
test binary-75.3 {binary decode uuencode} -body {
binary decode uuencode {}
} -result {}
+test binary-75.3.1 {binary decode uuencode} -body {
+ binary decode uuencode `\n
+} -result {}
test binary-75.4 {binary decode uuencode} -body {
- binary decode uuencode [string repeat "86)C" 20]
+ binary decode uuencode "M[string repeat 86)C 15]\n/[string repeat 86)C 5]\n"
} -result [string repeat abc 20]
test binary-75.5 {binary decode uuencode} -body {
- binary decode uuencode "``\$\"`P0``0(#"
+ binary decode uuencode ")``\$\"`P0``0(#"
} -result "\0\1\2\3\4\0\1\2\3"
test binary-75.6 {binary decode uuencode} -body {
- string length [binary decode uuencode {`}]
+ string length [binary decode uuencode "`\n"]
} -result 0
test binary-75.7 {binary decode uuencode} -body {
- string length [binary decode uuencode {``}]
+ string length [binary decode uuencode "!`\n"]
} -result 1
test binary-75.8 {binary decode uuencode} -body {
- string length [binary decode uuencode {```}]
+ string length [binary decode uuencode "\"``\n"]
} -result 2
test binary-75.9 {binary decode uuencode} -body {
- string length [binary decode uuencode {````}]
+ string length [binary decode uuencode "#```\n"]
} -result 3
test binary-75.10 {binary decode uuencode} -body {
- set s "[string repeat 86)C 10]\n[string repeat 86)C 10]"
+ set s ">[string repeat 86)C 10]\n>[string repeat 86)C 10]"
binary decode uuencode $s
} -result [string repeat abc 20]
test binary-75.11 {binary decode uuencode} -body {
- set s "[string repeat 86)C 10]\n [string repeat 86)C 10]"
+ set s ">[string repeat 86)C 10]\n\t>\t[string repeat 86)C 10]\r"
binary decode uuencode $s
} -result [string repeat abc 20]
test binary-75.12 {binary decode uuencode} -body {
binary decode uuencode -strict "|86)C"
} -returnCodes error -match glob -result {invalid uuencode character "|" at position 0}
test binary-75.13 {binary decode uuencode} -body {
- set s "[string repeat 86)C 10]|[string repeat 86)C 10]"
+ set s ">[string repeat 86)C 10]|[string repeat 86)C 10]"
binary decode uuencode -strict $s
-} -returnCodes error -match glob -result {invalid uuencode character "|" at position 40}
+} -returnCodes error -match glob -result {invalid uuencode character "|" at position 41}
test binary-75.14 {binary decode uuencode} -body {
- set s "[string repeat 86)C 10]\n [string repeat 86)C 10]"
+ set s ">[string repeat 86)C 10]\na[string repeat 86)C 10]"
binary decode uuencode -strict $s
} -returnCodes error -match glob -result {invalid uuencode character *}
test binary-75.20 {binary decode uuencode} -body {
- set r [binary decode uuencode 8]
+ set r [binary decode uuencode " 8"]
list [string length $r] $r
} -result {0 {}}
test binary-75.21 {binary decode uuencode} -body {
- set r [binary decode uuencode 86]
+ set r [binary decode uuencode "!86"]
list [string length $r] $r
} -result {1 a}
test binary-75.22 {binary decode uuencode} -body {
- set r [binary decode uuencode 86)]
+ set r [binary decode uuencode "\"86)"]
list [string length $r] $r
} -result {2 ab}
test binary-75.23 {binary decode uuencode} -body {
- set r [binary decode uuencode 86)C]
+ set r [binary decode uuencode "#86)C"]
list [string length $r] $r
} -result {3 abc}
test binary-75.24 {binary decode uuencode} -body {
- set s "04)\# "
+ set s "#04)\# "
binary decode uuencode $s
} -result ABC
test binary-75.25 {binary decode uuencode} -body {
- set s "04)\#z"
+ set s "#04)\#z"
binary decode uuencode $s
-} -returnCodes error -match glob -result {invalid uuencode character "z" at position 4}
+} -returnCodes error -match glob -result {invalid uuencode character "z" at position 5}
test binary-75.26 {binary decode uuencode} -body {
string length [binary decode uuencode " "]
} -result 0
diff --git a/tests/chan.test b/tests/chan.test
index da44ffd..d8390e2 100644
--- a/tests/chan.test
+++ b/tests/chan.test
@@ -61,7 +61,7 @@ test chan-4.5 {chan command: check valid inValue, invalid outValue} -body {
} -returnCodes error -match glob -result {bad value for -eofchar:*}
test chan-4.6 {chan command: check no inValue, valid outValue} -body {
chan configure stdout -eofchar [list {} \x27]
-} -returnCodes ok -result {}
+} -returnCodes ok -result {} -cleanup {chan configure stdout -eofchar [list {} {}]}
test chan-5.1 {chan command: copy subcommand} -body {
chan copy foo
diff --git a/tests/chanio.test b/tests/chanio.test
index 5569385..999d0bb 100644
--- a/tests/chanio.test
+++ b/tests/chanio.test
@@ -29,6 +29,9 @@ namespace eval ::tcl::test::io {
variable msg
variable expected
+ ::tcltest::loadTestedCommands
+ catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testchannel [llength [info commands testchannel]]
testConstraint exec [llength [info commands exec]]
testConstraint openpipe 1
@@ -37,7 +40,7 @@ namespace eval ::tcl::test::io {
testConstraint testfevent [llength [info commands testfevent]]
testConstraint testchannelevent [llength [info commands testchannelevent]]
testConstraint testmainthread [llength [info commands testmainthread]]
- testConstraint testthread [llength [info commands testthread]]
+ 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...
@@ -2211,13 +2214,17 @@ test chan-io-28.7 {Tcl_CloseEx (half-close) socket} -setup {
puts $sok DONE
exit 0
} echo.tcl]
-} -body {
+ variable done
+ unset -nocomplain done
+ set done ""
+ set timer ""
set ff [openpipe r $echo]
gets $ff port
+} -body {
set s [socket 127.0.0.1 $port]
puts $s Hey
close $s w
- set timer [after 1000 [namespace code {set ::done Failed}]]
+ set timer [after 1000 [namespace code {set done Failed}]]
set acc {}
fileevent $s readable [namespace code {
if {[gets $s line]<0} {
@@ -2227,11 +2234,11 @@ test chan-io-28.7 {Tcl_CloseEx (half-close) socket} -setup {
}
}]
vwait [namespace which -variable done]
- after cancel $timer
- close $s r
- close $ff
list $done $acc
} -cleanup {
+ catch {close $s}
+ close $ff
+ after cancel $timer
removeFile echo.tcl
} -result {Succeeded {Hey DONE}}
@@ -7413,7 +7420,6 @@ test chan-io-59.1 {Thread reference of channels} {testmainthread testchannel} {
# More complicated tests (like that the reference changes as a channel is
# moved from thread to thread) can be done only in the extension which
# fully implements the moving of channels between threads, i.e. 'Threads'.
- # Or we have to extend [testthread] as well.
set f [open $path(longfile) r]
set result [testchannel mthread $f]
chan close $f
@@ -7494,37 +7500,26 @@ test chan-io-70.0 {Cutting & Splicing channels} -setup {
chan close $c
removeFile cutsplice
} -result {0 1 0}
-# Duplicate of code in "thread.test". Find a better way of doing this without
-# duplication. Maybe placement into a proc which transforms to nop after the
-# first call, and placement of its defintion in a central location.
-if {[testConstraint testthread]} {
- testthread errorproc ThreadError
- proc ThreadError {id info} {
- global threadError
- set threadError $info
- }
- proc ThreadNullError {id info} {
- # ignore
- }
-}
+
test chan-io-70.1 {Transfer channel} -setup {
set f [makeFile {... dummy ...} cutsplice]
set res {}
-} -constraints {testchannel testthread} -body {
+} -constraints {testchannel thread} -body {
set c [open $f r]
lappend res [catch {chan seek $c 0 start}]
testchannel cut $c
lappend res [catch {chan seek $c 0 start}]
- set tid [testthread create]
- testthread send $tid [list set c $c]
- lappend res [testthread send $tid {
+ set tid [thread::create -preserved]
+ thread::send $tid [list set c $c]
+ thread::send $tid {load {} Tcltest}
+ lappend res [thread::send $tid {
testchannel splice $c
set res [catch {chan seek $c 0 start}]
chan close $c
set res
}]
} -cleanup {
- tcltest::threadReap
+ thread::release $tid
removeFile cutsplice
} -result {0 1 0}
diff --git a/tests/clock.test b/tests/clock.test
index 8c31f83..8debba1 100644
--- a/tests/clock.test
+++ b/tests/clock.test
@@ -17,11 +17,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
}
if {[testConstraint win]} {
- if {[catch {package require registry 1.1}]
- && [catch {load {} Registry}]
- && [catch {
+ if {[catch {
::tcltest::loadTestedCommands
- load $::reglib Registry
+ package require registry
}]} {
namespace eval ::tcl::clock {variable NoRegistry {}}
}
@@ -35895,6 +35893,39 @@ test clock-38.1 {regression - convertUTCToLocalViaC - east of Greenwich} \
} \
-result {01:00:00}
+test clock-38.2 {make sure TZ is not cached after unset} \
+ -setup {
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ unset env(TZ)
+ }
+ if { [info exists env(TCL_TZ)] } {
+ set oldTCLTZ $env(TCL_TZ)
+ unset env(TCL_TZ)
+ }
+ } \
+ -body {
+ set t1 [clock format 0]
+ # a time zone that is unlikely to anywhere
+ set env(TZ) "+04:20"
+ set t2 [clock format 0]
+ unset env(TZ)
+ set t3 [clock format 0]
+ expr {$t1 eq $t3 && $t1 ne $t2}
+ } \
+ -cleanup {
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ unset oldTZ
+ }
+ if { [info exists oldTclTZ] } {
+ set env(TCL_TZ) $oldTclTZ
+ unset oldTclTZ
+ }
+ } \
+ -result 1
+
+
test clock-39.1 {regression - synonym timezones} {
clock format 0 -format {%H:%M:%S} -timezone :US/Eastern
} {19:00:00}
@@ -36517,6 +36548,154 @@ test clock-56.3 {use of zoneinfo, version 2, Y2038 compliance} {*}{
-result {2040-07-01 00:00:00 PDT}
}
+test clock-56.4 {Bug 3470928} {*}{
+ -setup {
+ clock format [clock seconds]
+ set tzdir [makeDirectory zoneinfo]
+ set tzdir2 [makeDirectory Test $tzdir]
+ set tzfile [makeFile {} Windhoek $tzdir2]
+ set f [open $tzfile wb]
+ puts -nonewline $f [binary format c* {
+ 0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x06 0x00 0x00
+ 0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x5c 0x00 0x00 0x00
+ 0x06 0x00 0x00 0x00 0x13 0x82 0x46 0xcf 0x68 0xcc 0xae 0x8c 0x80
+ 0xcd 0x9e 0x6f 0x70 0x26 0x06 0xa7 0xe0 0x2d 0x9d 0xea 0xe0 0x2e
+ 0x69 0x1c 0x10 0x2f 0x7d 0xe9 0x00 0x30 0x48 0xfe 0x10 0x31 0x67
+ 0x05 0x80 0x32 0x28 0xe0 0x10 0x33 0x46 0xe7 0x80 0x34 0x11 0xfc
+ 0x90 0x35 0x26 0xc9 0x80 0x35 0xf1 0xde 0x90 0x37 0x06 0xab 0x80
+ 0x37 0xd1 0xc0 0x90 0x38 0xe6 0x8d 0x80 0x39 0xb1 0xa2 0x90 0x3a
+ 0xc6 0x6f 0x80 0x3b 0x91 0x84 0x90 0x3c 0xaf 0x8c 0x00 0x3d 0x71
+ 0x66 0x90 0x3e 0x8f 0x6e 0x00 0x3f 0x5a 0x83 0x10 0x40 0x6f 0x50
+ 0x00 0x41 0x3a 0x65 0x10 0x42 0x4f 0x32 0x00 0x43 0x1a 0x47 0x10
+ 0x44 0x2f 0x14 0x00 0x44 0xfa 0x29 0x10 0x46 0x0e 0xf6 0x00 0x46
+ 0xda 0x0b 0x10 0x47 0xf8 0x12 0x80 0x48 0xc3 0x27 0x90 0x49 0xd7
+ 0xf4 0x80 0x4a 0xa3 0x09 0x90 0x4b 0xb7 0xd6 0x80 0x4c 0x82 0xeb
+ 0x90 0x4d 0x97 0xb8 0x80 0x4e 0x62 0xcd 0x90 0x4f 0x77 0x9a 0x80
+ 0x50 0x42 0xaf 0x90 0x51 0x60 0xb7 0x00 0x52 0x22 0x91 0x90 0x53
+ 0x40 0x99 0x00 0x54 0x0b 0xae 0x10 0x55 0x20 0x7b 0x00 0x55 0xeb
+ 0x90 0x10 0x57 0x00 0x5d 0x00 0x57 0xcb 0x72 0x10 0x58 0xe0 0x3f
+ 0x00 0x59 0xab 0x54 0x10 0x5a 0xc0 0x21 0x00 0x5b 0x8b 0x36 0x10
+ 0x5c 0xa9 0x3d 0x80 0x5d 0x6b 0x18 0x10 0x5e 0x89 0x1f 0x80 0x5f
+ 0x54 0x34 0x90 0x60 0x69 0x01 0x80 0x61 0x34 0x16 0x90 0x62 0x48
+ 0xe3 0x80 0x63 0x13 0xf8 0x90 0x64 0x28 0xc5 0x80 0x64 0xf3 0xda
+ 0x90 0x66 0x11 0xe2 0x00 0x66 0xd3 0xbc 0x90 0x67 0xf1 0xc4 0x00
+ 0x68 0xbc 0xd9 0x10 0x69 0xd1 0xa6 0x00 0x6a 0x9c 0xbb 0x10 0x6b
+ 0xb1 0x88 0x00 0x6c 0x7c 0x9d 0x10 0x6d 0x91 0x6a 0x00 0x6e 0x5c
+ 0x7f 0x10 0x6f 0x71 0x4c 0x00 0x70 0x3c 0x61 0x10 0x71 0x5a 0x68
+ 0x80 0x72 0x1c 0x43 0x10 0x73 0x3a 0x4a 0x80 0x74 0x05 0x5f 0x90
+ 0x75 0x1a 0x2c 0x80 0x75 0xe5 0x41 0x90 0x76 0xfa 0x0e 0x80 0x77
+ 0xc5 0x23 0x90 0x78 0xd9 0xf0 0x80 0x79 0xa5 0x05 0x90 0x7a 0xb9
+ 0xd2 0x80 0x7b 0x84 0xe7 0x90 0x7c 0xa2 0xef 0x00 0x7d 0x6e 0x04
+ 0x10 0x7e 0x82 0xd1 0x00 0x7f 0x4d 0xe6 0x10 0x01 0x02 0x01 0x03
+ 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
+ 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
+ 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
+ 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
+ 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
+ 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
+ 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x00 0x00 0x15
+ 0x18 0x00 0x00 0x00 0x00 0x1c 0x20 0x00 0x05 0x00 0x00 0x2a 0x30
+ 0x01 0x05 0x00 0x00 0x1c 0x20 0x00 0x0a 0x00 0x00 0x1c 0x20 0x01
+ 0x0e 0x00 0x00 0x0e 0x10 0x00 0x01 0x53 0x57 0x41 0x54 0x00 0x53
+ 0x41 0x53 0x54 0x00 0x43 0x41 0x54 0x00 0x57 0x41 0x53 0x54 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x54
+ 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x07 0x00 0x00 0x00
+ 0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x5d 0x00 0x00 0x00 0x07
+ 0x00 0x00 0x00 0x17 0xff 0xff 0xff 0xff 0x6d 0x7b 0x4b 0x78 0xff
+ 0xff 0xff 0xff 0x82 0x46 0xcf 0x68 0xff 0xff 0xff 0xff 0xcc 0xae
+ 0x8c 0x80 0xff 0xff 0xff 0xff 0xcd 0x9e 0x6f 0x70 0x00 0x00 0x00
+ 0x00 0x26 0x06 0xa7 0xe0 0x00 0x00 0x00 0x00 0x2d 0x9d 0xea 0xe0
+ 0x00 0x00 0x00 0x00 0x2e 0x69 0x1c 0x10 0x00 0x00 0x00 0x00 0x2f
+ 0x7d 0xe9 0x00 0x00 0x00 0x00 0x00 0x30 0x48 0xfe 0x10 0x00 0x00
+ 0x00 0x00 0x31 0x67 0x05 0x80 0x00 0x00 0x00 0x00 0x32 0x28 0xe0
+ 0x10 0x00 0x00 0x00 0x00 0x33 0x46 0xe7 0x80 0x00 0x00 0x00 0x00
+ 0x34 0x11 0xfc 0x90 0x00 0x00 0x00 0x00 0x35 0x26 0xc9 0x80 0x00
+ 0x00 0x00 0x00 0x35 0xf1 0xde 0x90 0x00 0x00 0x00 0x00 0x37 0x06
+ 0xab 0x80 0x00 0x00 0x00 0x00 0x37 0xd1 0xc0 0x90 0x00 0x00 0x00
+ 0x00 0x38 0xe6 0x8d 0x80 0x00 0x00 0x00 0x00 0x39 0xb1 0xa2 0x90
+ 0x00 0x00 0x00 0x00 0x3a 0xc6 0x6f 0x80 0x00 0x00 0x00 0x00 0x3b
+ 0x91 0x84 0x90 0x00 0x00 0x00 0x00 0x3c 0xaf 0x8c 0x00 0x00 0x00
+ 0x00 0x00 0x3d 0x71 0x66 0x90 0x00 0x00 0x00 0x00 0x3e 0x8f 0x6e
+ 0x00 0x00 0x00 0x00 0x00 0x3f 0x5a 0x83 0x10 0x00 0x00 0x00 0x00
+ 0x40 0x6f 0x50 0x00 0x00 0x00 0x00 0x00 0x41 0x3a 0x65 0x10 0x00
+ 0x00 0x00 0x00 0x42 0x4f 0x32 0x00 0x00 0x00 0x00 0x00 0x43 0x1a
+ 0x47 0x10 0x00 0x00 0x00 0x00 0x44 0x2f 0x14 0x00 0x00 0x00 0x00
+ 0x00 0x44 0xfa 0x29 0x10 0x00 0x00 0x00 0x00 0x46 0x0e 0xf6 0x00
+ 0x00 0x00 0x00 0x00 0x46 0xda 0x0b 0x10 0x00 0x00 0x00 0x00 0x47
+ 0xf8 0x12 0x80 0x00 0x00 0x00 0x00 0x48 0xc3 0x27 0x90 0x00 0x00
+ 0x00 0x00 0x49 0xd7 0xf4 0x80 0x00 0x00 0x00 0x00 0x4a 0xa3 0x09
+ 0x90 0x00 0x00 0x00 0x00 0x4b 0xb7 0xd6 0x80 0x00 0x00 0x00 0x00
+ 0x4c 0x82 0xeb 0x90 0x00 0x00 0x00 0x00 0x4d 0x97 0xb8 0x80 0x00
+ 0x00 0x00 0x00 0x4e 0x62 0xcd 0x90 0x00 0x00 0x00 0x00 0x4f 0x77
+ 0x9a 0x80 0x00 0x00 0x00 0x00 0x50 0x42 0xaf 0x90 0x00 0x00 0x00
+ 0x00 0x51 0x60 0xb7 0x00 0x00 0x00 0x00 0x00 0x52 0x22 0x91 0x90
+ 0x00 0x00 0x00 0x00 0x53 0x40 0x99 0x00 0x00 0x00 0x00 0x00 0x54
+ 0x0b 0xae 0x10 0x00 0x00 0x00 0x00 0x55 0x20 0x7b 0x00 0x00 0x00
+ 0x00 0x00 0x55 0xeb 0x90 0x10 0x00 0x00 0x00 0x00 0x57 0x00 0x5d
+ 0x00 0x00 0x00 0x00 0x00 0x57 0xcb 0x72 0x10 0x00 0x00 0x00 0x00
+ 0x58 0xe0 0x3f 0x00 0x00 0x00 0x00 0x00 0x59 0xab 0x54 0x10 0x00
+ 0x00 0x00 0x00 0x5a 0xc0 0x21 0x00 0x00 0x00 0x00 0x00 0x5b 0x8b
+ 0x36 0x10 0x00 0x00 0x00 0x00 0x5c 0xa9 0x3d 0x80 0x00 0x00 0x00
+ 0x00 0x5d 0x6b 0x18 0x10 0x00 0x00 0x00 0x00 0x5e 0x89 0x1f 0x80
+ 0x00 0x00 0x00 0x00 0x5f 0x54 0x34 0x90 0x00 0x00 0x00 0x00 0x60
+ 0x69 0x01 0x80 0x00 0x00 0x00 0x00 0x61 0x34 0x16 0x90 0x00 0x00
+ 0x00 0x00 0x62 0x48 0xe3 0x80 0x00 0x00 0x00 0x00 0x63 0x13 0xf8
+ 0x90 0x00 0x00 0x00 0x00 0x64 0x28 0xc5 0x80 0x00 0x00 0x00 0x00
+ 0x64 0xf3 0xda 0x90 0x00 0x00 0x00 0x00 0x66 0x11 0xe2 0x00 0x00
+ 0x00 0x00 0x00 0x66 0xd3 0xbc 0x90 0x00 0x00 0x00 0x00 0x67 0xf1
+ 0xc4 0x00 0x00 0x00 0x00 0x00 0x68 0xbc 0xd9 0x10 0x00 0x00 0x00
+ 0x00 0x69 0xd1 0xa6 0x00 0x00 0x00 0x00 0x00 0x6a 0x9c 0xbb 0x10
+ 0x00 0x00 0x00 0x00 0x6b 0xb1 0x88 0x00 0x00 0x00 0x00 0x00 0x6c
+ 0x7c 0x9d 0x10 0x00 0x00 0x00 0x00 0x6d 0x91 0x6a 0x00 0x00 0x00
+ 0x00 0x00 0x6e 0x5c 0x7f 0x10 0x00 0x00 0x00 0x00 0x6f 0x71 0x4c
+ 0x00 0x00 0x00 0x00 0x00 0x70 0x3c 0x61 0x10 0x00 0x00 0x00 0x00
+ 0x71 0x5a 0x68 0x80 0x00 0x00 0x00 0x00 0x72 0x1c 0x43 0x10 0x00
+ 0x00 0x00 0x00 0x73 0x3a 0x4a 0x80 0x00 0x00 0x00 0x00 0x74 0x05
+ 0x5f 0x90 0x00 0x00 0x00 0x00 0x75 0x1a 0x2c 0x80 0x00 0x00 0x00
+ 0x00 0x75 0xe5 0x41 0x90 0x00 0x00 0x00 0x00 0x76 0xfa 0x0e 0x80
+ 0x00 0x00 0x00 0x00 0x77 0xc5 0x23 0x90 0x00 0x00 0x00 0x00 0x78
+ 0xd9 0xf0 0x80 0x00 0x00 0x00 0x00 0x79 0xa5 0x05 0x90 0x00 0x00
+ 0x00 0x00 0x7a 0xb9 0xd2 0x80 0x00 0x00 0x00 0x00 0x7b 0x84 0xe7
+ 0x90 0x00 0x00 0x00 0x00 0x7c 0xa2 0xef 0x00 0x00 0x00 0x00 0x00
+ 0x7d 0x6e 0x04 0x10 0x00 0x00 0x00 0x00 0x7e 0x82 0xd1 0x00 0x00
+ 0x00 0x00 0x00 0x7f 0x4d 0xe6 0x10 0x01 0x02 0x03 0x02 0x04 0x06
+ 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
+ 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
+ 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
+ 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
+ 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
+ 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
+ 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x00 0x00 0x10 0x08
+ 0x00 0x00 0x00 0x00 0x15 0x18 0x00 0x04 0x00 0x00 0x1c 0x20 0x00
+ 0x09 0x00 0x00 0x2a 0x30 0x01 0x09 0x00 0x00 0x1c 0x20 0x00 0x0e
+ 0x00 0x00 0x1c 0x20 0x01 0x12 0x00 0x00 0x0e 0x10 0x00 0x05 0x4c
+ 0x4d 0x54 0x00 0x53 0x57 0x41 0x54 0x00 0x53 0x41 0x53 0x54 0x00
+ 0x43 0x41 0x54 0x00 0x57 0x41 0x53 0x54 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a 0x57 0x41
+ 0x54 0x2d 0x31 0x57 0x41 0x53 0x54 0x2c 0x4d 0x39 0x2e 0x31 0x2e
+ 0x30 0x2c 0x4d 0x34 0x2e 0x31 0x2e 0x30 0x0a
+ }]
+ close $f
+ set ::tcl::clock::ZoneinfoPaths \
+ [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
+ ::tcl::clock::ClearCaches
+ }
+ -body {
+ clock format 1326054606 -timezone :Test/Windhoek
+ }
+ -cleanup {
+ set ::tcl::clock::ZoneinfoPaths \
+ [lrange $::tcl::clock::ZoneinfoPaths 1 end]
+ ::tcl::clock::ClearCaches
+ removeFile Windhoek $tzdir2
+ removeDirectory Test $tzdir
+ removeDirectory zoneinfo
+ }
+ -result {Sun Jan 08 22:30:06 WAST 2012}
+}
+
test clock-57.1 {clock scan - abbreviated options} {
clock scan 1970-01-01 -f %Y-%m-%d -g true
} 0
@@ -36748,6 +36927,15 @@ test clock-67.1 {clock format, %% with a letter following [Bug 2819334]} {
clock format [clock seconds] -format %%r
} %r
+test clock-67.2 {Bug d19a30db57} -body {
+ # error, not segfault
+ tcl::clock::GetJulianDayFromEraYearMonthDay {} 2361222
+} -returnCodes error -match glob -result *
+test clock-67.3 {Bug d19a30db57} -body {
+ # error, not segfault
+ tcl::clock::GetJulianDayFromEraYearWeekDay {} 2361222
+} -returnCodes error -match glob -result *
+
# cleanup
namespace delete ::testClock
diff --git a/tests/cmdAH.test b/tests/cmdAH.test
index 291df8d..04a86fa 100644
--- a/tests/cmdAH.test
+++ b/tests/cmdAH.test
@@ -15,6 +15,9 @@ if {"::tcltest" ni [namespace children]} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testchmod [llength [info commands testchmod]]
testConstraint testsetplatform [llength [info commands testsetplatform]]
testConstraint testvolumetype [llength [info commands testvolumetype]]
@@ -67,6 +70,12 @@ test cmdAH-1.2 {Tcl_CatchObjCmd, errors} {
test cmdAH-1.3 {Tcl_CatchObjCmd, errors} -returnCodes error -body {
catch foo bar baz spaz
} -result {wrong # args: should be "catch script ?resultVarName? ?optionVarName?"}
+test cmdAH-1.4 {Bug 3595576} {
+ catch {catch {} -> noSuchNs::var}
+} 1
+test cmdAH-1.5 {Bug 3595576} {
+ catch {catch error -> noSuchNs::var}
+} 1
test cmdAH-2.1 {Tcl_CdObjCmd} -returnCodes error -body {
cd foo bar
@@ -132,6 +141,9 @@ test cmdAH-2.6.2 {cd} -constraints {unix nonPortable} -setup {
} -cleanup {
cd $dir
} -result {/}
+test cmdAH-2.6.3 {Tcl_CdObjCmd, bug #3118489} -returnCodes error -body {
+ cd .\0
+} -result "couldn't change working directory to \".\0\": no such file or directory"
test cmdAH-2.7 {Tcl_ConcatObjCmd} {
concat
} {}
@@ -945,6 +957,19 @@ test cmdAH-19.11 {Tcl_FileObjCmd: exists} -constraints {unix notRoot} -setup {
removeFile /tmp/tcl.foo.dir/file
removeDirectory /tmp/tcl.foo.dir
} -result 0
+test cmdAH-19.12 {Bug 3608360: [file exists] mustn't do globbing} -setup {
+ set newdirfile [makeDirectory newdir.file]
+ set cwd [pwd]
+ cd $newdirfile
+ # Content of file is totally unimportant; name is *not*
+ set innocentBystander [makeFile "abc" [file join $newdirfile foo.bar]]
+} -body {
+ list [file exists foo.bar] [file exists *.bar]
+} -cleanup {
+ cd $cwd
+ removeFile $innocentBystander
+ removeDirectory $newdirfile
+} -result {1 0}
# Stat related commands
diff --git a/tests/cmdIL.test b/tests/cmdIL.test
index 4b1002a..23a5f96 100644
--- a/tests/cmdIL.test
+++ b/tests/cmdIL.test
@@ -13,6 +13,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
# Used for constraining memory leak tests
testConstraint memory [llength [info commands memory]]
testConstraint testobj [llength [info commands testobj]]
@@ -414,6 +417,15 @@ test cmdIL-4.34 {SortCompare procedure, -ascii option with -nocase option} {
test cmdIL-4.35 {SortCompare procedure, -ascii option with -nocase option} {
lsort -ascii -nocase {d E c B a D35 d300 100 20}
} {100 20 a B c d d300 D35 E}
+test cmdIL-4.36 {SortCompare procedure, UTF-8 with -nocase option} {
+ scan [lsort -ascii -nocase [list \u101 \u100]] %c%c%c
+} {257 32 256}
+test cmdIL-4.37 {SortCompare procedure, UTF-8 with -nocase option} {
+ scan [lsort -ascii -nocase [list a\u0000a a]] %c%c%c%c%c
+} {97 32 97 0 97}
+test cmdIL-4.38 {SortCompare procedure, UTF-8 with -nocase option} {
+ scan [lsort -ascii -nocase [list a a\u0000a]] %c%c%c%c%c
+} {97 32 97 0 97}
test cmdIL-5.1 {lsort with list style index} {
lsort -ascii -decreasing -index {0 1} {
@@ -714,6 +726,16 @@ test cmdIL-7.8 {lreverse command - shared intrep [Bug 1675044]} -setup {
rename K {}
} -result 1
+# This belongs in info test, but adding tests there breaks tests
+# that compute source file line numbers.
+test info-20.6 {Bug 3587651} -setup {
+ namespace eval my {namespace eval tcl {namespace eval mathfunc {
+ proc demo x {return 42}
+ }}}} -body { namespace eval my {expr {"demo" in [info functions]}}} -cleanup {
+ namespace delete my
+} -result 1
+
+
# cleanup
::tcltest::cleanupTests
return
diff --git a/tests/cmdInfo.test b/tests/cmdInfo.test
index 86aa6e1..0a587e8 100644
--- a/tests/cmdInfo.test
+++ b/tests/cmdInfo.test
@@ -13,10 +13,11 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest 2
- namespace import -force ::tcltest::*
-}
+package require tcltest 2
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
testConstraint testcmdinfo [llength [info commands testcmdinfo]]
testConstraint testcmdtoken [llength [info commands testcmdtoken]]
@@ -98,7 +99,7 @@ test cmdinfo-6.1 {Names for commands created when outside namespaces} \
# cleanup
catch {namespace delete cmdInfoNs1::cmdInfoNs2 cmdInfoNs1}
catch {rename x1 ""}
-::tcltest::cleanupTests
+cleanupTests
return
# Local Variables:
diff --git a/tests/compExpr-old.test b/tests/compExpr-old.test
index bb19151..bae26a0 100644
--- a/tests/compExpr-old.test
+++ b/tests/compExpr-old.test
@@ -17,6 +17,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} {
testConstraint testmathfunctions 0
} else {
diff --git a/tests/compExpr.test b/tests/compExpr.test
index 8e27f1f..14c875d 100644
--- a/tests/compExpr.test
+++ b/tests/compExpr.test
@@ -13,6 +13,9 @@ if {"::tcltest" ni [namespace children]} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} {
testConstraint testmathfunctions 0
} else {
diff --git a/tests/compile.test b/tests/compile.test
index d6048be..2852bf2 100644
--- a/tests/compile.test
+++ b/tests/compile.test
@@ -14,6 +14,9 @@
package require tcltest 2
namespace import -force ::tcltest::*
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint exec [llength [info commands exec]]
testConstraint memory [llength [info commands memory]]
testConstraint testevalex [llength [info commands testevalex]]
@@ -164,6 +167,36 @@ test compile-3.6 {TclCompileCatchCmd: error in storing result [Bug 3098302]} {*}
-cleanup {namespace delete catchtest}
}
+test compile-3.7 {TclCompileCatchCmd: error in storing options [Bug 3098302]} {*}{
+ -setup {
+ namespace eval catchtest {
+ variable options1 {}
+ }
+ trace add variable catchtest::options1 write catchtest::failtrace
+ proc catchtest::failtrace {n1 n2 op} {
+ return -code error "trace on $n1 fails by request"
+ }
+ }
+ -body {
+ proc catchtest::x {} {
+ variable options1
+ set count 0
+ for {set i 0} {$i < 10} {incr i} {
+ set status2 [catch {
+ set status1 [catch {
+ return -code error -level 0 "original failure"
+ } result1 options1]
+ } result2 options2]
+ incr count
+ }
+ list $count $result2
+ }
+ catchtest::x
+ }
+ -result {10 {can't set "options1": trace on options1 fails by request}}
+ -cleanup {namespace delete catchtest}
+}
+
test compile-4.1 {TclCompileForCmd: command substituted test expression} {
set i 0
set j 0
@@ -704,6 +737,76 @@ test compile-18.19 {disassembler - basics} -setup {
} -cleanup {
foo destroy
} -match glob -result *
+
+test compile-19.0 {Bug 3614102: reset stack housekeeping} -body {
+ # This will panic in a --enable-symbols=compile build, unless bug is fixed.
+ apply {{} {list [if 1]}}
+} -returnCodes error -match glob -result *
+
+test compile-20.1 {ensure there are no infinite loops in optimizing} {
+ tcl::unsupported::disassemble script {
+ while 1 {
+ return -code continue -level 0
+ }
+ }
+ return
+} {}
+test compile-20.2 {ensure there are no infinite loops in optimizing} {
+ tcl::unsupported::disassemble script {
+ while 1 {
+ while 1 {
+ return -code break -level 0
+ }
+ }
+ }
+ return
+} {}
+
+test compile-21.1 {stack balance management} {
+ apply {{} {
+ set result {}
+ while 1 {
+ lappend result a
+ lappend result [list b [break]]
+ lappend result c
+ }
+ return $result
+ }}
+} a
+test compile-21.2 {stack balance management} {
+ apply {{} {
+ set result {}
+ while {[incr i] <= 10} {
+ lappend result $i
+ lappend result [list b [continue] c]
+ lappend result c
+ }
+ return $result
+ }}
+} {1 2 3 4 5 6 7 8 9 10}
+test compile-21.3 {stack balance management} {
+ apply {args {
+ set result {}
+ while 1 {
+ lappend result a
+ lappend result [concat {*}$args [break]]
+ lappend result c
+ }
+ return $result
+ }} P Q R S T
+} a
+test compile-21.4 {stack balance management} {
+ apply {args {
+ set result {}
+ while {[incr i] <= 10} {
+ lappend result $i
+ lappend result [concat {*}$args [continue] c]
+ lappend result c
+ }
+ return $result
+ }} P Q R S T
+} {1 2 3 4 5 6 7 8 9 10}
+
# TODO sometime - check that bytecode from tbcload is *not* disassembled.
# cleanup
diff --git a/tests/coroutine.test b/tests/coroutine.test
index 7d5169b..05b58c9 100644
--- a/tests/coroutine.test
+++ b/tests/coroutine.test
@@ -1,4 +1,4 @@
-# Commands covered: coroutine, yield, [info coroutine]
+# Commands covered: coroutine, yield, yieldto, [info coroutine]
#
# This file contains a collection of tests for experimental commands that are
# found in ::tcl::unsupported. The tests will migrate to normal test files
@@ -14,6 +14,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testnrelevels [llength [info commands testnrelevels]]
testConstraint memory [llength [info commands memory]]
@@ -339,6 +342,9 @@ test coroutine-3.6 {info frame, bug #2910094} -setup {
rename stack {}
rename a {}
} -result {}
+test coroutine-3.7 {bug 0b874c344d} {
+ dict get [coroutine X coroutine Y info frame 0] cmd
+} {coroutine X coroutine Y info frame 0}
test coroutine-4.1 {bug #2093188} -setup {
proc foo {} {
@@ -436,7 +442,7 @@ test coroutine-4.5 {bug #2724403} -constraints {memory} \
} -result 0
test coroutine-4.6 {compile context, bug #3282869} -setup {
- unset ::x
+ unset -nocomplain ::x
proc f x {
coroutine D eval {yield X$x;yield Y}
}
@@ -557,12 +563,25 @@ test coroutine-6.3 {coroutine nargs} -body {
} -cleanup {
rename a {}
} -returnCodes error -result {wrong # args: should be "a ?arg?"}
-test coroutine-6.4 {unsupported: multi-argument yield} -body {
+
+test coroutine-7.1 {yieldto} -body {
+ coroutine c apply {{} {
+ yield
+ yieldto return -level 0 -code 1 quux
+ return quuy
+ }}
+ set res [list [catch c msg] $msg]
+ lappend res [catch c msg] $msg
+ lappend res [catch c msg] $msg
+} -cleanup {
+ unset res
+} -result [list 1 quux 0 quuy 1 {invalid command name "c"}]
+test coroutine-7.2 {multi-argument yielding with yieldto} -body {
proc corobody {} {
set a 1
while 1 {
set a [yield $a]
- set a [::tcl::unsupported::yieldm $a]
+ set a [yieldto return -level 0 $a]
lappend a [llength $a]
}
}
@@ -573,19 +592,140 @@ test coroutine-6.4 {unsupported: multi-argument yield} -body {
} -cleanup {
rename corobody {}
} -result {x {y z 2} \{p {\{q r 2} {} 0 {} ok {}}
-
-test coroutine-7.1 {yieldTo} -body {
- coroutine c apply {{} {
- yield
- tcl::unsupported::yieldTo return -level 0 -code 1 quux
- return quuy
- }}
- set res [list [catch c msg] $msg]
- lappend res [catch c msg] $msg
- lappend res [catch c msg] $msg
+test coroutine-7.3 {yielding between coroutines} -body {
+ proc juggler {target {value ""}} {
+ if {$value eq ""} {
+ set value [yield [info coroutine]]
+ }
+ while {[llength $value]} {
+ lappend ::result $value [info coroutine]
+ set value [lrange $value 0 end-1]
+ lassign [yieldto $target $value] value
+ }
+ # Clear nested collection of coroutines
+ catch $target
+ }
+ set result ""
+ coroutine j1 juggler [coroutine j2 juggler [coroutine j3 juggler j1]]\
+ {a b c d e}
+ list $result [info command j1] [info command j2] [info command j3]
} -cleanup {
- unset res
-} -result [list 1 quux 0 quuy 1 {invalid command name "c"}]
+ catch {rename juggler ""}
+} -result {{{a b c d e} ::j1 {a b c d} ::j2 {a b c} ::j3 {a b} ::j1 a ::j2} {} {} {}}
+test coroutine-7.4 {Bug 8ff0cb9fe1} -setup {
+ proc foo {a b} {catch yield; return 1}
+} -cleanup {
+ rename foo {}
+} -body {
+ coroutine demo lsort -command foo {a b}
+} -result {b a}
+test coroutine-7.5 {return codes} {
+ set result {}
+ foreach code {0 1 2 3 4 5} {
+ lappend result [catch {coroutine demo return -level 0 -code $code}]
+ }
+ set result
+} {0 1 2 3 4 5}
+test coroutine-7.6 {Early yield crashes} {
+ proc foo args {}
+ trace add execution foo enter {catch yield}
+ coroutine demo foo
+ rename foo {}
+} {}
+test coroutine-7.7 {Bug 2486550} -setup {
+ interp hide {} yield
+} -body {
+ coroutine demo interp invokehidden {} yield ok
+} -cleanup {
+ demo
+ interp expose {} yield
+} -result ok
+test coroutine-7.8 {yieldto context nuke: Bug a90d9331bc} -setup {
+ namespace eval cotest {}
+ set ::result ""
+} -body {
+ proc cotest::body {} {
+ lappend ::result a
+ yield OUT
+ lappend ::result b
+ yieldto ::return -level 0 123
+ lappend ::result c
+ return
+ }
+ lappend ::result [coroutine cotest cotest::body]
+ namespace delete cotest
+ namespace eval cotest {}
+ lappend ::result [cotest]
+ cotest
+ return $result
+} -returnCodes error -cleanup {
+ catch {namespace delete ::cotest}
+ catch {rename cotest ""}
+} -result {yieldto called in deleted namespace}
+test coroutine-7.9 {yieldto context nuke: Bug a90d9331bc} -setup {
+ namespace eval cotest {}
+ set ::result ""
+} -body {
+ proc cotest::body {} {
+ set y ::yieldto
+ lappend ::result a
+ yield OUT
+ lappend ::result b
+ $y ::return -level 0 123
+ lappend ::result c
+ return
+ }
+ lappend ::result [coroutine cotest cotest::body]
+ namespace delete cotest
+ namespace eval cotest {}
+ lappend ::result [cotest]
+ cotest
+ return $result
+} -returnCodes error -cleanup {
+ catch {namespace delete ::cotest}
+ catch {rename cotest ""}
+} -result {yieldto called in deleted namespace}
+test coroutine-7.10 {yieldto context nuke: Bug a90d9331bc} -setup {
+ namespace eval cotest {}
+ set ::result ""
+} -body {
+ proc cotest::body {} {
+ lappend ::result a
+ yield OUT
+ lappend ::result b
+ yieldto ::return -level 0 -cotest [namespace delete ::cotest] 123
+ lappend ::result c
+ return
+ }
+ lappend ::result [coroutine cotest cotest::body]
+ lappend ::result [cotest]
+ cotest
+ return $result
+} -returnCodes error -cleanup {
+ catch {namespace delete ::cotest}
+ catch {rename cotest ""}
+} -result {yieldto called in deleted namespace}
+test coroutine-7.11 {yieldto context nuke: Bug a90d9331bc} -setup {
+ namespace eval cotest {}
+ set ::result ""
+} -body {
+ proc cotest::body {} {
+ set y ::yieldto
+ lappend ::result a
+ yield OUT
+ lappend ::result b
+ $y ::return -level 0 -cotest [namespace delete ::cotest] 123
+ lappend ::result c
+ return
+ }
+ lappend ::result [coroutine cotest cotest::body]
+ lappend ::result [cotest]
+ cotest
+ return $result
+} -returnCodes error -cleanup {
+ catch {namespace delete ::cotest}
+ catch {rename cotest ""}
+} -result {yieldto called in deleted namespace}
# cleanup
diff --git a/tests/dcall.test b/tests/dcall.test
index 8977c31..41dd777 100644
--- a/tests/dcall.test
+++ b/tests/dcall.test
@@ -11,10 +11,11 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest
- namespace import -force ::tcltest::*
-}
+package require tcltest 2
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
testConstraint testdcall [llength [info commands testdcall]]
@@ -38,5 +39,5 @@ test dcall-1.6 {deletion callbacks} testdcall {
} {}
# cleanup
-::tcltest::cleanupTests
+cleanupTests
return
diff --git a/tests/dict.test b/tests/dict.test
index d80a11f..a583de8 100644
--- a/tests/dict.test
+++ b/tests/dict.test
@@ -78,6 +78,24 @@ test dict-2.7 {dict create command - #-quoting in string rep} {
test dict-2.8 {dict create command - #-quoting in string rep} -body {
dict create #a x #b x
} -match glob -result {{#?} x #? x}
+test dict-2.9 {dict create command: compilation} {
+ apply {{} {dict create [format a] b}}
+} {a b}
+test dict-2.10 {dict create command: compilation} {
+ apply {{} {dict create [format a] b c d}}
+} {a b c d}
+test dict-2.11 {dict create command: compilation} {
+ apply {{} {dict create [format a] b c d a x}}
+} {a x c d}
+test dict-2.12 {dict create command: non-compilation} {
+ dict create [format a] b
+} {a b}
+test dict-2.13 {dict create command: non-compilation} {
+ dict create [format a] b c d
+} {a b c d}
+test dict-2.14 {dict create command: non-compilation} {
+ dict create [format a] b c d a x
+} {a x c d}
test dict-3.1 {dict get command} {dict get {a b} a} b
test dict-3.2 {dict get command} {dict get {a b c d} a} b
@@ -214,9 +232,7 @@ test dict-9.2 {dict exists command} {dict exists {a b} b} 0
test dict-9.3 {dict exists command} {dict exists {a {b c}} a b} 1
test dict-9.4 {dict exists command} {dict exists {a {b c}} a c} 0
test dict-9.5 {dict exists command} {dict exists {a {b c}} b c} 0
-test dict-9.6 {dict exists command} -returnCodes error -body {
- dict exists {a {b c d}} a c
-} -result {missing value to go with key}
+test dict-9.6 {dict exists command} {dict exists {a {b c d}} a c} 0
test dict-9.7 {dict exists command} -returnCodes error -body {
dict exists
} -result {wrong # args: should be "dict exists dictionary key ?key ...?"}
@@ -652,6 +668,24 @@ test dict-14.20 {dict for stack space compilation: bug 1903325} {
concat "c=$y,$args"
}} {} 1 2 3
} {c=1,2 3}
+test dict-14.21 {compiled dict for and break} {
+ apply {{} {
+ dict for {a b} {c d e f} {
+ lappend result $a,$b
+ break
+ }
+ return $result
+ }}
+} c,d
+test dict-14.22 {dict for and exception range depths: Bug 3614382} {
+ apply {{} {
+ dict for {a b} {c d} {
+ dict for {e f} {g h} {
+ return 5
+ }
+ }
+ }}
+} 5
# There's probably a lot more tests to add here. Really ought to use a
# coverage tool for this job...
@@ -783,6 +817,55 @@ test dict-16.9 {dict unset command: write failure} -setup {
} -returnCodes error -cleanup {
unset dictVar
} -result {can't set "dictVar": variable is array}
+# Now test with an LVT present (i.e., the bytecoded version).
+test dict-16.10 {dict unset command} -body {
+ apply {{} {
+ set dictVar {a b c d}
+ dict unset dictVar a
+ }}
+} -result {c d}
+test dict-16.11 {dict unset command} -body {
+ apply {{} {
+ set dictVar {a b c d}
+ dict unset dictVar c
+ }}
+} -result {a b}
+test dict-16.12 {dict unset command} -body {
+ apply {{} {
+ set dictVar {a b}
+ dict unset dictVar c
+ }}
+} -result {a b}
+test dict-16.13 {dict unset command} -body {
+ apply {{} {
+ set dictVar {a {b c d e}}
+ dict unset dictVar a b
+ }}
+} -result {a {d e}}
+test dict-16.14 {dict unset command} -returnCodes error -body {
+ apply {{} {
+ set dictVar a
+ dict unset dictVar a
+ }}
+} -result {missing value to go with key}
+test dict-16.15 {dict unset command} -returnCodes error -body {
+ apply {{} {
+ set dictVar {a b}
+ dict unset dictVar c d
+ }}
+} -result {key "c" not known in dictionary}
+test dict-16.16 {dict unset command} -body {
+ apply {{} {list [info exists dictVar] [dict unset dictVar a] [info exists dictVar]}}
+} -result {0 {} 1}
+test dict-16.17 {dict unset command} -returnCodes error -body {
+ apply {{} {dict unset dictVar}}
+} -result {wrong # args: should be "dict unset varName key ?key ...?"}
+test dict-16.18 {dict unset command: write failure} -body {
+ apply {{} {
+ set dictVar(block) {}
+ dict unset dictVar a
+ }}
+} -returnCodes error -result {can't set "dictVar": variable is array}
test dict-17.1 {dict filter command: key} -body {
set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
@@ -1113,6 +1196,36 @@ test dict-20.9 {dict merge command} {
test dict-20.10 {dict merge command} {
dict merge {a b c d e f} {a x 1 2 3 4} {a - 1 -}
} {a - c d e f 1 - 3 4}
+test dict-20.11 {dict merge command} {
+ apply {{} {dict merge}}
+} {}
+test dict-20.12 {dict merge command} {
+ apply {{} {dict merge {a b c d e f}}}
+} {a b c d e f}
+test dict-20.13 {dict merge command} -body {
+ apply {{} {dict merge {a b c d e}}}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.14 {dict merge command} {
+ apply {{} {dict merge {a b c d} {e f g h}}}
+} {a b c d e f g h}
+test dict-20.15 {dict merge command} -body {
+ apply {{} {dict merge {a b c d e} {e f g h}}}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.16 {dict merge command} -body {
+ apply {{} {dict merge {a b c d} {e f g h i}}}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.17 {dict merge command} {
+ apply {{} {dict merge {a b c d e f} {e x g h}}}
+} {a b c d e x g h}
+test dict-20.18 {dict merge command} {
+ apply {{} {dict merge {a b c d} {a x c y}}}
+} {a x c y}
+test dict-20.19 {dict merge command} {
+ apply {{} {dict merge {a b c d} {c y a x}}}
+} {a x c y}
+test dict-20.20 {dict merge command} {
+ apply {{} {dict merge {a b c d e f} {a x 1 2 3 4} {a - 1 -}}}
+} {a - c d e f 1 - 3 4}
test dict-21.1 {dict update command} -returnCodes 1 -body {
dict update
@@ -1358,6 +1471,504 @@ test dict-22.11 {dict with command: no recursive structures [Bug 1786481]} -body
} -cleanup {
unset foo t inner
} -result OK
+test dict-22.12 {dict with: compiled} {
+ apply {{} {
+ set d {a 1 b 2}
+ list [dict with d {
+ set a $b
+ unset b
+ dict set d c 3
+ list ok
+ }] $d
+ }}
+} {ok {a 2 c 3}}
+test dict-22.13 {dict with: compiled} {
+ apply {i {
+ set d($i) {a 1 b 2}
+ list [dict with d($i) {
+ set a $b
+ unset b
+ dict set d($i) c 3
+ list ok
+ }] [array get d]
+ }} e
+} {ok {e {a 2 c 3}}}
+test dict-22.14 {dict with: compiled} {
+ apply {{} {
+ set d {a 1 b 2}
+ foreach x {1 2 3} {
+ dict with d {
+ incr a $b
+ if {$x == 2} break
+ }
+ unset a b
+ }
+ list $a $b $x $d
+ }}
+} {5 2 2 {a 5 b 2}}
+test dict-22.15 {dict with: compiled} {
+ apply {i {
+ set d($i) {a 1 b 2}
+ foreach x {1 2 3} {
+ dict with d($i) {
+ incr a $b
+ if {$x == 2} break
+ }
+ unset a b
+ }
+ list $a $b $x [array get d]
+ }} e
+} {5 2 2 {e {a 5 b 2}}}
+test dict-22.16 {dict with: compiled} {
+ apply {{} {
+ set d {p {q {a 1 b 2}}}
+ dict with d p q {
+ set a $b.$a
+ }
+ return $d
+ }}
+} {p {q {a 2.1 b 2}}}
+test dict-22.17 {dict with: compiled} {
+ apply {i {
+ set d($i) {p {q {a 1 b 2}}}
+ dict with d($i) p q {
+ set a $b.$a
+ }
+ array get d
+ }} e
+} {e {p {q {a 2.1 b 2}}}}
+test dict-22.18 {dict with: compiled} {
+ set ::d {a 1 b 2}
+ apply {{} {
+ dict with ::d {
+ set a $b.$a
+ }
+ return $::d
+ }}
+} {a 2.1 b 2}
+test dict-22.19 {dict with: compiled} {
+ set ::d {p {q {r {a 1 b 2}}}}
+ apply {{} {
+ dict with ::d p q r {
+ set a $b.$a
+ }
+ return $::d
+ }}
+} {p {q {r {a 2.1 b 2}}}}
+test dict-22.20 {dict with: compiled} {
+ apply {d {
+ dict with d {
+ }
+ return $a,$b
+ }} {a 1 b 2}
+} 1,2
+test dict-22.21 {dict with: compiled} {
+ apply {d {
+ dict with d p q {
+ }
+ return $a,$b
+ }} {p {q {a 1 b 2}}}
+} 1,2
+test dict-22.22 {dict with: compiled} {
+ set ::d {a 1 b 2}
+ apply {{} {
+ dict with ::d {
+ }
+ return $a,$b
+ }}
+} 1,2
+test dict-22.23 {dict with: compiled} {
+ set ::d {p {q {a 1 b 2}}}
+ apply {{} {
+ dict with ::d p q {
+ }
+ return $a,$b
+ }}
+} 1,2
+
+proc linenumber {} {
+ dict get [info frame -1] line
+}
+test dict-23.1 {dict compilation crash: Bug 3487626} {
+ apply {{} {apply {n {
+ set e {}
+ set k {}
+ dict for {a b} {c {d {e {f g}}}} {
+ ::tcl::dict::for {h i} $b {
+ dict update i e j {
+ ::tcl::dict::update j f k {
+ return [expr {$n - [linenumber]}]
+ }
+ }
+ }
+ }
+ }} [linenumber]}}
+} 5
+test dict-23.2 {dict compilation crash: Bug 3487626} {
+ # Something isn't quite right in line number and continuation line
+ # tracking; at time of writing, this test produces 7, not 5, which
+ # indicates that the extra newlines in the non-script argument are
+ # confusing things.
+ apply {{} {apply {n {
+ set e {}
+ set k {}
+ dict for {a {
+b
+}} {c {d {e {f g}}}} {
+ ::tcl::dict::for {h {
+i
+}} ${
+b
+} {
+ dict update {
+i
+} e {
+j
+} {
+ ::tcl::dict::update {
+j
+} f k {
+ return [expr {$n - [linenumber]}]
+ }
+ }
+ }
+ }
+ }} [linenumber]}}
+} 5
+rename linenumber {}
+
+test dict-24.1 {dict map command: syntax} -returnCodes error -body {
+ dict map
+} -result {wrong # args: should be "dict map {keyVar valueVar} dictionary script"}
+test dict-24.2 {dict map command: syntax} -returnCodes error -body {
+ dict map x
+} -result {wrong # args: should be "dict map {keyVar valueVar} dictionary script"}
+test dict-24.3 {dict map command: syntax} -returnCodes error -body {
+ dict map x x
+} -result {wrong # args: should be "dict map {keyVar valueVar} dictionary script"}
+test dict-24.4 {dict map command: syntax} -returnCodes error -body {
+ dict map x x x x
+} -result {wrong # args: should be "dict map {keyVar valueVar} dictionary script"}
+test dict-24.5 {dict map command: syntax} -returnCodes error -body {
+ dict map x x x
+} -result {must have exactly two variable names}
+test dict-24.6 {dict map command: syntax} -returnCodes error -body {
+ dict map {x x x} x x
+} -result {must have exactly two variable names}
+test dict-24.7 {dict map command: syntax} -returnCodes error -body {
+ dict map "\{x" x x
+} -result {unmatched open brace in list}
+test dict-24.8 {dict map command} -setup {
+ set values {}
+ set keys {}
+} -body {
+ # This test confirms that [dict keys], [dict values] and [dict map]
+ # all traverse a dictionary in the same order.
+ set dictv {a A b B c C}
+ dict map {k v} $dictv {
+ lappend keys $k
+ lappend values $v
+ }
+ set result [expr {
+ $keys eq [dict keys $dictv] && $values eq [dict values $dictv]
+ }]
+ expr {$result ? "YES" : [list "NO" $dictv $keys $values]}
+} -cleanup {
+ unset result keys values k v dictv
+} -result YES
+test dict-24.9 {dict map command} {
+ dict map {k v} {} {
+ error "unexpected execution of 'dict map' body"
+ }
+} {}
+test dict-24.10 {dict map command: script results} -body {
+ set times 0
+ dict map {k v} {a a b b} {
+ incr times
+ continue
+ error "shouldn't get here"
+ }
+ return $times
+} -cleanup {
+ unset times k v
+} -result 2
+test dict-24.11 {dict map command: script results} -body {
+ set times 0
+ dict map {k v} {a a b b} {
+ incr times
+ break
+ error "shouldn't get here"
+ }
+ return $times
+} -cleanup {
+ unset times k v
+} -result 1
+test dict-24.12 {dict map command: script results} -body {
+ set times 0
+ list [catch {
+ dict map {k v} {a a b b} {
+ incr times
+ error test
+ }
+ } msg] $msg $times $::errorInfo
+} -cleanup {
+ unset times k v msg
+} -result {1 test 1 {test
+ while executing
+"error test"
+ ("dict map" body line 3)
+ invoked from within
+"dict map {k v} {a a b b} {
+ incr times
+ error test
+ }"}}
+test dict-24.13 {dict map command: script results} {
+ apply {{} {
+ dict map {k v} {a b} {
+ return ok,$k,$v
+ error "skipped return completely"
+ }
+ error "return didn't go far enough"
+ }}
+} ok,a,b
+test dict-24.14 {dict map command: handle representation loss} -setup {
+ set keys {}
+ set values {}
+} -body {
+ set dictVar {a b c d e f g h}
+ list [dict size [dict map {k v} $dictVar {
+ if {[llength $dictVar]} {
+ lappend keys $k
+ lappend values $v
+ return -level 0 $k
+ }
+ }]] [lsort $keys] [lsort $values]
+} -cleanup {
+ unset dictVar keys values k v
+} -result {4 {a c e g} {b d f h}}
+test dict-24.14a {dict map command: handle representation loss} -body {
+ apply {{} {
+ set dictVar {a b c d e f g h}
+ list [dict size [dict map {k v} $dictVar {
+ if {[llength $dictVar]} {
+ lappend keys $k
+ lappend values $v
+ return -level 0 $k
+ }
+ }]] [lsort $keys] [lsort $values]
+ }}
+} -result {4 {a c e g} {b d f h}}
+test dict-24.15 {dict map command: keys are unique and iterated over once only} -setup {
+ unset -nocomplain accum
+ array set accum {}
+} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict map {k v} $dictVar {
+ append accum($k) $v,
+ }
+ set result [lsort [array names accum]]
+ lappend result :
+ foreach k $result {
+ catch {lappend result $accum($k)}
+ }
+ return $result
+} -cleanup {
+ unset dictVar k v result accum
+} -result {a1 a2 b1 b2 bar foo : a, b, c, d, foo, bar,}
+test dict-24.16 {dict map command in compilation context} {
+ apply {{} {
+ set res {x x x x x x}
+ dict map {k v} {a 0 b 1 c 2 d 3 e 4 f 5} {
+ lset res $v $k
+ continue
+ }
+ return $res
+ }}
+} {a b c d e f}
+test dict-24.17 {dict map command in compilation context} {
+ # Bug 1379349 (dict for)
+ apply {{} {
+ set d [dict create a 1] ;# Dict must be unshared!
+ dict map {k v} $d {
+ dict set d $k 0 ;# Any modification will do
+ }
+ return $d
+ }}
+} {a 0}
+test dict-24.17a {dict map command in compilation context} {
+ # Bug 1379349 (dict for)
+ apply {{} {
+ set d [dict create a 1] ;# Dict must be unshared!
+ dict map {k v} $d {
+ dict set d $k 0 ;# Any modification will do
+ }
+ }}
+} {a {a 0}}
+test dict-24.18 {dict map command in compilation context} {
+ # Bug 1382528 (dict for)
+ apply {{} {
+ dict map {k v} {} {} ;# Note empty dict
+ catch { error foo } ;# Note compiled [catch]
+ }}
+} 1
+test dict-24.19 {dict map and invalid dicts: 'dict for' bug 1531184} -body {
+ di[list]ct map {k v} x {}
+} -returnCodes 1 -result {missing value to go with key}
+test dict-24.20 {dict map stack space compilation: 'dict for' bug 1903325} {
+ apply {{x y args} {
+ dict map {a b} $x {}
+ concat "c=$y,$args"
+ }} {} 1 2 3
+} {c=1,2 3}
+proc linenumber {} {
+ dict get [info frame -1] line
+}
+test dict-24.20.1 {dict compilation crash: 'dict for' bug 3487626} {
+ apply {{} {apply {n {
+ set e {}
+ set k {}
+ dict map {a b} {c {d {e {f g}}}} {
+ ::tcl::dict::map {h i} $b {
+ dict update i e j {
+ ::tcl::dict::update j f k {
+ return [expr {$n - [linenumber]}]
+ }
+ }
+ }
+ }
+ }} [linenumber]}}
+} 5
+test dict-24.21 {dict compilation crash: 'dict for' bug 3487626} {
+ apply {{} {apply {n {
+ set e {}
+ set k {}
+ dict map {a {
+b
+}} {c {d {e {f g}}}} {
+ ::tcl::dict::map {h {
+i
+}} ${
+b
+} {
+ dict update {
+i
+} e {
+j
+} {
+ ::tcl::dict::update {
+j
+} f k {
+ return [expr {$n - [linenumber]}]
+ }
+ }
+ }
+ }
+ }} [linenumber]}}
+} 5
+test dict-23.3 {CompileWord OBOE} {
+ # segfault when buggy
+ apply {{} {tcl::dict::lappend foo bar \
+ [format baz]}}
+} {bar baz}
+test dict-23.4 {CompileWord OBOE} {
+ apply {n {
+ dict set foo {*}{
+ } [return [incr n -[linenumber]]] val
+ }} [linenumber]
+} 1
+test dict-23.5 {CompileWord OBOE} {
+ # segfault when buggy
+ apply {{} {tcl::dict::incr foo \
+ [format bar]}}
+} {bar 1}
+test dict-23.6 {CompileWord OBOE} {
+ apply {n {
+ dict get {a b} {*}{
+ } [return [incr n -[linenumber]]]
+ }} [linenumber]
+} 1
+test dict-23.7 {CompileWord OBOE} {
+ apply {n {
+ dict for {a b} [return [incr n -[linenumber]]] {*}{
+ } {}
+ }} [linenumber]
+} 2
+test dict-23.8 {CompileWord OBOE} {
+ apply {n {
+ dict update foo {*}{
+ } [return [incr n -[linenumber]]] x {}
+ }} [linenumber]
+} 1
+test dict-23.9 {CompileWord OBOE} {
+ apply {n {
+ dict exists {} {*}{
+ } [return [incr n -[linenumber]]]
+ }} [linenumber]
+} 1
+test dict-23.10 {CompileWord OBOE} {
+ apply {n {
+ dict with foo {*}{
+ } [return [incr n -[linenumber]]] {}
+ }} [linenumber]
+} 1
+test dict-23.11 {CompileWord OBOE} {
+ apply {n {
+ dict with ::foo {*}{
+ } [return [incr n -[linenumber]]] {}
+ }} [linenumber]
+} 1
+test dict-23.12 {CompileWord OBOE} {
+ apply {n {
+ dict with {*}{
+ } [return [incr n -[linenumber]]] {}
+ }} [linenumber]
+} 1
+test dict-23.13 {CompileWord OBOE} {
+ apply {n {
+ dict with {*}{
+ } [return [incr n -[linenumber]]] {bar}
+ }} [linenumber]
+} 1
+test dict-23.14 {CompileWord OBOE} {
+ apply {n {
+ dict with foo {*}{
+ } [return [incr n -[linenumber]]] {bar}
+ }} [linenumber]
+} 1
+
+rename linenumber {}
+test dict-24.22 {dict map results (non-compiled)} {
+ dict map {k v} [dict map {k v} {a 1 b 2 c 3 d 4} { list $v $k }] {
+ return -level 0 "$k,$v"
+ }
+} {a {a,1 a} b {b,2 b} c {c,3 c} d {d,4 d}}
+test dict-24.23 {dict map results (compiled)} {
+ apply {{} {
+ dict map {k v} [dict map {k v} {a 1 b 2 c 3 d 4} { list $v $k }] {
+ return -level 0 "$k,$v"
+ }
+ }}
+} {a {a,1 a} b {b,2 b} c {c,3 c} d {d,4 d}}
+test dict-24.23a {dict map results (compiled)} {
+ apply {{list} {
+ dict map {k v} [dict map {k v} $list { list $v $k }] {
+ return -level 0 "$k,$v"
+ }
+ }} {a 1 b 2 c 3 d 4}
+} {a {a,1 a} b {b,2 b} c {c,3 c} d {d,4 d}}
+test dict-24.24 {dict map with huge dict (non-compiled)} {
+ tcl::mathop::+ {*}[dict map {k v} [lsearch -all [lrepeat 100000 x] x] {
+ expr { $k * $v }
+ }]
+} 166666666600000
+test dict-24.25 {dict map with huge dict (compiled)} {
+ apply {{n} {
+ tcl::mathop::+ {*}[dict map {k v} [lsearch -all [lrepeat $n y] y] {
+ expr { $k * $v }
+ }]
+ }} 100000
+} 166666666600000
+
# cleanup
::tcltest::cleanupTests
diff --git a/tests/dstring.test b/tests/dstring.test
index bcc304d..06121a3 100644
--- a/tests/dstring.test
+++ b/tests/dstring.test
@@ -16,6 +16,9 @@ if {"::tcltest" ni [namespace children]} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testdstring [llength [info commands testdstring]]
if {[testConstraint testdstring]} {
testdstring free
diff --git a/tests/encoding.test b/tests/encoding.test
index a4f8449..0374e2d 100644
--- a/tests/encoding.test
+++ b/tests/encoding.test
@@ -15,6 +15,11 @@ namespace eval ::tcl::test::encoding {
namespace import -force ::tcltest::*
+catch {
+ ::tcltest::loadTestedCommands
+ package require -exact Tcltest [info patchlevel]
+}
+
proc toutf {args} {
variable x
lappend x "toutf $args"
@@ -417,13 +422,14 @@ test encoding-24.1 {EscapeFreeProc on open channels} exec {
gets $f
}
} {}
-test encoding-24.2 {EscapeFreeProc on open channels} exec {
+test encoding-24.2 {EscapeFreeProc on open channels} {exec} {
# Bug #524674 output
viewable [runInSubprocess {
encoding system cp1252; # Bug #2891556 crash revelator
fconfigure stdout -encoding iso2022-jp
puts ab\u4e4e\u68d9g
- testfinexit
+ set env(TCL_FINALIZE_ON_EXIT) 1
+ exit
}]
} "ab\x1b\$B8C\x1b\$(DD%\x1b(Bg (ab\\u001b\$B8C\\u001b\$(DD%\\u001b(Bg)"
test encoding-24.3 {EscapeFreeProc on open channels} {stdio} {
@@ -581,6 +587,14 @@ file delete {*}[glob -directory [temporaryDirectory] *.chars *.tcltestout]
# EscapeFreeProc, GetTableEncoding, unilen are fully tested by the rest of
# this file.
+
+test encoding-27.1 {encoding dirs basic behavior} -returnCodes error -body {
+ encoding dirs ? ?
+} -result {wrong # args: should be "encoding dirs ?dirList?"}
+test encoding-27.2 {encoding dirs basic behavior} -returnCodes error -body {
+ encoding dirs "\{not a list"
+} -result "expected directory list but got \"\{not a list\""
+
}
runtests
diff --git a/tests/env.test b/tests/env.test
index 9c417d9..83d99e0 100644
--- a/tests/env.test
+++ b/tests/env.test
@@ -70,7 +70,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 {
@@ -89,6 +89,7 @@ set printenvScript [makeFile {
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
} {
lrem names $name
}
@@ -97,6 +98,7 @@ set printenvScript [makeFile {
}
exit
} printenv]
+
# [exec] is required here to see the actual environment received by child
# processes.
proc getenv {} {
@@ -119,6 +121,7 @@ foreach name [array names env] {
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)
}
@@ -215,8 +218,8 @@ test env-4.5 {unsetting international environment variables} -setup {
unset env(\ua7)
getenv
} -constraints {exec} -cleanup {
- encoding system $sysenc
unset env(\ub6)
+ encoding system $sysenc
} -result {\u00b6=\u00a7}
test env-5.0 {corner cases - set a value, it should exist} -body {
@@ -288,6 +291,29 @@ test env-6.1 {corner cases - add lots of env variables} {} {
expr {[array size env] - $size}
} 100
+test env-7.1 {[219226]: whole env array should not be unset by read} {
+ set n [array size env]
+ set s [array startsearch env]
+ while {[array anymore env $s]} {
+ array nextelement env $s
+ incr n -1
+ }
+ array donesearch env $s
+ return $n
+} 0
+test env-7.2 {[219226]: links to env elements should not be removed by read} {
+ apply {{} {
+ set ::env(test7_2) ok
+ upvar env(test7_2) elem
+ set ::env(PATH)
+ try {
+ return $elem
+ } finally {
+ unset ::env(test7_2)
+ }
+ }}
+} ok
+
# Restore the environment variables at the end of the test.
foreach name [array names env] {
diff --git a/tests/error.test b/tests/error.test
index 97bcc0a..0de644c 100644
--- a/tests/error.test
+++ b/tests/error.test
@@ -17,6 +17,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
}
testConstraint memory [llength [info commands memory]]
+customMatch pairwise {apply {{a b} {
+ string equal [lindex $b 0] [lindex $b 1]
+}}}
namespace eval ::tcl::test::error {
if {[testConstraint memory]} {
proc getbytes {} {
@@ -179,6 +182,16 @@ test error-4.7 {errorstack via options dict } -body {
catch {f 12} m d
dict get $d -errorstack
} -match glob -result {INNER * CALL {g 1212} CALL {f 12} UP 1}
+test error-4.8 {errorstack from exec traces} -body {
+ proc foo args {}
+ proc goo {} foo
+ trace add execution foo enter {error bar;#}
+ catch goo m d
+ dict get $d -errorstack
+} -cleanup {
+ rename goo {}; rename foo {}
+ unset -nocomplain m d
+} -result {INNER {error bar} CALL goo UP 1}
# Errors in error command itself
@@ -314,6 +327,12 @@ test error-8.8 {throw syntax checks} -returnCodes error -body {
test error-8.9 {throw syntax checks} -returnCodes error -body {
throw {} foo
} -result {type must be non-empty list}
+test error-8.10 {Bug 33b7abb8a2: throw stack usage} -returnCodes error -body {
+ apply {code {throw $code foo}} {}
+} -result {type must be non-empty list}
+test error-8.11 {Bug 7174354ecb: throw error message} -returnCodes error -body {
+ throw {not {}a list} x[]y
+} -result {list element in braces followed by "a" instead of space}
# simple try tests: body completes with code ok
@@ -601,21 +620,21 @@ test error-16.7 {try with variable assignment and propagation #2} {
}
list $em [dict get $opts -errorcode]
} {bar FOO}
-test error-16.8 {exception chaining (try=ok, handler=error)} {
+test error-16.8 {exception chaining (try=ok, handler=error)} -body {
#FIXME is the intent of this test correct?
catch {
try { list a b c } on ok {em opts} { throw BAR baz }
} tryem tryopts
- string equal $opts [dict get $tryopts -during]
-} {1}
-test error-16.9 {exception chaining (try=error, handler=error)} {
+ list $opts [dict get $tryopts -during]
+} -match pairwise -result equal
+test error-16.9 {exception chaining (try=error, handler=error)} -body {
# The exception off the handler should chain to the exception off the
# try-body (using the -during option)
catch {
try { throw FOO bar } trap {} {em opts} { throw BAR baz }
} tryem tryopts
- string equal $opts [dict get $tryopts -during]
-} {1}
+ list $opts [dict get $tryopts -during]
+} -match pairwise -result equal
test error-16.10 {no exception chaining when handler is successful} {
catch {
try { throw FOO bar } trap {} {em opts} { list d e f }
@@ -628,6 +647,131 @@ test error-16.11 {no exception chaining when handler is a non-error exception} {
} tryem tryopts
dict exists $tryopts -during
} {0}
+test error-16.12 {compiled try with successfully executed handler} {
+ apply {{} {
+ try { throw FOO bar } trap FOO {} { list a b c }
+ }}
+} {a b c}
+test error-16.13 {compiled try with exception (error) in handler} -body {
+ apply {{} {
+ try { throw FOO bar } trap FOO {} { throw BAR foo }
+ }}
+} -returnCodes error -result {foo}
+test error-16.14 {compiled try with exception (return) in handler} -body {
+ apply {{} {
+ list [catch {
+ try { throw FOO bar } trap FOO {} { return BAR }
+ } msg] $msg
+ }}
+} -result {2 BAR}
+test error-16.15 {compiled try with exception (break) in handler} {
+ apply {{} {
+ for { set i 5 } { $i < 10 } { incr i } {
+ try { throw FOO bar } trap FOO {} { break }
+ }
+ return $i
+ }}
+} {5}
+test error-16.16 {compiled try with exception (continue) in handler} {
+ apply {{} {
+ for { set i 5 } { $i < 10 } { incr i } {
+ try { throw FOO bar } trap FOO {} { continue }
+ incr i 20
+ }
+ return $i
+ }}
+} {10}
+test error-16.17 {compiled try with variable assignment and propagation #1} {
+ # Ensure that the handler variables preserve the exception off the
+ # try-body, and are not modified by the exception off the handler
+ apply {{} {
+ catch {
+ try { throw FOO bar } trap FOO {em} { throw BAR baz }
+ }
+ return $em
+ }}
+} {bar}
+test error-16.18 {compiled try with variable assignment and propagation #2} {
+ apply {{} {
+ catch {
+ try { throw FOO bar } trap FOO {em opts} { throw BAR baz }
+ }
+ list $em [dict get $opts -errorcode]
+ }}
+} {bar FOO}
+test error-16.19 {compiled try exception chaining (try=ok, handler=error)} -body {
+ #FIXME is the intent of this test correct?
+ apply {{} {
+ catch {
+ try { list a b c } on ok {em opts} { throw BAR baz }
+ } tryem tryopts
+ list $opts [dict get $tryopts -during]
+ }}
+} -match pairwise -result equal
+test error-16.20 {compiled try exception chaining (try=error, handler=error)} -body {
+ # The exception off the handler should chain to the exception off the
+ # try-body (using the -during option)
+ apply {{} {
+ catch {
+ try { throw FOO bar } trap {} {em opts} { throw BAR baz }
+ } tryem tryopts
+ list $opts [dict get $tryopts -during]
+ }}
+} -match pairwise -result equal
+test error-16.21 {compiled try exception chaining (try=error, finally=error)} {
+ # The exception off the handler should chain to the exception off the
+ # try-body (using the -during option)
+ apply {{} {
+ catch {
+ try { throw FOO bar } finally { throw BAR baz }
+ } tryem tryopts
+ dict get $tryopts -during -errorcode
+ }}
+} FOO
+test error-16.22 {compiled try: no exception chaining when handler is successful} {
+ apply {{} {
+ catch {
+ try { throw FOO bar } trap {} {em opts} { list d e f }
+ } tryem tryopts
+ dict exists $tryopts -during
+ }}
+} {0}
+test error-16.23 {compiled try: no exception chaining when handler is a non-error exception} {
+ apply {{} {
+ catch {
+ try { throw FOO bar } trap {} {em opts} { break }
+ } tryem tryopts
+ dict exists $tryopts -during
+ }}
+} {0}
+test error-16.24 {compiled try exception chaining (try=ok, handler=error, finally=error)} -body {
+ apply {{} {
+ catch {
+ try {
+ list a b c
+ } on ok {em opts} {
+ throw BAR baz
+ } finally {
+ throw DING dong
+ }
+ } tryem tryopts
+ list $opts [dict get $tryopts -during -during]
+ }}
+} -match pairwise -result equal
+test error-16.25 {compiled try exception chaining (all errors)} -body {
+ apply {{} {
+ catch {
+ try {
+ throw FOO bar
+ } on error {em opts} {
+ throw BAR baz
+ } finally {
+ throw DING dong
+ }
+ } tryem tryopts
+ list $opts [dict get $tryopts -during -during]
+ }}
+} -match pairwise -result equal
# try tests - finally
@@ -709,15 +853,15 @@ test error-18.5 {exception in finally doesn't affect variable assignment} {
}
list $em [dict get $opts -errorcode]
} {bar FOO}
-test error-18.6 {exception chaining in finally (try=ok)} {
+test error-18.6 {exception chaining in finally (try=ok)} -body {
catch {
list a b c
} em expopts
catch {
try { list a b c } finally { throw BAR foo }
} em opts
- string equal $expopts [dict get $opts -during]
-} {1}
+ list $expopts [dict get $opts -during]
+} -match pairwise -result equal
test error-18.7 {exception chaining in finally (try=error)} {
catch {
try { throw FOO bar } finally { throw BAR baz }
diff --git a/tests/event.test b/tests/event.test
index 0ee7558..0d1b06c 100644
--- a/tests/event.test
+++ b/tests/event.test
@@ -12,6 +12,13 @@
package require tcltest 2
namespace import -force ::tcltest::*
+catch {
+ ::tcltest::loadTestedCommands
+ package require -exact Tcltest [info patchlevel]
+ set ::tcltestlib [lindex [package ifneeded Tcltest [info patchlevel]] 1]
+}
+
+
testConstraint testfilehandler [llength [info commands testfilehandler]]
testConstraint testexithandler [llength [info commands testexithandler]]
testConstraint testfilewait [llength [info commands testfilewait]]
@@ -427,6 +434,7 @@ catch {rename bgerror {}}
test event-8.1 {Tcl_CreateExitHandler procedure} {stdio testexithandler} {
set child [open |[list [interpreter]] r+]
+ puts $child "catch {load $::tcltestlib Tcltest}"
puts $child "testexithandler create 41; testexithandler create 4"
puts $child "testexithandler create 6; exit"
flush $child
@@ -440,6 +448,7 @@ odd 41
test event-9.1 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
set child [open |[list [interpreter]] r+]
+ puts $child "catch {load $::tcltestlib Tcltest}"
puts $child "testexithandler create 41; testexithandler create 4"
puts $child "testexithandler create 6; testexithandler delete 41"
puts $child "testexithandler create 16; exit"
@@ -453,6 +462,7 @@ even 4
}
test event-9.2 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
set child [open |[list [interpreter]] r+]
+ puts $child "catch {load $::tcltestlib Tcltest}"
puts $child "testexithandler create 41; testexithandler create 4"
puts $child "testexithandler create 6; testexithandler delete 4"
puts $child "testexithandler create 16; exit"
@@ -466,6 +476,7 @@ odd 41
}
test event-9.3 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
set child [open |[list [interpreter]] r+]
+ puts $child "catch {load $::tcltestlib Tcltest}"
puts $child "testexithandler create 41; testexithandler create 4"
puts $child "testexithandler create 6; testexithandler delete 6"
puts $child "testexithandler create 16; exit"
@@ -479,6 +490,7 @@ odd 41
}
test event-9.4 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
set child [open |[list [interpreter]] r+]
+ puts $child "catch {load $::tcltestlib Tcltest}"
puts $child "testexithandler create 41; testexithandler delete 41"
puts $child "testexithandler create 16; exit"
flush $child
diff --git a/tests/exec.test b/tests/exec.test
index 64d3517..871c0c5 100644
--- a/tests/exec.test
+++ b/tests/exec.test
@@ -157,7 +157,7 @@ test exec-2.6 {redirecting input from immediate source, with UTF} -setup {
encoding system iso8859-1
proc quotenonascii s {
regsub -all {\[|\\|\]} $s {\\&} s
- regsub -all {[\u007f-\uffff]} $s \
+ regsub -all "\[\u007f-\uffff\]" $s \
{[apply {c {format {\u%04x} [scan $c %c]}} &]} s
return [subst -novariables $s]
}
diff --git a/tests/execute.test b/tests/execute.test
index 012b3a7..94af158 100644
--- a/tests/execute.test
+++ b/tests/execute.test
@@ -19,6 +19,9 @@ if {"::tcltest" ni [namespace children]} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
catch {namespace delete {*}[namespace children :: test_ns_*]}
catch {rename foo ""}
catch {unset x}
diff --git a/tests/expr-old.test b/tests/expr-old.test
index c05a925..06a00ba 100644
--- a/tests/expr-old.test
+++ b/tests/expr-old.test
@@ -13,10 +13,11 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest 2.1
- namespace import -force ::tcltest::*
-}
+package require tcltest 2.1
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
testConstraint testexprlong [llength [info commands testexprlong]]
testConstraint testexprdouble [llength [info commands testexprdouble]]
@@ -142,7 +143,7 @@ test expr-old-1.50 {integer operators} {expr +36} 36
test expr-old-1.51 {integer operators} {expr +--++36} 36
test expr-old-1.52 {integer operators} {expr +36%+5} 1
test expr-old-1.53 {integer operators} {
- catch {unset x}
+ unset -nocomplain x
set x yes
list [expr {1 && $x}] [expr {$x && 1}] \
[expr {0 || $x}] [expr {$x || 0}]
@@ -450,7 +451,7 @@ test expr-old-23.3 {double quotes} {
test expr-old-23.4 {double quotes} {expr {"11\}\}22"}} 11}}22
test expr-old-23.5 {double quotes} {expr {"\*bc"}} {*bc}
test expr-old-23.6 {double quotes} {
- catch {unset bogus__}
+ unset -nocomplain bogus__
list [catch {expr {"$bogus__"}} msg] $msg
} {1 {can't read "bogus__": no such variable}}
test expr-old-23.7 {double quotes} {
@@ -499,7 +500,7 @@ test expr-old-26.2 {error conditions} -body {
test expr-old-26.3 {error conditions} -body {
expr 2+4*(
} -returnCodes error -match glob -result *
-catch {unset _non_existent_}
+unset -nocomplain _non_existent_
test expr-old-26.4 {error conditions} {
list [catch {expr 2+$_non_existent_} msg] $msg
} {1 {can't read "_non_existent_": no such variable}}
@@ -578,7 +579,7 @@ test expr-old-27.4 {cancelled evaluation} {
expr {1?2:[set a 2]}
set a
} 1
-catch {unset x}
+unset -nocomplain x
test expr-old-27.5 {cancelled evaluation} {
list [catch {expr {[info exists x] && $x}} msg] $msg
} {0 0}
diff --git a/tests/expr.test b/tests/expr.test
index 6679569..6ad7208 100644
--- a/tests/expr.test
+++ b/tests/expr.test
@@ -15,6 +15,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testmathfunctions [expr {
([catch {expr T1()} msg] != 1) || ($msg ne {invalid command name "tcl::mathfunc::T1"})
}]
diff --git a/tests/fCmd.test b/tests/fCmd.test
index 410e610..3d22b09 100644
--- a/tests/fCmd.test
+++ b/tests/fCmd.test
@@ -15,6 +15,11 @@ if {"::tcltest" ni [namespace children]} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+cd [temporaryDirectory]
+
testConstraint testsetplatform [llength [info commands testsetplatform]]
testConstraint testchmod [llength [info commands testchmod]]
testConstraint winVista 0
@@ -37,6 +42,7 @@ if {[testConstraint win]} {
}
}
+set tmpspace /tmp;# default value
# Find a group that exists on this Unix system, or else skip tests that
# require Unix groups.
testConstraint foundGroup [expr {![testConstraint unix]}]
@@ -46,6 +52,15 @@ if {[testConstraint unix]} {
set group [lindex $groupList 0]
testConstraint foundGroup 1
}
+
+ proc dev dir {
+ file stat $dir stat
+ return $stat(dev)
+ }
+
+ if {[catch {makeDirectory tcl[pid] /tmp} tmpspace] == 0} {
+ testConstraint xdev [expr {([dev .] != [dev $tmpspace])}]
+ }
}
# Also used in winFCmd...
@@ -149,13 +164,6 @@ proc contents {file} {
return $r
}
-cd [temporaryDirectory]
-
-proc dev dir {
- file stat $dir stat
- return $stat(dev)
-}
-testConstraint xdev [expr {[testConstraint unix] && ([dev .] != [dev /tmp])}]
set root [lindex [file split [pwd]] 0]
@@ -503,12 +511,6 @@ test fCmd-6.6 {CopyRenameOneFile: errno != ENOENT} -setup {
} -returnCodes error -cleanup {
testchmod 755 td1
} -result {error renaming "tf1" to "td1/tf1": permission denied}
-test fCmd-6.7 {CopyRenameOneFile: errno != ENOENT} -setup {
- cleanup
-} -constraints {win 95} -returnCodes error -body {
- createfile tf1
- file rename tf1 $long
-} -result [subst {error renaming "tf1" to "$long": file name too long}]
test fCmd-6.9 {CopyRenameOneFile: errno == ENOENT} -setup {
cleanup
} -constraints {unix notRoot} -body {
@@ -586,12 +588,12 @@ test fCmd-6.18 {CopyRenameOneFile: errno != EXDEV} -setup {
} -returnCodes error -match glob -result \
[subst {error renaming "td2" to "[file join td1 td2]": file *}]
test fCmd-6.19 {CopyRenameOneFile: errno == EXDEV} -setup {
- cleanup /tmp
+ cleanup $tmpspace
} -constraints {unix notRoot} -body {
createfile tf1
- file rename tf1 /tmp
- glob -nocomplain tf* /tmp/tf1
-} -result {/tmp/tf1}
+ file rename tf1 $tmpspace
+ glob -nocomplain tf* [file join $tmpspace tf1]
+} -result [file join $tmpspace tf1]
test fCmd-6.20 {CopyRenameOneFile: errno == EXDEV} -constraints {win} -setup {
catch {file delete -force c:/tcl8975@ d:/tcl8975@}
} -body {
@@ -605,28 +607,29 @@ test fCmd-6.20 {CopyRenameOneFile: errno == EXDEV} -constraints {win} -setup {
catch {file delete -force d:/tcl8975@}
} -result {d:/tcl8975@}
test fCmd-6.21 {CopyRenameOneFile: copy/rename: S_ISDIR(source)} -setup {
- cleanup /tmp
+ cleanup $tmpspace
} -constraints {unix notRoot} -body {
file mkdir td1
- file rename td1 /tmp
- glob -nocomplain td* /tmp/td*
-} -result {/tmp/td1}
+ file rename td1 $tmpspace
+ glob -nocomplain td* [file join $tmpspace td*]
+} -result [file join $tmpspace td1]
test fCmd-6.22 {CopyRenameOneFile: copy/rename: !S_ISDIR(source)} -setup {
- cleanup /tmp
+ cleanup $tmpspace
} -constraints {unix notRoot} -body {
createfile tf1
- file rename tf1 /tmp
- glob -nocomplain tf* /tmp/tf*
-} -result {/tmp/tf1}
+ file rename tf1 $tmpspace
+ glob -nocomplain tf* [file join $tmpspace tf*]
+} -result [file join $tmpspace tf1]
test fCmd-6.23 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
- cleanup /tmp
-} -constraints {unix notRoot xdev} -body {
+ cleanup $tmpspace
+} -constraints {xdev notRoot} -body {
file mkdir td1/td2/td3
file attributes td1 -permissions 0000
- file rename td1 /tmp
+ file rename td1 $tmpspace
} -returnCodes error -cleanup {
file attributes td1 -permissions 0755
-} -match regexp -result {^error renaming "td1"( to "/tmp/td1")?: permission denied$}
+ cleanup
+} -match regexp -result {^error renaming "td1"( to "/tmp/tcl\d+/td1")?: permission denied$}
test fCmd-6.24 {CopyRenameOneFile: error uses original name} -setup {
cleanup
} -constraints {unix notRoot} -body {
@@ -662,54 +665,54 @@ test fCmd-6.26 {CopyRenameOneFile: doesn't use original name} -setup {
file delete -force ~/td1
} -result "error copying \"~/td1\" to \"td1\": \"[file join $::env(HOME) td1 td2]\": permission denied"
test fCmd-6.27 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
- cleanup /tmp
-} -constraints {unix notRoot xdev} -returnCodes error -body {
+ cleanup $tmpspace
+} -constraints {notRoot xdev} -returnCodes error -body {
file mkdir td1/td2/td3
- file mkdir /tmp/td1
- createfile /tmp/td1/tf1
- file rename -force td1 /tmp
-} -result {error renaming "td1" to "/tmp/td1": file already exists}
+ file mkdir [file join $tmpspace td1]
+ createfile [file join $tmpspace td1 tf1]
+ file rename -force td1 $tmpspace
+} -match glob -result {error renaming "td1" to "/tmp/tcl*/td1": file already exists}
test fCmd-6.28 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
- cleanup /tmp
-} -constraints {unix notRoot xdev} -body {
+ cleanup $tmpspace
+} -constraints {notRoot xdev} -body {
file mkdir td1/td2/td3
file attributes td1/td2/td3 -permissions 0000
- file rename td1 /tmp
+ file rename td1 $tmpspace
} -returnCodes error -cleanup {
file attributes td1/td2/td3 -permissions 0755
-} -result {error renaming "td1" to "/tmp/td1": "td1/td2/td3": permission denied}
+ cleanup $tmpspace
+} -match glob -result {error renaming "td1" to "/tmp/tcl*/td1": "td1/td2/td3": permission denied}
test fCmd-6.29 {CopyRenameOneFile: TclpCopyDirectory passed} -setup {
- cleanup /tmp
-} -constraints {unix notRoot xdev} -body {
+ cleanup $tmpspace
+} -constraints {notRoot xdev} -body {
file mkdir td1/td2/td3
- file rename td1 /tmp
- glob td* /tmp/td1/t*
-} -result {/tmp/td1/td2}
+ file rename td1 $tmpspace
+ glob td* [file join $tmpspace td1 t*]
+} -result [file join $tmpspace td1 td2]
test fCmd-6.30 {CopyRenameOneFile: TclpRemoveDirectory failed} -setup {
- cleanup
+ cleanup $tmpspace
} -constraints {unix notRoot} -body {
file mkdir foo/bar
file attr foo -perm 040555
- file rename foo/bar /tmp
+ file rename foo/bar $tmpspace
} -returnCodes error -cleanup {
- catch {file delete /tmp/bar}
+ catch {file delete [file join $tmpspace bar]}
catch {file attr foo -perm 040777}
catch {file delete -force foo}
} -match glob -result {*: permission denied}
test fCmd-6.31 {CopyRenameOneFile: TclpDeleteFile passed} -setup {
- catch {cleanup /tmp}
-} -constraints {unix notRoot xdev} -body {
- file mkdir /tmp/td1
- createfile /tmp/td1/tf1
- file rename /tmp/td1/tf1 tf1
- list [file exists /tmp/td1/tf1] [file exists tf1]
+ cleanup $tmpspace
+} -constraints {notRoot xdev} -body {
+ file mkdir [file join $tmpspace td1]
+ createfile [file join $tmpspace td1 tf1]
+ file rename [file join $tmpspace td1 tf1] tf1
+ list [file exists [file join $tmpspace td1 tf1]] [file exists tf1]
} -result {0 1}
test fCmd-6.32 {CopyRenameOneFile: copy} -constraints {notRoot} -setup {
cleanup
} -returnCodes error -body {
file copy tf1 tf2
} -result {error copying "tf1": no such file or directory}
-catch {cleanup /tmp}
test fCmd-7.1 {FileForceOption: none} -constraints {notRoot} -setup {
cleanup
@@ -1347,23 +1350,23 @@ test fCmd-12.8 {renamefile: generic error} -setup {
file delete -force tfa
} -result {1}
test fCmd-12.9 {renamefile: moving a file across volumes} -setup {
- catch {file delete -force -- tfa /tmp/tfa}
+ cleanup $tmpspace
} -constraints {unix notRoot} -body {
set s [createfile tfa]
- file rename tfa /tmp
- list [checkcontent /tmp/tfa $s] [file exists tfa]
+ file rename tfa $tmpspace
+ list [checkcontent [file join $tmpspace tfa] $s] [file exists tfa]
} -cleanup {
- file delete /tmp/tfa
+ cleanup $tmpspace
} -result {1 0}
test fCmd-12.10 {renamefile: moving a directory across volumes} -setup {
- catch {file delete -force -- tfad /tmp/tfad}
-} -constraints {unix notRoot} -body {
+ cleanup $tmpspace
+} -constraints {xdev notRoot} -body {
file mkdir tfad
set s [createfile tfad/a]
- file rename tfad /tmp
- list [checkcontent /tmp/tfad/a $s] [file exists tfad]
+ file rename tfad $tmpspace
+ list [checkcontent [file join $tmpspace tfad a] $s] [file exists tfad]
} -cleanup {
- file delete -force /tmp/tfad
+ cleanup $tmpspace
} -result {1 0}
#
@@ -2432,14 +2435,17 @@ test fCmd-28.12 {file link: cd into a link} -setup {
return "ok"
}
} -cleanup {
+ file delete -force abc.link
cd [workingDirectory]
} -result ok
test fCmd-28.13 {file link} -constraints {linkDirectory} -setup {
cd [temporaryDirectory]
+ file link abc.link abc.dir
} -body {
# duplicate link throws error
file link abc.link abc.dir
} -returnCodes error -cleanup {
+ file delete -force abc.link
cd [workingDirectory]
} -result {could not create new link "abc.link": that path already exists}
test fCmd-28.14 {file link: deletes link not dir} -setup {
@@ -2460,6 +2466,7 @@ test fCmd-28.15.1 {file link: copies link not dir} -setup {
# directory, not a link (links trace to endpoint).
list [file type abc2.link] [file tail [file link abc.link]]
} -cleanup {
+ file delete -force abc.link
cd [workingDirectory]
} -result {directory abc.dir}
test fCmd-28.15.2 {file link: copies link not dir} -setup {
@@ -2470,6 +2477,7 @@ test fCmd-28.15.2 {file link: copies link not dir} -setup {
file copy abc.link abc2.link
list [file type abc2.link] [file tail [file link abc2.link]]
} -cleanup {
+ file delete -force abc.link
cd [workingDirectory]
} -result {link abc.dir}
cd [temporaryDirectory]
@@ -2489,20 +2497,25 @@ test fCmd-28.16 {file link: glob inside link} -setup {
file link abc.link abc.dir
lsort [glob -dir abc.link -tails *]
} -cleanup {
+ file delete -force abc.link
cd [workingDirectory]
} -result {abc.file abc2.file}
test fCmd-28.17 {file link: glob -type l} -setup {
cd [temporaryDirectory]
+ file link abc.link abc.dir
} -constraints {linkDirectory} -body {
glob -dir [pwd] -type l -tails abc*
} -cleanup {
+ file delete -force abc.link
cd [workingDirectory]
} -result {abc.link}
test fCmd-28.18 {file link: glob -type d} -constraints linkDirectory -setup {
cd [temporaryDirectory]
+ file link abc.link abc.dir
} -body {
lsort [glob -dir [pwd] -type d -tails abc*]
} -cleanup {
+ file delete -force abc.link
cd [workingDirectory]
} -result [lsort [list abc.link abc.dir abc2.dir]]
test fCmd-28.19 {file link: relative paths} -setup {
@@ -2583,6 +2596,9 @@ test fCmd-30.3 {file readable on 'pagefile.sys'} -constraints {win} -body {
# cleanup
cleanup
+if {[testConstraint unix]} {
+ removeDirectory tcl[pid] /tmp
+}
::tcltest::cleanupTests
return
diff --git a/tests/fileName.test b/tests/fileName.test
index affacff..51f00d1 100644
--- a/tests/fileName.test
+++ b/tests/fileName.test
@@ -15,6 +15,9 @@ if {"::tcltest" ni [namespace children]} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testsetplatform [llength [info commands testsetplatform]]
testConstraint testtranslatefilename [llength [info commands testtranslatefilename]]
testConstraint linkDirectory 1
@@ -196,7 +199,7 @@ test filename-4.12 {Tcl_SplitPath: unix} {testsetplatform} {
test filename-4.13 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split //foo
-} {/ foo}
+} "/ foo"
test filename-4.14 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split foo//bar
@@ -433,11 +436,11 @@ test filename-7.16 {Tcl_JoinPath: unix} {testsetplatform} {
test filename-7.17 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join //a b
-} {/a/b}
+} "/a/b"
test filename-7.18 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join /// a b
-} {/a/b}
+} "/a/b"
test filename-9.1 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
@@ -746,7 +749,7 @@ test filename-11.13 {Tcl_GlobCmd} {
} [file join $env(HOME)]
set oldpwd [pwd]
set oldhome $env(HOME)
-cd [temporaryDirectory]
+catch {cd [makeDirectory tcl[pid]]}
set env(HOME) [pwd]
file delete -force globTest
file mkdir globTest/a1/b1
@@ -1613,6 +1616,7 @@ catch {file delete -force C:/globTest}
cd [temporaryDirectory]
file delete -force globTest
cd $oldpwd
+catch {removeDirectory tcl[pid]}
set env(HOME) $oldhome
if {[testConstraint testsetplatform]} {
testsetplatform $platform
diff --git a/tests/fileSystem.test b/tests/fileSystem.test
index 4191713..942a86c 100644
--- a/tests/fileSystem.test
+++ b/tests/fileSystem.test
@@ -19,6 +19,17 @@ namespace eval ::tcl::test::fileSystem {
file delete -force [file join dir.dir linkinside.file]
}
+testConstraint loaddll 0
+catch {
+ ::tcltest::loadTestedCommands
+ package require -exact Tcltest [info patchlevel]
+ set ::ddever [package require dde]
+ set ::ddelib [lindex [package ifneeded dde $::ddever] 1]
+ set ::regver [package require registry]
+ set ::reglib [lindex [package ifneeded registry $::regver] 1]
+ testConstraint loaddll 1
+}
+
# Test for commands defined in Tcltest executable
testConstraint testfilesystem [llength [info commands ::testfilesystem]]
testConstraint testsetplatform [llength [info commands ::testsetplatform]]
@@ -127,13 +138,18 @@ test filesystem-1.9 {link normalisation} -setup {
testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \
[file normalize [file join dir.link inside.file foo]]
} -result ok
-test filesystem-1.10 {link normalisation: double link} {unix hasLinks} {
+test filesystem-1.10 {link normalisation: double link} -constraints {
+ unix hasLinks
+} -body {
file link dir2.link dir.link
testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \
[file normalize [file join dir2.link inside.file foo]]
-} ok
+} -cleanup {
+ file delete dir2.link
+} -result ok
makeDirectory dir2.file
test filesystem-1.11 {link normalisation: double link, back in tree} {unix hasLinks} {
+ file link dir2.link dir.link
file link [file join dir2.file dir2.link] [file join .. dir2.link]
testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \
[file normalize [file join dir2.file dir2.link inside.file foo]]
@@ -305,7 +321,7 @@ test filesystem-1.39 {file normalisation with volume relative} -setup {
file norm [string range $drv 0 1]
} -cleanup {
cd $old
-} -match glob -result {*[^/]}
+} -match regexp -result {.*[^/]}
test filesystem-1.40 {file normalisation with repeated separators} {
testPathEqual [file norm foo////bar] [file norm foo/bar]
} ok
@@ -362,7 +378,9 @@ test filesystem-2.0 {new native path} {unix} {
# Make sure the testfilesystem hasn't been registered.
if {[testConstraint testfilesystem]} {
+ proc resetfs {} {
while {![catch {testfilesystem 0}]} {}
+ }
}
test filesystem-3.1 {Tcl_FSRegister & Tcl_FSUnregister} testfilesystem {
@@ -377,12 +395,14 @@ test filesystem-3.3 {Tcl_FSRegister} testfilesystem {
testfilesystem 0
testfilesystem 0
} {unregistered}
-test filesystem-3.4 {Tcl_FSRegister} testfilesystem {
+test filesystem-3.4 {Tcl_FSRegister} -constraints testfilesystem -body {
testfilesystem 1
file system bar
-} {reporting}
-test filesystem-3.5 {Tcl_FSUnregister} testfilesystem {
+} -cleanup {
testfilesystem 0
+} -result {reporting}
+test filesystem-3.5 {Tcl_FSUnregister} testfilesystem {
+ resetfs
lindex [file system bar] 0
} {native}
@@ -473,7 +493,7 @@ test filesystem-6.22 {empty file name} {file pathtype ""} relative
test filesystem-6.23 {empty file name} {file readable ""} 0
test filesystem-6.24 {empty file name} -returnCodes error -body {
file readlink ""
-} -result {could not readlink "": no such file or directory}
+} -result {could not read link "": no such file or directory}
test filesystem-6.25 {empty file name} -returnCodes error -body {
file rename "" ""
} -result {error renaming "": no such file or directory}
@@ -501,13 +521,12 @@ if {[testConstraint testfilesystem]} {
test filesystem-7.1.1 {load from vfs} -setup {
set dir [pwd]
-} -constraints {win testsimplefilesystem} -body {
+} -constraints {win testsimplefilesystem loaddll} -body {
# This may cause a crash on exit
- cd [file dirname [info nameof]]
- set dde [lindex [glob *dde*[info sharedlib]] 0]
+ cd [file dirname $::ddelib]
testsimplefilesystem 1
# This loads dde via a complex copy-to-temp operation
- load simplefs:/$dde dde
+ load simplefs:/[file tail $::ddelib] dde
testsimplefilesystem 0
return ok
# The real result of this test is what happens when Tcl exits.
@@ -516,14 +535,13 @@ test filesystem-7.1.1 {load from vfs} -setup {
} -result ok
test filesystem-7.1.2 {load from vfs, and then unload again} -setup {
set dir [pwd]
-} -constraints {win testsimplefilesystem} -body {
+} -constraints {win testsimplefilesystem loaddll} -body {
# This may cause a crash on exit
- cd [file dirname [info nameof]]
- set reg [lindex [glob tclreg*[info sharedlib]] 0]
+ cd [file dirname $::reglib]
testsimplefilesystem 1
# This loads reg via a complex copy-to-temp operation
- load simplefs:/$reg Registry
- unload simplefs:/$reg
+ load simplefs:/[file tail $::reglib] Registry
+ unload simplefs:/[file tail $::reglib]
testsimplefilesystem 0
return ok
# The real result of this test is what happens when Tcl exits.
@@ -623,7 +641,7 @@ test filesystem-7.4 {cross-filesystem file copy with -force} -setup {
file delete -force simplefile
file delete -force file2
cd $dir
-} -result {0 10 1 {error copying "simplefs:/simplefile" to "file2": file already exists} 0 10 1}
+} -result {0 {} 1 {error copying "simplefs:/simplefile" to "file2": file already exists} 0 {} 1}
test filesystem-7.5 {cross-filesystem file copy with -force} -setup {
set dir [pwd]
cd [tcltest::temporaryDirectory]
@@ -648,7 +666,7 @@ test filesystem-7.5 {cross-filesystem file copy with -force} -setup {
file delete -force simplefile
file delete -force file2
cd $dir
-} -result {0 10 1 {error copying "simplefs:/simplefile" to "file2": file already exists} 0 10 1}
+} -result {0 {} 1 {error copying "simplefs:/simplefile" to "file2": file already exists} 0 {} 1}
test filesystem-7.6 {cross-filesystem dir copy with -force} -setup {
set dir [pwd]
cd [tcltest::temporaryDirectory]
@@ -920,6 +938,10 @@ test filesystem-9.9 {path objects and glob and file tail and tilde} -setup {
# ----------------------------------------------------------------------
+test filesystem-10.1 {Bug 3414754} {
+ string match */ [file join [pwd] foo/]
+} 0
+
cleanupTests
unset -nocomplain drive drives
}
diff --git a/tests/for.test b/tests/for.test
index ff4dc0e..8abd270 100644
--- a/tests/for.test
+++ b/tests/for.test
@@ -14,6 +14,12 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+# Used for constraining memory leak tests
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+ proc meminfo {} {lindex [split [memory info] "\n"] 3 3}
+}
+
# Basic "for" operation.
test for-1.1 {TclCompileForCmd: missing initial command} {
@@ -345,7 +351,6 @@ proc formatMail {} {
64 { UNIX (Solaris 2.* and SunOS, other systems soon to follow). Easy to install} \
65 { binary packages are now for sale at the Sun Labs Tcl/Tk Shop. Check it out!} \
}
-
set result ""
set NL "
"
@@ -365,7 +370,6 @@ proc formatMail {} {
} else {
set break 1
}
-
set xmailer 0
set inheaders 1
set last [array size lines]
@@ -386,9 +390,7 @@ proc formatMail {} {
set limit 55
} else {
set limit 55
-
# Decide whether or not to break the body line
-
if {$plen > 0} {
if {[string first {> } $line] == 0} {
# This is quoted text from previous message, don't reformat
@@ -431,7 +433,7 @@ proc formatMail {} {
set climit [expr $limit-1]
set cutoff 50
set continuation 0
-
+
while {[string length $line] > $limit} {
for {set c [expr $limit-1]} {$c >= $cutoff} {incr c -1} {
set char [string index $line $c]
@@ -824,7 +826,369 @@ test for-6.18 {Tcl_ForObjCmd: for command result} {
1 {invoked "continue" outside of a loop} \
]
-
+test for-7.1 {Bug 3614226: ensure that break cleans up the stack} memory {
+ apply {{} {
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {$x < 5} {incr x} {
+ list a b c [break] d e f
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.2 {Bug 3614226: ensure that continue cleans up the stack} memory {
+ apply {{} {
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {$x < 5} {incr x} {
+ list a b c [continue] d e f
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.3 {Bug 3614226: ensure that break cleans up the expansion stack} memory {
+ apply {{} {
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {[incr x]<50} {} {
+ puts {*}[puts a b c {*}[break] d e f]
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.4 {Bug 3614226: ensure that continue cleans up the expansion stack} memory {
+ apply {{} {
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {[incr x]<50} {} {
+ puts {*}[puts a b c {*}[continue] d e f]
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.5 {Bug 3614226: ensure that break cleans up the combination of main and expansion stack} memory {
+ apply {{} {
+ set l [lrepeat 50 p q r]
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {[incr x]<50} {} {
+ puts [puts {*}$l {*}[puts a b c {*}$l {*}[break] d e f]]
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.6 {Bug 3614226: ensure that continue cleans up the combination of main and expansion stack} memory {
+ apply {{} {
+ set l [lrepeat 50 p q r]
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {[incr x]<50} {} {
+ puts [puts {*}$l {*}[puts a b c {*}$l {*}[continue] d e f]]
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.7 {Bug 3614226: ensure that break only cleans up the right amount} memory {
+ apply {{} {
+ set l [lrepeat 50 p q r]
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ unset -nocomplain {*}[for {set x 0} {[incr x]<50} {} {
+ puts [puts {*}$l {*}[puts a b c {*}$l {*}[break] d e f]]
+ }]
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.8 {Bug 3614226: ensure that continue only cleans up the right amount} memory {
+ apply {{} {
+ set l [lrepeat 50 p q r]
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ unset -nocomplain {*}[for {set x 0} {[incr x]<50} {} {
+ puts [puts {*}$l {*}[puts a b c {*}$l {*}[continue] d e f]]
+ }]
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.9 {Bug 3614226: ensure that break from invoked command cleans up the stack} memory {
+ apply {{} {
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {$x < 5} {incr x} {
+ list a b c [apply {{} {return -code break}}] d e f
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.10 {Bug 3614226: ensure that continue from invoked command cleans up the stack} memory {
+ apply {{} {
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {$x < 5} {incr x} {
+ list a b c [apply {{} {return -code continue}}] d e f
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.11 {Bug 3614226: ensure that break from invoked command cleans up the expansion stack} memory {
+ apply {{} {
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {[incr x]<50} {} {
+ puts {*}[puts a b c {*}[apply {{} {return -code break}}] d e f]
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.12 {Bug 3614226: ensure that continue from invoked command cleans up the expansion stack} memory {
+ apply {{} {
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {[incr x]<50} {} {
+ puts {*}[puts a b c {*}[apply {{} {
+ return -code continue
+ }}] d e f]
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.13 {Bug 3614226: ensure that break from invoked command cleans up the combination of main and expansion stack} memory {
+ apply {{} {
+ set l [lrepeat 50 p q r]
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {[incr x]<50} {} {
+ puts [puts {*}$l {*}[puts a b c {*}$l {*}[apply {{} {
+ return -code break
+ }}] d e f]]
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.14 {Bug 3614226: ensure that continue from invoked command cleans up the combination of main and expansion stack} memory {
+ apply {{} {
+ set l [lrepeat 50 p q r]
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {[incr x]<50} {} {
+ puts [puts {*}$l {*}[puts a b c {*}$l {*}[apply {{} {
+ return -code continue
+ }}] d e f]]
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.15 {Bug 3614226: ensure that break from invoked command only cleans up the right amount} memory {
+ apply {{} {
+ set l [lrepeat 50 p q r]
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ unset -nocomplain {*}[for {set x 0} {[incr x]<50} {} {
+ puts [puts {*}$l {*}[puts a b c {*}$l {*}[apply {{} {
+ return -code break
+ }}] d e f]]
+ }]
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.16 {Bug 3614226: ensure that continue from invoked command only cleans up the right amount} memory {
+ apply {{} {
+ set l [lrepeat 50 p q r]
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ unset -nocomplain {*}[for {set x 0} {[incr x]<50} {} {
+ puts [puts {*}$l {*}[puts a b c {*}$l {*}[apply {{} {
+ return -code continue
+ }}] d e f]]
+ }]
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }}
+} 0
+test for-7.17 {Bug 3614226: ensure that break from expanded command cleans up the stack} memory {
+ apply {op {
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {$x < 5} {incr x} {
+ list a b c [{*}$op] d e f
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }} {return -level 0 -code break}
+} 0
+test for-7.18 {Bug 3614226: ensure that continue from expanded command cleans up the stack} memory {
+ apply {op {
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {$x < 5} {incr x} {
+ list a b c [{*}$op] d e f
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }} {return -level 0 -code continue}
+} 0
+test for-7.19 {Bug 3614226: ensure that break from expanded command cleans up the expansion stack} memory {
+ apply {op {
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {[incr x]<50} {} {
+ puts {*}[puts a b c {*}[{*}$op] d e f]
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }} {return -level 0 -code break}
+} 0
+test for-7.20 {Bug 3614226: ensure that continue from expanded command cleans up the expansion stack} memory {
+ apply {op {
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {[incr x]<50} {} {
+ puts {*}[puts a b c {*}[{*}$op] d e f]
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }} {return -level 0 -code continue}
+} 0
+test for-7.21 {Bug 3614226: ensure that break from expanded command cleans up the combination of main and expansion stack} memory {
+ apply {op {
+ set l [lrepeat 50 p q r]
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {[incr x]<50} {} {
+ puts [puts {*}$l {*}[puts a b c {*}$l {*}[{*}$op] d e f]]
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }} {return -level 0 -code break}
+} 0
+test for-7.22 {Bug 3614226: ensure that continue from expanded command cleans up the combination of main and expansion stack} memory {
+ apply {op {
+ set l [lrepeat 50 p q r]
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ for {set x 0} {[incr x]<50} {} {
+ puts [puts {*}$l {*}[puts a b c {*}$l {*}[{*}$op] d e f]]
+ }
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }} {return -level 0 -code continue}
+} 0
+test for-7.23 {Bug 3614226: ensure that break from expanded command only cleans up the right amount} memory {
+ apply {op {
+ set l [lrepeat 50 p q r]
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ unset -nocomplain {*}[for {set x 0} {[incr x]<50} {} {
+ puts [puts {*}$l {*}[puts a b c {*}$l {*}[{*}$op] d e f]]
+ }]
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }} {return -level 0 -code break}
+} 0
+test for-7.24 {Bug 3614226: ensure that continue from expanded command only cleans up the right amount} memory {
+ apply {op {
+ set l [lrepeat 50 p q r]
+ # Can't use [memtest]; must be careful when we change stack frames
+ set end [meminfo]
+ for {set i 0} {$i < 5} {incr i} {
+ unset -nocomplain {*}[for {set x 0} {[incr x]<50} {} {
+ puts [puts {*}$l {*}[puts a b c {*}$l {*}[{*}$op] d e f]]
+ }]
+ set tmp $end
+ set end [meminfo]
+ }
+ expr {$end - $tmp}
+ }} {return -level 0 -code continue}
+} 0
+
# cleanup
::tcltest::cleanupTests
return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/foreach.test b/tests/foreach.test
index a4b652a..6fd5476 100644
--- a/tests/foreach.test
+++ b/tests/foreach.test
@@ -254,6 +254,17 @@ test foreach-9.1 {compiled empty var list} {
list [catch { foo } msg] $msg
} {1 {foreach varlist is empty}}
+test foreach-9.2 {line numbers} -setup {
+ proc linenumber {} {dict get [info frame -1] line}
+} -body {
+ apply {n {
+ foreach x y {*}{
+ } {return [incr n -[linenumber]]}
+ }} [linenumber]
+} -cleanup {
+ rename linenumber {}
+} -result 1
+
test foreach-10.1 {foreach: [Bug 1671087]} -setup {
proc demo {} {
set vals {1 2 3 4}
@@ -266,6 +277,15 @@ test foreach-10.1 {foreach: [Bug 1671087]} -setup {
rename demo {}
} -result {}
+test foreach-11.1 {error then dereference loop var (dev bug)} {
+ catch { foreach a 0 b {1 2 3} { error x } }
+ set a
+} 0
+test foreach-11.2 {error then dereference loop var (dev bug)} {
+ catch { foreach a 0 b {1 2 3} { incr a $b; error x } }
+ set a
+} 1
+
# cleanup
catch {unset a}
catch {unset x}
diff --git a/tests/format.test b/tests/format.test
index 2d53eba..27eac31 100644
--- a/tests/format.test
+++ b/tests/format.test
@@ -549,10 +549,7 @@ test format-18.2 {do not demote existing numeric values} {wideBiggerThanInt} {
list [format %08x $a] [expr {$a == $b}]
} {aaaaaaab 1}
-test format-19.1 {
- regression test - tcl-core message by Brian Griffin on
- 26 0ctober 2004
-} -body {
+test format-19.1 {regression test - tcl-core message by Brian Griffin on 26 0ctober 2004} -body {
set x 0x8fedc654
list [expr { ~ $x }] [format %08x [expr { ~$x }]]
} -match regexp -result {-2414724693 f*701239ab}
@@ -569,7 +566,7 @@ test format-20.1 {Bug 2932421: plain %s caused intrep change of args} -body {
format %s $x
# After this, obj in $x should be a dict with a non-NULL bytes field
tcl::unsupported::representation $x
-} -match glob -result {value is a dict with *, string representation "*".}
+} -match glob -result {value is a dict with *, string representation "*"}
# cleanup
catch {unset a}
diff --git a/tests/get.test b/tests/get.test
index 40ec98f..d51ec6d 100644
--- a/tests/get.test
+++ b/tests/get.test
@@ -15,6 +15,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testgetint [llength [info commands testgetint]]
testConstraint longIs32bit [expr {int(0x80000000) < 0}]
testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}]
diff --git a/tests/http.test b/tests/http.test
index 1f4d8b4..a0a26de 100644
--- a/tests/http.test
+++ b/tests/http.test
@@ -51,14 +51,13 @@ if {![file exists $httpdFile]} {
set removeHttpd 1
}
-if {[info commands testthread] == "testthread" && [file exists $httpdFile]} {
- set httpthread [testthread create "
- source [list $httpdFile]
- testthread wait
- "]
- testthread send $httpthread [list set port $port]
- testthread send $httpthread [list set bindata $bindata]
- testthread send $httpthread {httpd_init $port}
+catch {package require Thread 2.7-}
+if {[catch {package present Thread}] == 0 && [file exists $httpdFile]} {
+ set httpthread [thread::create -preserved]
+ thread::send $httpthread [list source $httpdFile]
+ thread::send $httpthread [list set port $port]
+ thread::send $httpthread [list set bindata $bindata]
+ thread::send $httpthread {httpd_init $port}
puts "Running httpd in thread $httpthread"
} else {
if {![file exists $httpdFile]} {
@@ -120,7 +119,7 @@ test http-3.2 {http::geturl} -returnCodes error -body {
http::geturl http:junk
} -result {Unsupported URL: http:junk}
set url //[info hostname]:$port
-set badurl //[info hostname]:6666
+set badurl //[info hostname]:[expr $port+1]
test http-3.3 {http::geturl} -body {
set token [http::geturl $url]
http::data $token
@@ -132,10 +131,12 @@ test http-3.3 {http::geturl} -body {
</body></html>"
set tail /a/b/c
set url //[info hostname]:$port/a/b/c
-set fullurl http://user:pass@[info hostname]:$port/a/b/c
+set fullurl HTTP://user:pass@[info hostname]:$port/a/b/c
set binurl //[info hostname]:$port/binary
set posturl //[info hostname]:$port/post
set badposturl //[info hostname]:$port/droppost
+set authorityurl //[info hostname]:$port
+set ipv6url http://\[::1\]:$port/
test http-3.4 {http::geturl} -body {
set token [http::geturl $url]
http::data $token
@@ -365,7 +366,58 @@ test http-3.26 {http::meta} -setup {
http::cleanup $token
unset -nocomplain m token
} -result {Content-Length Content-Type Date X-Check}
-
+test http-3.27 {http::geturl: -headers override -type} -body {
+ set token [http::geturl $url/headers -type "text/plain" -query dummy \
+ -headers [list "Content-Type" "text/plain;charset=utf-8"]]
+ http::data $token
+} -cleanup {
+ http::cleanup $token
+} -match regexp -result {(?n)Accept \*/\*
+Host .*
+User-Agent .*
+Connection close
+Content-Type {text/plain;charset=utf-8}
+Accept-Encoding .*
+Content-Length 5}
+test http-3.28 {http::geturl: -headers override -type default} -body {
+ set token [http::geturl $url/headers -query dummy \
+ -headers [list "Content-Type" "text/plain;charset=utf-8"]]
+ http::data $token
+} -cleanup {
+ http::cleanup $token
+} -match regexp -result {(?n)Accept \*/\*
+Host .*
+User-Agent .*
+Connection close
+Content-Type {text/plain;charset=utf-8}
+Accept-Encoding .*
+Content-Length 5}
+test http-3.29 {http::geturl IPv6 address} -body {
+ # We only want to see if the URL gets parsed correctly. This is
+ # the case if http::geturl succeeds or returns a socket related
+ # error. If the parsing is wrong, we'll get a parse error.
+ # It'd be better to separate the URL parser from http::geturl, so
+ # that it can be tested without also trying to make a connection.
+ set error [catch {http::geturl $ipv6url -validate 1} token]
+ if {$error && [string match "couldn't open socket: *" $token]} {
+ set error 0
+ }
+ set error
+} -cleanup {
+ catch { http::cleanup $token }
+} -result 0
+test http-3.30 {http::geturl query without path} -body {
+ set token [http::geturl $authorityurl?var=val]
+ http::ncode $token
+} -cleanup {
+ catch { http::cleanup $token }
+} -result 200
+test http-3.31 {http::geturl fragment without path} -body {
+ set token [http::geturl "$authorityurl#fragment42"]
+ http::ncode $token
+} -cleanup {
+ catch { http::cleanup $token }
+} -result 200
test http-4.1 {http::Event} -body {
set token [http::geturl $url -keepalive 0]
upvar #0 $token data
@@ -440,14 +492,10 @@ proc myProgress {token total current} {
}
set progress [list $total $current]
}
-if 0 {
- # This test hangs on Windows95 because the client never gets EOF
- set httpLog 1
- test http-4.6.1 {http::Event} knownBug {
- set token [http::geturl $url -blocksize 50 -progress myProgress]
- return $progress
- } {111 111}
-}
+test http-4.6.1 {http::Event} knownBug {
+ set token [http::geturl $url -blocksize 50 -progress myProgress]
+ return $progress
+} {111 111}
test http-4.7 {http::Event} -body {
set token [http::geturl $url -keepalive 0 -progress myProgress]
return $progress
@@ -507,11 +555,10 @@ test http-4.14 {http::Event} -body {
error "bogus return from http::geturl"
}
http::wait $token
- http::status $token
- # error code varies among platforms.
-} -returnCodes 1 -match regexp -cleanup {
+ lindex [http::error $token] 0
+} -cleanup {
catch {http::cleanup $token}
-} -result {(connect failed|couldn't open socket)}
+} -result {connect failed connection refused}
# Bogus host
test http-4.15 {http::Event} -body {
# This test may fail if you use a proxy server. That is to be
@@ -530,17 +577,17 @@ test http-5.1 {http::formatQuery} {
# test http-5.2 obsoleted by 5.4 and 5.5 with http 2.5
test http-5.3 {http::formatQuery} {
http::formatQuery lines "line1\nline2\nline3"
-} {lines=line1%0d%0aline2%0d%0aline3}
+} {lines=line1%0D%0Aline2%0D%0Aline3}
test http-5.4 {http::formatQuery} {
http::formatQuery name1 ~bwelch name2 \xa1\xa2\xa2
-} {name1=~bwelch&name2=%c2%a1%c2%a2%c2%a2}
+} {name1=~bwelch&name2=%C2%A1%C2%A2%C2%A2}
test http-5.5 {http::formatQuery} {
set enc [http::config -urlencoding]
http::config -urlencoding iso8859-1
set res [http::formatQuery name1 ~bwelch name2 \xa1\xa2\xa2]
http::config -urlencoding $enc
set res
-} {name1=~bwelch&name2=%a1%a2%a2}
+} {name1=~bwelch&name2=%A1%A2%A2}
test http-6.1 {http::ProxyRequired} -body {
http::config -proxyhost [info hostname] -proxyport $port
@@ -558,12 +605,12 @@ test http-6.1 {http::ProxyRequired} -body {
test http-7.1 {http::mapReply} {
http::mapReply "abc\$\[\]\"\\()\}\{"
-} {abc%24%5b%5d%22%5c%28%29%7d%7b}
+} {abc%24%5B%5D%22%5C%28%29%7D%7B}
test http-7.2 {http::mapReply} {
# RFC 2718 specifies that we pass urlencoding on utf-8 chars by default,
# so make sure this gets converted to utf-8 then urlencoded.
http::mapReply "\u2208"
-} {%e2%88%88}
+} {%E2%88%88}
test http-7.3 {http::formatQuery} -setup {
set enc [http::config -urlencoding]
} -returnCodes error -body {
@@ -582,7 +629,7 @@ test http-7.4 {http::formatQuery} -setup {
http::mapReply "\u2208"
} -cleanup {
http::config -urlencoding $enc
-} -result {%3f}
+} -result {%3F}
# cleanup
catch {unset url}
@@ -590,9 +637,7 @@ catch {unset badurl}
catch {unset port}
catch {unset data}
if {[info exists httpthread]} {
- testthread send -async $httpthread {
- testthread exit
- }
+ thread::release $httpthread
} else {
close $listen
}
diff --git a/tests/httpd b/tests/httpd
index 5272385..232e80a 100644
--- a/tests/httpd
+++ b/tests/httpd
@@ -40,7 +40,7 @@ proc httpdAccept {newsock ipaddr port} {
fconfigure $newsock -blocking 0 -translation {auto crlf}
httpd_log $newsock Connect $ipaddr $port
set data(ipaddr) $ipaddr
- fileevent $newsock readable [list httpdRead $newsock]
+ after 50 [list fileevent $newsock readable [list httpdRead $newsock]]
}
# read data from a client request
@@ -175,6 +175,14 @@ proc httpdRespond { sock } {
set html "Got [string length $data(query)] bytes"
set type text/plain
}
+ *headers* {
+ set html ""
+ set type text/plain
+ foreach {key value} $data(meta) {
+ append html [list $key $value] "\n"
+ }
+ set html [string trim $html]
+ }
default {
set type text/html
diff --git a/tests/indexObj.test b/tests/indexObj.test
index 098aec0..646cb02 100644
--- a/tests/indexObj.test
+++ b/tests/indexObj.test
@@ -1,20 +1,24 @@
# This file is a Tcl script to test out the the procedures in file
-# tkIndexObj.c, which implement indexed table lookups. The tests here
-# are organized in the standard fashion for Tcl tests.
+# tkIndexObj.c, which implement indexed table lookups. The tests here are
+# organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# 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
+ package require tcltest 2
namespace import -force ::tcltest::*
}
-testConstraint testindexobj [llength [info commands testindexobj]]
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+testConstraint testindexobj [llength [info commands testindexobj]]
+testConstraint testparseargs [llength [info commands testparseargs]]
+
test indexObj-1.1 {exact match} testindexobj {
testindexobj 1 1 xyz abc def xyz alm
} {2}
@@ -128,6 +132,31 @@ test indexObj-6.4 {Tcl_GetIndexFromObjStruct} testindexobj {
testgetindexfromobjstruct $x 1
} "wrong # args: should be \"testgetindexfromobjstruct c 1\""
+test indexObj-7.1 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs
+} {0 1 testparseargs}
+test indexObj-7.2 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs -bool
+} {1 1 testparseargs}
+test indexObj-7.3 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs -bool bar
+} {1 2 {testparseargs bar}}
+test indexObj-7.4 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs bar
+} {0 2 {testparseargs bar}}
+test indexObj-7.5 {Tcl_ParseArgsObjv} -constraints testparseargs -body {
+ testparseargs -help
+} -returnCodes error -result {Command-specific options:
+ -bool: booltest
+ --: Marks the end of the options
+ -help: Print summary of command-line options and abort}
+test indexObj-7.6 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs -- -bool -help
+} {0 3 {testparseargs -bool -help}}
+test indexObj-7.7 {Tcl_ParseArgsObjv memory management} testparseargs {
+ testparseargs 1 2 3 4 5 6 7 8 9 0 -bool 1 2 3 4 5 6 7 8 9 0
+} {1 21 {testparseargs 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0}}
+
# cleanup
::tcltest::cleanupTests
return
diff --git a/tests/info.test b/tests/info.test
index 3323281..3057dd2 100644
--- a/tests/info.test
+++ b/tests/info.test
@@ -20,6 +20,9 @@ if {{::tcltest} ni [namespace children]} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
# Set up namespaces needed to test operation of "info args", "info body",
# "info default", and "info procs" with imported procedures.
@@ -231,7 +234,6 @@ test info-6.11 {info default option} {
}
} {0 {} 1 27}
-
test info-7.1 {info exists option} -body {
set value foo
info exists value
@@ -690,31 +692,31 @@ test info-21.5 {miscellaneous error conditions} -returnCodes error -body {
##
# ### ### ### ######### ######### #########
## info frame
+
## Helper
# For the more complex results we cut the file name down to remove path
# dependencies, and we use only part of the first line of the reported
# command. The latter is required because otherwise the whole test case may
# appear in some results, but the result is part of the testcase. An infinite
# string would be required to describe that. The cutting-down breaks this.
+
proc reduce {frame} {
- set pos [lsearch -exact $frame cmd]
- incr pos
- set cmd [lindex $frame $pos]
+ set cmd [dict get $frame cmd]
if {[regexp \n $cmd]} {
- set first [string range [lindex [split $cmd \n] 0] 0 end-4]
- set frame [lreplace $frame $pos $pos $first]
+ dict set frame cmd \
+ [string range [lindex [split $cmd \n] 0] 0 end-4]
}
- set pos [lsearch -exact $frame file]
- if {$pos >=0} {
- incr pos
- set tail [file tail [lindex $frame $pos]]
- set frame [lreplace $frame $pos $pos $tail]
+ if {[dict exists $frame file]} {
+ dict set frame file \
+ [file tail [dict get $frame file]]
}
- set frame
+ return $frame
}
+
proc subinterp {} { interp create sub ; interp debug sub -frame 1;
interp eval sub [list proc reduce [info args reduce] [info body reduce]]
}
+
## Helper
# Generate a stacktrace from the current location to top. This code
# not only depends on the exact location of things, but also on the
@@ -731,8 +733,6 @@ proc etrace {} {
return $res
}
-##
-
test info-22.0 {info frame, levels} {!singleTestInterp} {
info frame
} 7
@@ -763,7 +763,7 @@ test info-22.7 {info frame, global, absolute} {!singleTestInterp} {
} {type source line 761 file info.test cmd test\ info-22.7\ \{info\ frame,\ global,\ absolute\}\ \{!singleTestInter level 0}
test info-22.8 {info frame, basic trace} -match glob -body {
join [lrange [etrace] 0 2] \n
-} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0}
* {type source line 765 file info.test cmd etrace proc ::tcltest::RunTest}
* {type source line * file tcltest* cmd {uplevel 1 $script} proc ::tcltest::RunTest}}
unset -nocomplain msg
@@ -803,7 +803,7 @@ test info-23.5 {eval'd info frame, dynamic} -cleanup {unset script} -body {
test info-23.6 {eval'd info frame, trace} -match glob -cleanup {unset script} -body {
set script {etrace}
join [lrange [eval $script] 0 2] \n
-} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0}
* {type eval line 1 cmd etrace proc ::tcltest::RunTest}
* {type source line 805 file info.test cmd {eval $script} proc ::tcltest::RunTest}}
@@ -1318,7 +1318,7 @@ test info-37.0 {eval pure list, single line} -match glob -body {
}]
eval $cmd
return $res
-} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0}
* {type eval line 2 cmd etrace proc ::tcltest::RunTest}
* {type eval line 1 cmd foreac proc ::tcltest::RunTest}} -cleanup {unset foo cmd res b c}
@@ -1359,7 +1359,7 @@ test info-38.1 {location information for uplevel, dv, direct-var} -match glob -b
etrace
}
join [lrange [uplevel \#0 $script] 0 2] \n
-} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0}
* {type eval line 3 cmd etrace proc ::tcltest::RunTest}
* {type source line 1361 file info.test cmd {uplevel \\#0 $script} proc ::tcltest::RunTest}} -cleanup {unset script y}
@@ -1378,7 +1378,7 @@ test info-38.3 {location information for uplevel, dpv, direct-proc-var} -match g
etrace
}
join [lrange [control y $script] 0 3] \n
-} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0}
* {type eval line 3 cmd etrace proc ::control}
* {type source line 1338 file info.test cmd {uplevel 1 $script} proc ::control}
* {type source line 1380 file info.test cmd {control y $script} proc ::tcltest::RunTest}} -cleanup {unset script y}
@@ -1395,7 +1395,7 @@ test info-38.3 {location information for uplevel, dpv, direct-proc-var} -match g
test info-38.5 {location information for uplevel, ppv, proc-proc-var} -match glob -body {
join [lrange [datav] 0 4] \n
-} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0}
* {type eval line 3 cmd etrace proc ::control}
* {type source line 1338 file info.test cmd {uplevel 1 $script} proc ::control}
* {type source line 1353 file info.test cmd {control y $script} proc ::datav level 1}
@@ -1412,7 +1412,7 @@ test info-38.5 {location information for uplevel, ppv, proc-proc-var} -match glo
testConstraint testevalex [llength [info commands testevalex]]
test info-38.7 {location information for arg substitution} -constraints testevalex -match glob -body {
join [lrange [testevalex {return -level 0 [etrace]}] 0 3] \n
-} -result {* {type source line 728 file info.test cmd {info frame \$level} proc ::etrace level 0}
+} -result {* {type source line 730 file info.test cmd {info frame \$level} proc ::etrace level 0}
* {type eval line 1 cmd etrace proc ::tcltest::RunTest}
* {type source line 1414 file info.test cmd {testevalex {return -level 0 \[etrace]}} proc ::tcltest::RunTest}
* {type source line * file tcltest* cmd {uplevel 1 $script} proc ::tcltest::RunTest}}
@@ -1454,9 +1454,9 @@ test info-30.1 {bs+nl in literal words, procedure body, compiled} -body {
test info-30.2 {bs+nl in literal words, namespace script} {
namespace eval xxx {
variable res \
- [reduce [info frame 0]];# line 1457
+ [info frame 0];# line 1457
}
- return $xxx::res
+ return [reduce $xxx::res]
} {type source line 1457 file info.test cmd {info frame 0} level 0}
test info-30.3 {bs+nl in literal words, namespace multi-word script} {
@@ -1955,6 +1955,446 @@ test info-38.2 {location information for uplevel, dl, direct-literal} -match glo
* {type source line 1951 file info.test cmd etrace level 1}
* {type source line 1949 file info.test cmd uplevel\\ \\\\ level 1}} -cleanup {interp delete sub}
+# This test at the end of this file _only_ to avoid disturbing above line
+# numbers. It _belongs_ after info-9.12
+test info-9.13 {info level option, value in global context} -body {
+ uplevel #0 {info level 2}
+} -returnCodes error -result {bad level "2"}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ catch {*}{
+ {info frame 0}
+ res
+ }
+ return $res
+}
+test info-33.4 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 1968 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ dict for {a b} {c d} {*}{
+ {set res [info frame 0]}
+ }
+ return $res
+}
+test info-33.5 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 1983 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ set d {a b}
+ dict update d x y {*}{
+ {set res [info frame 0]}
+ }
+ return $res
+}
+test info-33.6 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 1998 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ set d {}
+ dict with d {*}{
+ {set res [info frame 0]}
+ }
+ return $res
+}
+test info-33.7 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2013 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ for {*}{
+ {set res [info frame 0]}
+ {1} {} {break}
+ }
+ return $res
+}
+test info-33.8 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2027 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ for {*}{
+ {} {1} {}
+ {set res [info frame 0]; break}
+ }
+ return $res
+}
+test info-33.9 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2043 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ for {*}{
+ {} {1}
+ {return [info frame 0]}
+ {}
+ }
+}
+test info-33.10 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2058 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ for {*}{
+ {}
+ {[return [info frame 0]]}
+ {} {}
+ }
+}
+test info-33.11 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2073 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ foreach {*}{
+ x
+ } [return [info frame 0]] {}
+}
+test info-33.12 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2088 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ foreach {*}{
+ x y
+ {set res [info frame 0]}
+ }
+ return $res
+}
+test info-33.13 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2101 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ if {*}{
+ {[return [info frame 0]]}
+ {}
+ }
+}
+test info-33.14 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2115 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ if 0 {*}{
+ {} else
+ {return [info frame 0]}
+ }
+}
+test info-33.15 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2130 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ incr {*}{
+ x
+ } [return [info frame 0]]
+}
+test info-33.16 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2144 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ info level {*}{
+ } [return [info frame 0]]
+}
+test info-33.17 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2156 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ string match {*}{
+ } [return [info frame 0]] {}
+}
+test info-33.18 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2168 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ string match {*}{
+ {}
+ } [return [info frame 0]]
+}
+test info-33.19 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2181 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ string length {*}{
+ } [return [info frame 0]]
+}
+test info-33.20 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2193 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ while {*}{
+ {[return [info frame 0]]}
+ } {}
+}
+test info-33.21 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2205 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ switch -- {*}{
+ } [return [info frame 0]] {*}{
+ } x y
+}
+test info-33.22 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2218 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ try {*}{
+ {set res [info frame 0]}
+ }
+ return $res
+}
+test info-33.23 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2231 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ try {*}{
+ {set res [info frame 0]}
+ } finally {}
+ return $res
+}
+test info-33.24 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2245 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ try {*}{
+ {set res [info frame 0]}
+ } on ok {} {}
+ return $res
+}
+test info-33.25 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2259 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ try {*}{
+ {set res [info frame 0]}
+ } on ok {} {} finally {}
+ return $res
+}
+test info-33.26 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2273 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ while 1 {*}{
+ {return [info frame 0]}
+ }
+}
+test info-33.27 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2287 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ try {} finally {*}{
+ {return [info frame 0]}
+ }
+}
+test info-33.28 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2300 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ try {} on ok {} {} finally {*}{
+ {return [info frame 0]}
+ }
+}
+test info-33.29 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2313 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ try {} on ok {} {*}{
+ {return [info frame 0]}
+ }
+}
+test info-33.30 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2326 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ try {} on ok {} {*}{
+ {return [info frame 0]}
+ } finally {}
+}
+test info-33.31 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2339 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ binary format {*}{
+ } [return [info frame 0]]
+}
+test info-33.32 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2352 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ set format format
+ binary $format {*}{
+ } [return [info frame 0]]
+}
+test info-33.33 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2365 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ append x {*}{
+ } [return [info frame 0]]
+}
+test info-33.34 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2377 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+ append {*}{
+ } x([return [info frame 0]]) {*}{
+ } a
+}
+test info-33.35 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 2389 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
# -------------------------------------------------------------------------
unset -nocomplain res
diff --git a/tests/init.test b/tests/init.test
index 79d9a04..41b8624 100644
--- a/tests/init.test
+++ b/tests/init.test
@@ -11,7 +11,7 @@
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
if {"::tcltest" ni [namespace children]} {
- package require tcltest 2.3.3
+ package require tcltest 2.3.4
namespace import -force ::tcltest::*
}
diff --git a/tests/interp.test b/tests/interp.test
index 35f6824..ad99fac 100644
--- a/tests/interp.test
+++ b/tests/interp.test
@@ -15,9 +15,12 @@ if {"::tcltest" ni [namespace children]} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testinterpdelete [llength [info commands testinterpdelete]]
-set hidden_cmds {cd encoding exec exit fconfigure glob load open pwd socket source tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable unload}
+set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable unload}
foreach i [interp slaves] {
interp delete $i
@@ -584,7 +587,6 @@ test interp-14.10 {testing interp-alias: error messages} -setup {
invoked from within
"a 1"}
-
# part 15: testing file sharing
test interp-15.1 {testing file sharing} {
catch {interp delete z}
@@ -665,8 +667,7 @@ test interp-15.8 {testing file transferring} -body {
# Torture tests for interpreter deletion order
#
proc kill {} {interp delete xxx}
-
-test interp-15.9 {testing deletion order} {
+test interp-16.0 {testing deletion order} {
catch {interp delete xxx}
interp create xxx
xxx alias kill kill
@@ -1598,6 +1599,20 @@ test interp-20.50 {Bug 2486550} -setup {
} -cleanup {
interp delete slave
} -returnCodes error -match glob -result *
+test interp-20.50.1 {Bug 2486550} -setup {
+ interp create slave
+} -body {
+ slave hide coroutine
+ catch {slave invokehidden coroutine} m o
+ dict get $o -errorinfo
+} -cleanup {
+ unset -nocomplain m 0
+ interp delete slave
+} -returnCodes ok -result {wrong # args: should be "coroutine name cmd ?arg ...?"
+ while executing
+"coroutine"
+ invoked from within
+"slave invokehidden coroutine"}
test interp-21.1 {interp hidden} {
interp hidden {}
@@ -3497,6 +3512,13 @@ test interp-35.22 {interp time limits normalize milliseconds} -body {
} -cleanup {
interp delete $i
} -result {2 500}
+# Bug 3398794
+test interp-35.23 {interp command limits can't touch current interp} -body {
+ interp limit {} commands -value 10
+} -returnCodes error -result {limits on current interpreter inaccessible}
+test interp-35.24 {interp time limits can't touch current interp} -body {
+ interp limit {} time -seconds 2
+} -returnCodes error -result {limits on current interpreter inaccessible}
test interp-36.1 {interp bgerror syntax} -body {
interp bgerror
@@ -3610,7 +3632,6 @@ test interp-38.8 {interp debug basic setup} -body {
} -returnCodes {
error
} -result {wrong # args: should be "interp debug path ?-frame ?bool??"}
-
# cleanup
unset -nocomplain hidden_cmds
diff --git a/tests/io.test b/tests/io.test
index e28948f..edc0b11 100644
--- a/tests/io.test
+++ b/tests/io.test
@@ -17,6 +17,10 @@ if {[catch {package require tcltest 2}]} {
puts stderr "Skipping tests in [info script]. tcltest 2 required."
return
}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
namespace eval ::tcl::test::io {
namespace import ::tcltest::*
@@ -37,7 +41,7 @@ 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 testthread [llength [info commands testthread]]
+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...
@@ -2086,6 +2090,8 @@ set path(pipe) [makeFile {} pipe]
set path(output) [makeFile {} output]
test io-27.6 {FlushChannel, async flushing, async close} \
{stdio asyncPipeClose openpipe} {
+ # This test may fail on old Unix systems (seen on IRIX64 6.5) with
+ # obsolete gettimeofday() calls. See Tcl Bugs 3530533, 1942197.
file delete $path(pipe)
file delete $path(output)
set f [open $path(pipe) w]
@@ -2645,6 +2651,8 @@ test io-29.30 {Tcl_WriteChars, crlf mode} {
file size $path(test1)
} 25
test io-29.31 {Tcl_WriteChars, background flush} {stdio openpipe} {
+ # This test may fail on old Unix systems (seen on IRIX64 6.5) with
+ # obsolete gettimeofday() calls. See Tcl Bugs 3530533, 1942197.
file delete $path(pipe)
file delete $path(output)
set f [open $path(pipe) w]
@@ -2686,6 +2694,8 @@ test io-29.31 {Tcl_WriteChars, background flush} {stdio openpipe} {
} ok
test io-29.32 {Tcl_WriteChars, background flush to slow reader} \
{stdio asyncPipeClose openpipe} {
+ # This test may fail on old Unix systems (seen on IRIX64 6.5) with
+ # obsolete gettimeofday() calls. See Tcl Bugs 3530533, 1942197.
file delete $path(pipe)
file delete $path(output)
set f [open $path(pipe) w]
@@ -2736,6 +2746,26 @@ test io-29.33 {Tcl_Flush, implicit flush on exit} {exec} {
close $f
set r
} "hello\nbye\nstrange\n"
+set path(script2) [makeFile {} script2]
+test io-29.33b {TIP#398, no implicit flush of nonblocking on exit} {exec} {
+ set f [open $path(script) w]
+ puts $f {
+ fconfigure stdout -blocking 0
+ puts -nonewline stdout [string repeat A 655360]
+ flush stdout
+ }
+ close $f
+ set f [open $path(script2) w]
+ puts $f {after 2000}
+ close $f
+ set t1 [clock milliseconds]
+ set ff [open "|[list [interpreter] $path(script2)]" w]
+ catch {unset ::env(TCL_FLUSH_NONBLOCKING_ON_EXIT)}
+ exec [interpreter] $path(script) >@ $ff
+ set t2 [clock milliseconds]
+ close $ff
+ expr {($t2-$t1)/2000 ? $t2-$t1 : 0}
+} 0
test io-29.34 {Tcl_Close, async flush on close, using sockets} {socket tempNotMac fileevent} {
variable c 0
variable x running
@@ -4695,6 +4725,77 @@ test io-35.17 {Tcl_Eof, eof char in middle, crlf write, crlf read} {
close $f
list $c $l $e
} {21 8 1}
+test io-35.18 {Tcl_Eof, eof char, cr write, crlf read} -body {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f abc\ndef
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set l [string length [set in [read $f]]]
+ set e [eof $f]
+ close $f
+ list $s $l $e [scan [string index $in end] %c]
+} -result {8 8 1 13}
+test io-35.18a {Tcl_Eof, eof char, cr write, crlf read} -body {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar \x1a
+ set l [string length [set in [read $f]]]
+ set e [eof $f]
+ close $f
+ list $s $l $e [scan [string index $in end] %c]
+} -result {9 8 1 13}
+test io-35.18b {Tcl_Eof, eof char, cr write, crlf read} -constraints knownBug -body {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar \x1a
+ puts $f {}
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar \x1a
+ set l [string length [set in [read $f]]]
+ set e [eof $f]
+ close $f
+ list $s $l $e [scan [string index $in end] %c]
+} -result {2 1 1 13}
+test io-35.18c {Tcl_Eof, eof char, cr write, crlf read} -body {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f {}
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set l [string length [set in [read $f]]]
+ set e [eof $f]
+ close $f
+ list $s $l $e [scan [string index $in end] %c]
+} -result {1 1 1 13}
+test io-35.19 {Tcl_Eof, eof char in middle, cr write, crlf read} -body {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar {}
+ set i [format abc\ndef\n%cqrs\nuvw 26]
+ puts $f $i
+ close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar \x1a
+ set l [string length [set in [read $f]]]
+ set e [eof $f]
+ close $f
+ list $c $l $e [scan [string index $in end] %c]
+} -result {17 8 1 13}
# Test Tcl_InputBlocked
@@ -5205,16 +5306,16 @@ test io-40.1 {POSIX open access modes: RDWR} {
} {zzy abzzy}
test io-40.2 {POSIX open access modes: CREAT} {unix} {
file delete $path(test3)
- set f [open $path(test3) {WRONLY CREAT} 0600]
+ set f [open $path(test3) {WRONLY CREAT} 0o600]
file stat $path(test3) stats
- set x [format "0%o" [expr $stats(mode)&0o777]]
+ set x [format "0o%o" [expr $stats(mode)&0o777]]
puts $f "line 1"
close $f
set f [open $path(test3) r]
lappend x [gets $f]
close $f
set x
-} {0600 {line 1}}
+} {0o600 {line 1}}
test io-40.3 {POSIX open access modes: CREAT} {unix umask} {
# This test only works if your umask is 2, like ouster's.
file delete $path(test3)
@@ -7435,7 +7536,7 @@ test io-59.1 {Thread reference of channels} {testmainthread testchannel} {
# More complicated tests (like that the reference changes as a
# channel is moved from thread to thread) can be done only in the
# extension which fully implements the moving of channels between
- # threads, i.e. 'Threads'. Or we have to extend [testthread] as well.
+ # threads, i.e. 'Threads'.
set f [open $path(longfile) r]
set result [testchannel mthread $f]
@@ -7527,25 +7628,7 @@ test io-70.0 {Cutting & Splicing channels} {testchannel} {
} {0 1 0}
-# Duplicate of code in "thread.test". Find a better way of doing this
-# without duplication. Maybe placement into a proc which transforms to
-# nop after the first call, and placement of its defintion in a
-# central location.
-
-if {[testConstraint testthread]} {
- testthread errorproc ThreadError
-
- proc ThreadError {id info} {
- global threadError
- set threadError $info
- }
-
- proc ThreadNullError {id info} {
- # ignore
- }
-}
-
-test io-70.1 {Transfer channel} {testchannel testthread} {
+test io-70.1 {Transfer channel} {testchannel thread} {
set f [makeFile {... dummy ...} cutsplice]
set c [open $f r]
@@ -7554,16 +7637,17 @@ test io-70.1 {Transfer channel} {testchannel testthread} {
testchannel cut $c
lappend res [catch {seek $c 0 start}]
- set tid [testthread create]
- testthread send $tid [list set c $c]
- lappend res [testthread send $tid {
+ set tid [thread::create -preserved]
+ thread::send $tid [list set c $c]
+ thread::send $tid {load {} Tcltest}
+ lappend res [thread::send $tid {
testchannel splice $c
set res [catch {seek $c 0 start}]
close $c
set res
}]
- tcltest::threadReap
+ thread::release $tid
removeFile cutsplice
set res
@@ -7778,7 +7862,7 @@ test io-73.2 {channel Tcl_Obj SetChannelFromAny, bug 2407783} -setup {
# ### ### ### ######### ######### #########
# cleanup
-foreach file [list fooBar longfile script output test1 pipe my_script \
+foreach file [list fooBar longfile script script2 output test1 pipe my_script \
test2 test3 cat stdout kyrillic.txt utf8-fcopy.txt utf8-rp.txt] {
removeFile $file
}
diff --git a/tests/ioCmd.test b/tests/ioCmd.test
index 82f83db..3976d25 100644
--- a/tests/ioCmd.test
+++ b/tests/ioCmd.test
@@ -18,10 +18,13 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
# Custom constraints used in this file
testConstraint fcopy [llength [info commands fcopy]]
testConstraint testchannel [llength [info commands testchannel]]
-testConstraint testthread [llength [info commands testthread]]
+testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
#----------------------------------------------------------------------
@@ -790,6 +793,90 @@ test iocmd-21.19 {chan create, init failure -> no channel, no finalize} -match g
rename foo {}
set res
} -result {{} {initialize rc* {read write}} 1 {*all required methods*} {}}
+test iocmd-21.20 {Bug 88aef05cda} -setup {
+ proc foo {method chan args} {
+ switch -- $method blocking {
+ chan configure $chan -blocking [lindex $args 0]
+ return
+ } initialize {
+ return {initialize finalize watch blocking read write
+ configure cget cgetall}
+ } finalize {
+ return
+ }
+ }
+ set ch [chan create {read write} foo]
+} -body {
+ list [catch {chan configure $ch -blocking 0} m] $m
+} -cleanup {
+ close $ch
+ rename foo {}
+} -match glob -result {1 {*nested eval*}}
+test iocmd-21.21 {[close] in [read] segfaults} -setup {
+ proc foo {method chan args} {
+ switch -- $method initialize {
+ return {initialize finalize watch read}
+ } finalize {} watch {} read {
+ close $chan
+ return a
+ }
+ }
+ set ch [chan create read foo]
+} -body {
+ read $ch 0
+} -cleanup {
+ close $ch
+ rename foo {}
+} -result {}
+test iocmd-21.22 {[close] in [read] segfaults} -setup {
+ proc foo {method chan args} {
+ switch -- $method initialize {
+ return {initialize finalize watch read}
+ } finalize {} watch {} read {
+ catch {close $chan}
+ return a
+ }
+ }
+ set ch [chan create read foo]
+} -body {
+ read $ch 1
+} -returnCodes error -cleanup {
+ catch {close $ch}
+ rename foo {}
+} -match glob -result {*invalid argument*}
+test iocmd-21.23 {[close] in [gets] segfaults} -setup {
+ proc foo {method chan args} {
+ switch -- $method initialize {
+ return {initialize finalize watch read}
+ } finalize {} watch {} read {
+ catch {close $chan}
+ return \n
+ }
+ }
+ set ch [chan create read foo]
+} -body {
+ gets $ch
+} -cleanup {
+ catch {close $ch}
+ rename foo {}
+} -result {}
+test iocmd-21.24 {[close] in binary [gets] segfaults} -setup {
+ proc foo {method chan args} {
+ switch -- $method initialize {
+ return {initialize finalize watch read}
+ } finalize {} watch {} read {
+ catch {close $chan}
+ return \n
+ }
+ }
+ set ch [chan create read foo]
+} -body {
+ chan configure $ch -translation binary
+ gets $ch
+} -cleanup {
+ catch {close $ch}
+ rename foo {}
+} -result {}
# --- --- --- --------- --------- ---------
# Helper commands to record the arguments to handler methods.
@@ -1048,6 +1135,20 @@ test iocmd-23.10 {chan read, EAGAIN means no data, yet no eof either} -match glo
rename foo {}
unset res
} -result {{read rc* 4096} {} 0}
+test iocmd-23.11 {chan read, close pulls the rug out} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ set args [lassign $args sub id]
+ if {$sub ne "read"} {return}
+ close $id
+ return {}
+ }
+ set c [chan create {r} foo]
+ note [read $c]
+ rename foo {}
+ set res
+} -result {{read rc* 4096} {}}
# --- === *** ###########################
# method write
@@ -1991,7 +2092,6 @@ test iocmd-32.1 {origin interpreter of moved channel destroyed during access} -m
# response.
interp eval $idb [list set chan $chan]
- interp eval $idb [list set mid $tcltest::mainThread]
set res [interp eval $idb {
# wait a bit, give the main thread the time to start its event
# loop to wait for the response from B
@@ -2028,23 +2128,6 @@ test iocmd-32.2 {delete interp of reflected chan} {
## forwarding, and gaps due to tests not applicable to forwarding are
## left to keep this asociation.
-# Duplicate of code in "thread.test". Find a better way of doing this
-# without duplication. Maybe placement into a proc which transforms to
-# nop after the first call, and placement of its defintion in a
-# central location.
-
-if {[testConstraint testthread]} {
- testthread errorproc ThreadError
-
- proc ThreadError {id info} {
- global threadError
- set threadError $info
- }
- proc ThreadNullError {id info} {
- # ignore
- }
-}
-
# ### ### ### ######### ######### #########
## Helper command. Runs a script in a separate thread and returns the
## result. A channel is transfered into the thread as well, and list of
@@ -2053,7 +2136,8 @@ if {[testConstraint testthread]} {
proc inthread {chan script args} {
# Test thread.
- set tid [testthread create]
+ set tid [thread::create -preserved]
+ thread::send $tid {load {} Tcltest}
# Init thread configuration.
# - Listed variables
@@ -2062,22 +2146,23 @@ proc inthread {chan script args} {
foreach v $args {
upvar 1 $v x
- testthread send $tid [list set $v $x]
+ thread::send $tid [list set $v $x]
+
}
- testthread send $tid [list set mid $tcltest::mainThread]
- testthread send $tid {
+ thread::send $tid [list set mid [thread::id]]
+ thread::send $tid {
proc note {item} {global notes; lappend notes $item}
proc notes {} {global notes; return $notes}
proc noteOpts opts {global notes; lappend notes [dict merge {
-code !?! -level !?! -errorcode !?! -errorline !?! -errorinfo !?!
} $opts]}
}
- testthread send $tid [list proc s {} [list uplevel 1 $script]]; # (*)
+ thread::send $tid [list proc s {} [list uplevel 1 $script]]; # (*)
# Transfer channel (cut/splice aka detach/attach)
testchannel cut $chan
- testthread send $tid [list testchannel splice $chan]
+ thread::send $tid [list testchannel splice $chan]
# Run test script, also run local event loop!
# The local event loop waits for the result to come back.
@@ -2085,15 +2170,15 @@ proc inthread {chan script args} {
# operations.
set ::tres ""
- testthread send -async $tid {
+ thread::send -async $tid {
after 500
catch {s} res; # This runs the script, 's' was defined at (*)
- testthread send -async $mid [list set ::tres $res]
+ thread::send -async $mid [list set ::tres $res]
}
vwait ::tres
# Remove test thread, and return the captured result.
- tcltest::threadReap
+ thread::release $tid
return $::tres
}
@@ -2114,7 +2199,7 @@ test iocmd.tf-22.2 {chan finalize, for close} -match glob -body {
note [info command foo]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{initialize rc* {read write}} rc* {finalize rc*} {} foo}
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} {} foo}
test iocmd.tf-22.3 {chan finalize, for close, error, close error} -match glob -body {
set res {}
proc foo {args} {track; oninit; return -code error 5}
@@ -2127,7 +2212,7 @@ test iocmd.tf-22.3 {chan finalize, for close, error, close error} -match glob -b
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 5 {}}
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 5 {}}
test iocmd.tf-22.4 {chan finalize, for close, error, close errror} -match glob -body {
set res {}
proc foo {args} {track; oninit; error FOO}
@@ -2138,7 +2223,7 @@ test iocmd.tf-22.4 {chan finalize, for close, error, close errror} -match glob -
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 FOO}
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 FOO}
test iocmd.tf-22.5 {chan finalize, for close, arbitrary result} -match glob -body {
set res {}
proc foo {args} {track; oninit; return SOMETHING}
@@ -2149,7 +2234,7 @@ test iocmd.tf-22.5 {chan finalize, for close, arbitrary result} -match glob -bod
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{initialize rc* {read write}} rc* {finalize rc*} 0 {}}
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} 0 {}}
test iocmd.tf-22.6 {chan finalize, for close, break, close error} -match glob -body {
set res {}
proc foo {args} {track; oninit; return -code 3}
@@ -2161,7 +2246,7 @@ test iocmd.tf-22.6 {chan finalize, for close, break, close error} -match glob -b
rename foo {}
set res
} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-22.7 {chan finalize, for close, continue, close error} -match glob -body {
set res {}
proc foo {args} {track; oninit; return -code 4}
@@ -2173,7 +2258,7 @@ test iocmd.tf-22.7 {chan finalize, for close, continue, close error} -match glob
rename foo {}
set res
} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-22.8 {chan finalize, for close, custom code, close error} -match glob -body {
set res {}
proc foo {args} {track; oninit; return -code 777 BANG}
@@ -2185,7 +2270,7 @@ test iocmd.tf-22.8 {chan finalize, for close, custom code, close error} -match g
rename foo {}
set res
} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-22.9 {chan finalize, for close, ignore level, close error} -match glob -body {
set res {}
proc foo {args} {track; oninit; return -level 5 -code 777 BANG}
@@ -2197,7 +2282,7 @@ test iocmd.tf-22.9 {chan finalize, for close, ignore level, close error} -match
rename foo {}
set res
} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
# --- === *** ###########################
# method read
@@ -2216,7 +2301,7 @@ test iocmd.tf-23.1 {chan read, regular data return} -match glob -body {
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{read rc* 4096} {read rc* 4096} snarfsnarf}
+} -constraints {testchannel thread} -result {{read rc* 4096} {read rc* 4096} snarfsnarf}
test iocmd.tf-23.2 {chan read, bad data return, to much} -match glob -body {
set res {}
proc foo {args} {
@@ -2231,7 +2316,7 @@ test iocmd.tf-23.2 {chan read, bad data return, to much} -match glob -body {
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{read rc* 4096} 1 {read delivered more than requested}}
+} -constraints {testchannel thread} -result {{read rc* 4096} 1 {read delivered more than requested}}
test iocmd.tf-23.3 {chan read, for non-readable channel} -match glob -body {
set res {}
proc foo {args} {
@@ -2245,7 +2330,7 @@ test iocmd.tf-23.3 {chan read, for non-readable channel} -match glob -body {
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {1 {channel "rc*" wasn't opened for reading}}
+} -constraints {testchannel thread} -result {1 {channel "rc*" wasn't opened for reading}}
test iocmd.tf-23.4 {chan read, error return} -match glob -body {
set res {}
proc foo {args} {
@@ -2261,7 +2346,7 @@ test iocmd.tf-23.4 {chan read, error return} -match glob -body {
rename foo {}
set res
} -result {{read rc* 4096} 1 BOOM!} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-23.5 {chan read, break return is error} -match glob -body {
set res {}
proc foo {args} {
@@ -2277,7 +2362,7 @@ test iocmd.tf-23.5 {chan read, break return is error} -match glob -body {
rename foo {}
set res
} -result {{read rc* 4096} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-23.6 {chan read, continue return is error} -match glob -body {
set res {}
proc foo {args} {
@@ -2293,7 +2378,7 @@ test iocmd.tf-23.6 {chan read, continue return is error} -match glob -body {
rename foo {}
set res
} -result {{read rc* 4096} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-23.7 {chan read, custom return is error} -match glob -body {
set res {}
proc foo {args} {
@@ -2309,7 +2394,7 @@ test iocmd.tf-23.7 {chan read, custom return is error} -match glob -body {
rename foo {}
set res
} -result {{read rc* 4096} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-23.8 {chan read, level is squashed} -match glob -body {
set res {}
proc foo {args} {
@@ -2325,7 +2410,7 @@ test iocmd.tf-23.8 {chan read, level is squashed} -match glob -body {
rename foo {}
set res
} -result {{read rc* 4096} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-23.9 {chan read, no data means eof} -match glob -setup {
set res {}
proc foo {args} {
@@ -2345,7 +2430,7 @@ test iocmd.tf-23.9 {chan read, no data means eof} -match glob -setup {
rename foo {}
unset res
} -result {{read rc* 4096} {} 1} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-23.10 {chan read, EAGAIN means no data, yet no eof either} -match glob -setup {
set res {}
proc foo {args} {
@@ -2365,7 +2450,7 @@ test iocmd.tf-23.10 {chan read, EAGAIN means no data, yet no eof either} -match
rename foo {}
unset res
} -result {{read rc* 4096} {} 0} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
# --- === *** ###########################
# method write
@@ -2385,7 +2470,7 @@ test iocmd.tf-24.1 {chan write, regular write} -match glob -body {
} c
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{write rc* snarf} 5}
+} -constraints {testchannel thread} -result {{write rc* snarf} 5}
test iocmd.tf-24.2 {chan write, ack partial writes} -match glob -body {
set res {}
proc foo {args} {
@@ -2402,7 +2487,7 @@ test iocmd.tf-24.2 {chan write, ack partial writes} -match glob -body {
} c
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{write rc* snarfsnarfsnarf} 7 {write rc* arfsnarf} 8}
+} -constraints {testchannel thread} -result {{write rc* snarfsnarfsnarf} 7 {write rc* arfsnarf} 8}
test iocmd.tf-24.3 {chan write, failed write} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; note -1; return -1}
@@ -2413,7 +2498,7 @@ test iocmd.tf-24.3 {chan write, failed write} -match glob -body {
} c
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{write rc* snarfsnarfsnarf} -1}
+} -constraints {testchannel thread} -result {{write rc* snarfsnarfsnarf} -1}
test iocmd.tf-24.4 {chan write, non-writable channel} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
@@ -2426,7 +2511,7 @@ test iocmd.tf-24.4 {chan write, non-writable channel} -match glob -body {
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {1 {channel "rc*" wasn't opened for writing}}
+} -constraints {testchannel thread} -result {1 {channel "rc*" wasn't opened for writing}}
test iocmd.tf-24.5 {chan write, bad result, more written than data} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; return 10000}
@@ -2439,7 +2524,7 @@ test iocmd.tf-24.5 {chan write, bad result, more written than data} -match glob
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{write rc* snarf} 1 {write wrote more than requested}}
+} -constraints {testchannel thread} -result {{write rc* snarf} 1 {write wrote more than requested}}
test iocmd.tf-24.6 {chan write, zero writes} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; return 0}
@@ -2452,7 +2537,7 @@ test iocmd.tf-24.6 {chan write, zero writes} -match glob -body {
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{write rc* snarf} 1 {write wrote more than requested}}
+} -constraints {testchannel thread} -result {{write rc* snarf} 1 {write wrote more than requested}}
test iocmd.tf-24.7 {chan write, failed write, error return} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; return -code error BOOM!}
@@ -2466,7 +2551,7 @@ test iocmd.tf-24.7 {chan write, failed write, error return} -match glob -body {
rename foo {}
set res
} -result {{write rc* snarfsnarfsnarf} 1 BOOM!} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-24.8 {chan write, failed write, error return} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; error BOOM!}
@@ -2480,7 +2565,7 @@ test iocmd.tf-24.8 {chan write, failed write, error return} -match glob -body {
rename foo {}
set res
} -result {{write rc* snarfsnarfsnarf} 1 BOOM!} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-24.9 {chan write, failed write, break return is error} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; return -code break BOOM!}
@@ -2494,7 +2579,7 @@ test iocmd.tf-24.9 {chan write, failed write, break return is error} -match glob
rename foo {}
set res
} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-24.10 {chan write, failed write, continue return is error} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; return -code continue BOOM!}
@@ -2508,7 +2593,7 @@ test iocmd.tf-24.10 {chan write, failed write, continue return is error} -match
rename foo {}
set res
} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-24.11 {chan write, failed write, custom return is error} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; return -code 777 BOOM!}
@@ -2522,7 +2607,7 @@ test iocmd.tf-24.11 {chan write, failed write, custom return is error} -match gl
rename foo {}
set res
} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-24.12 {chan write, failed write, non-numeric return is error} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; return BANG}
@@ -2536,7 +2621,7 @@ test iocmd.tf-24.12 {chan write, failed write, non-numeric return is error} -mat
rename foo {}
set res
} -result {{write rc* snarfsnarfsnarf} 1 {expected integer but got "BANG"}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-24.13 {chan write, failed write, level is ignored} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; return -level 55 -code 777 BOOM!}
@@ -2551,7 +2636,7 @@ test iocmd.tf-24.13 {chan write, failed write, level is ignored} -match glob -bo
rename foo {}
set res
} -result {{write rc* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "write"*}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-24.14 {chan write, no EAGAIN means that writing is allowed at this time, bug 2936225} -match glob -setup {
set res {}
proc foo {args} {
@@ -2570,7 +2655,7 @@ test iocmd.tf-24.14 {chan write, no EAGAIN means that writing is allowed at this
rename foo {}
unset res
} -result {{write rc* ABC} {}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-24.15 {chan write, EAGAIN means that writing is not allowed at this time, bug 2936225} -match glob -setup {
set res {}
proc foo {args} {
@@ -2590,10 +2675,161 @@ test iocmd.tf-24.15 {chan write, EAGAIN means that writing is not allowed at thi
} c]
set res
} -cleanup {
+ proc foo {args} {onfinal; set ::done-24.15 1; return 3}
+ after 1000 {set ::done-24.15 2}
+ vwait done-24.15
rename foo {}
unset res
} -result {{write rc* ABC} {watch rc* write} {}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
+
+test iocmd.tf-24.16 {chan write, note the background flush setup by close due to the EAGAIN leaving data in buffers.} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ # Note: The EAGAIN signals that the channel cannot accept
+ # write requests right now, this in turn causes the IO core to
+ # request the generation of writable events (see expected
+ # result below, and compare to case 24.14 above).
+ error EAGAIN
+ }
+ set c [chan create {r w} foo]
+} -body {
+ notes [inthread $c {
+ note [puts -nonewline $c ABC ; flush $c]
+ close $c
+ notes
+ } c]
+ # Replace handler with all-tracking one which doesn't error.
+ # This will tell us if a write-due-flush is there.
+ proc foo {args} { onfinal; note BG ; track ; set ::endbody-24.16 1}
+ # Flush (sic!) the event-queue to capture the write from a
+ # BG-flush.
+ after 1000 {set ::endbody-24.16 2}
+ vwait endbody-24.16
+ set res
+} -cleanup {
+ proc foo {args} {onfinal; set ::done-24.16 1; return 3}
+ after 1000 {set ::done-24.16 2}
+ vwait done-24.16
+ rename foo {}
+ unset res
+} -result {{write rc* ABC} {watch rc* write} {} BG {write rc* ABC}} \
+ -constraints {testchannel thread}
+
+test iocmd.tf-24.17.bug3522560 {postevent for transfered channel} \
+ -constraints {testchannel thread} -setup {
+ # This test exposes how the execution of postevent in the handler thread causes
+ # a crash if we are not properly injecting the events into the owning thread instead.
+ # With the injection the test will simply complete without crash.
+
+ set beat 10000
+ set drive 999
+ set data ...---...
+
+ proc LOG {text} {
+ #puts stderr "[thread::id]: $text"
+ return
+ }
+
+ proc POST {hi} {
+ LOG "-> [info level 0]"
+ chan postevent $hi read
+ LOG "<- [info level 0]"
+
+ set ::timer [after $::drive [info level 0]]
+ return
+ }
+
+ proc HANDLER {op ch args} {
+ lappend ::res [lrange [info level 0] 1 end]
+ LOG "-> [info level 0]"
+ set ret {}
+ switch -glob -- $op {
+ init* {set ret {initialize finalize watch read}}
+ watch {
+ set l [lindex $args 0]
+ if {[llength $l]} {
+ set ::timer [after $::drive [list POST $ch]]
+ } else {
+ after cancel $::timer
+ }
+ }
+ finalize {
+ catch { after cancel $::timer }
+ after 500 {set ::forever now}
+ }
+ read {
+ set ret $::data
+ set ::data {} ; # Next is EOF.
+ }
+ }
+ LOG "<- [info level 0] : $ret"
+ return $ret
+ }
+} -body {
+ LOG BEGIN
+ set ch [chan create {read} HANDLER]
+
+ set tid [thread::create {
+ proc LOG {text} {
+ #puts stderr "\t\t\t\t\t\t[thread::id]: $text"
+ return
+ }
+ LOG THREAD-STARTED
+ load {} Tcltest
+ proc bgerror s {
+ LOG BGERROR:$s
+ }
+ vwait forever
+ LOG THREAD-DONE
+ }]
+
+ testchannel cut $ch
+ thread::send $tid [list set thech $ch]
+ thread::send $tid [list set beat $beat]
+ thread::send -async $tid {
+ LOG SPLICE-BEG
+ testchannel splice $thech
+ LOG SPLICE-END
+ proc PROCESS {ch} {
+ LOG "-> [info level 0]"
+ if {[eof $ch]} {
+ close $ch
+ set ::done 1
+ set c <<EOF>>
+ } else {
+ set c [read $ch 1]
+ }
+ LOG "GOTCHAR: $c"
+ LOG "<- [info level 0]"
+ }
+ LOG THREAD-FILEEVENT
+ fconfigure $thech -translation binary -blocking 0
+ fileevent $thech readable [list PROCESS $thech]
+ LOG THREAD-NOEVENT-LOOP
+ set done 0
+ while {!$done} {
+ after $beat
+ LOG THREAD-HEARTBEAT
+ update
+ }
+ LOG THREAD-LOOP-DONE
+ thread::exit
+ }
+
+ LOG MAIN_WAITING
+ vwait forever
+ LOG MAIN_DONE
+
+ set res
+} -cleanup {
+ rename LOG {}
+ rename POST {}
+ rename HANDLER {}
+ unset beat drive data forever res tid ch
+} -match glob \
+ -result {{initialize rc* read} {watch rc* read} {read rc* 4096} {watch rc* {}} {watch rc* read} {read rc* 4096} {watch rc* {}} {finalize rc*}}
# --- === *** ###########################
# method cgetall
@@ -2609,7 +2845,7 @@ test iocmd.tf-25.1 {chan configure, cgetall, standard options} -match glob -body
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} \
+} -constraints {testchannel thread} \
-result {{-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *}}}
test iocmd.tf-25.2 {chan configure, cgetall, no options} -match glob -body {
set res {}
@@ -2622,7 +2858,7 @@ test iocmd.tf-25.2 {chan configure, cgetall, no options} -match glob -body {
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} \
+} -constraints {testchannel thread} \
-result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *}}}
test iocmd.tf-25.3 {chan configure, cgetall, regular result} -match glob -body {
set res {}
@@ -2638,7 +2874,7 @@ test iocmd.tf-25.3 {chan configure, cgetall, regular result} -match glob -body {
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} \
+} -constraints {testchannel thread} \
-result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *} -bar foo -snarf x}}
test iocmd.tf-25.4 {chan configure, cgetall, bad result, list of uneven length} -match glob -body {
set res {}
@@ -2655,7 +2891,7 @@ test iocmd.tf-25.4 {chan configure, cgetall, bad result, list of uneven length}
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{cgetall rc*} 1 {Expected list with even number of elements, got 1 element instead}}
+} -constraints {testchannel thread} -result {{cgetall rc*} 1 {Expected list with even number of elements, got 1 element instead}}
test iocmd.tf-25.5 {chan configure, cgetall, bad result, not a list} -match glob -body {
set res {}
proc foo {args} {
@@ -2671,7 +2907,7 @@ test iocmd.tf-25.5 {chan configure, cgetall, bad result, not a list} -match glob
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{cgetall rc*} 1 {unmatched open brace in list}}
+} -constraints {testchannel thread} -result {{cgetall rc*} 1 {unmatched open brace in list}}
test iocmd.tf-25.6 {chan configure, cgetall, error return} -match glob -body {
set res {}
proc foo {args} {
@@ -2687,7 +2923,7 @@ test iocmd.tf-25.6 {chan configure, cgetall, error return} -match glob -body {
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{cgetall rc*} 1 BOOM!}
+} -constraints {testchannel thread} -result {{cgetall rc*} 1 BOOM!}
test iocmd.tf-25.7 {chan configure, cgetall, break return is error} -match glob -body {
set res {}
proc foo {args} {
@@ -2704,7 +2940,7 @@ test iocmd.tf-25.7 {chan configure, cgetall, break return is error} -match glob
rename foo {}
set res
} -result {{cgetall rc*} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-25.8 {chan configure, cgetall, continue return is error} -match glob -body {
set res {}
proc foo {args} {
@@ -2721,7 +2957,7 @@ test iocmd.tf-25.8 {chan configure, cgetall, continue return is error} -match gl
rename foo {}
set res
} -result {{cgetall rc*} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-25.9 {chan configure, cgetall, custom return is error} -match glob -body {
set res {}
proc foo {args} {
@@ -2738,7 +2974,7 @@ test iocmd.tf-25.9 {chan configure, cgetall, custom return is error} -match glob
rename foo {}
set res
} -result {{cgetall rc*} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-25.10 {chan configure, cgetall, level is ignored} -match glob -body {
set res {}
proc foo {args} {
@@ -2756,7 +2992,7 @@ test iocmd.tf-25.10 {chan configure, cgetall, level is ignored} -match glob -bod
rename foo {}
set res
} -result {{cgetall rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cgetall"*}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
# --- === *** ###########################
# method configure
@@ -2774,7 +3010,7 @@ test iocmd.tf-26.1 {chan configure, set standard option} -match glob -body {
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{}}
+} -constraints {testchannel thread} -result {{}}
test iocmd.tf-26.2 {chan configure, set option, error return} -match glob -body {
set res {}
proc foo {args} {
@@ -2790,7 +3026,7 @@ test iocmd.tf-26.2 {chan configure, set option, error return} -match glob -body
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{configure rc* -rc-foo bar} 1 BOOM!}
+} -constraints {testchannel thread} -result {{configure rc* -rc-foo bar} 1 BOOM!}
test iocmd.tf-26.3 {chan configure, set option, ok return} -match glob -body {
set res {}
proc foo {args} {oninit configure; onfinal; track; return}
@@ -2802,7 +3038,7 @@ test iocmd.tf-26.3 {chan configure, set option, ok return} -match glob -body {
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{configure rc* -rc-foo bar} {}}
+} -constraints {testchannel thread} -result {{configure rc* -rc-foo bar} {}}
test iocmd.tf-26.4 {chan configure, set option, break return is error} -match glob -body {
set res {}
proc foo {args} {
@@ -2819,7 +3055,7 @@ test iocmd.tf-26.4 {chan configure, set option, break return is error} -match gl
rename foo {}
set res
} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-26.5 {chan configure, set option, continue return is error} -match glob -body {
set res {}
proc foo {args} {
@@ -2836,7 +3072,7 @@ test iocmd.tf-26.5 {chan configure, set option, continue return is error} -match
rename foo {}
set res
} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-26.6 {chan configure, set option, custom return is error} -match glob -body {
set res {}
proc foo {args} {
@@ -2853,7 +3089,7 @@ test iocmd.tf-26.6 {chan configure, set option, custom return is error} -match g
rename foo {}
set res
} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-26.7 {chan configure, set option, level is ignored} -match glob -body {
set res {}
proc foo {args} {
@@ -2871,7 +3107,7 @@ test iocmd.tf-26.7 {chan configure, set option, level is ignored} -match glob -b
rename foo {}
set res
} -result {{configure rc* -rc-foo bar} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "configure"*}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
# --- === *** ###########################
# method cget
@@ -2887,7 +3123,7 @@ test iocmd.tf-27.1 {chan configure, get option, ok return} -match glob -body {
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{cget rc* -rc-foo} foo}
+} -constraints {testchannel thread} -result {{cget rc* -rc-foo} foo}
test iocmd.tf-27.2 {chan configure, get option, error return} -match glob -body {
set res {}
proc foo {args} {
@@ -2903,7 +3139,7 @@ test iocmd.tf-27.2 {chan configure, get option, error return} -match glob -body
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{cget rc* -rc-foo} 1 BOOM!}
+} -constraints {testchannel thread} -result {{cget rc* -rc-foo} 1 BOOM!}
test iocmd.tf-27.3 {chan configure, get option, break return is error} -match glob -body {
set res {}
proc foo {args} {
@@ -2920,7 +3156,7 @@ test iocmd.tf-27.3 {chan configure, get option, break return is error} -match gl
rename foo {}
set res
} -result {{cget rc* -rc-foo} 1 BOOM!} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-27.4 {chan configure, get option, continue return is error} -match glob -body {
set res {}
proc foo {args} {
@@ -2937,7 +3173,7 @@ test iocmd.tf-27.4 {chan configure, get option, continue return is error} -match
rename foo {}
set res
} -result {{cget rc* -rc-foo} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-27.5 {chan configure, get option, custom return is error} -match glob -body {
set res {}
proc foo {args} {
@@ -2954,7 +3190,7 @@ test iocmd.tf-27.5 {chan configure, get option, custom return is error} -match g
rename foo {}
set res
} -result {{cget rc* -rc-foo} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-27.6 {chan configure, get option, level is ignored} -match glob -body {
set res {}
proc foo {args} {
@@ -2972,7 +3208,7 @@ test iocmd.tf-27.6 {chan configure, get option, level is ignored} -match glob -b
rename foo {}
set res
} -result {{cget rc* -rc-foo} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cget"*}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
# --- === *** ###########################
# method seek
@@ -2989,7 +3225,7 @@ test iocmd.tf-28.1 {chan tell, not supported by handler} -match glob -body {
rename foo {}
set res
} -result {-1} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.2 {chan tell, error return} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return -code error BOOM!}
@@ -3003,7 +3239,7 @@ test iocmd.tf-28.2 {chan tell, error return} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 current} 1 BOOM!} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.3 {chan tell, break return is error} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return -code break BOOM!}
@@ -3017,7 +3253,7 @@ test iocmd.tf-28.3 {chan tell, break return is error} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 current} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.4 {chan tell, continue return is error} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
@@ -3031,7 +3267,7 @@ test iocmd.tf-28.4 {chan tell, continue return is error} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 current} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.5 {chan tell, custom return is error} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return -code 222 BOOM!}
@@ -3045,7 +3281,7 @@ test iocmd.tf-28.5 {chan tell, custom return is error} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 current} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.6 {chan tell, level is ignored} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return -level 11 -code 222 BANG}
@@ -3060,7 +3296,7 @@ test iocmd.tf-28.6 {chan tell, level is ignored} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 current} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.7 {chan tell, regular return} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return 88}
@@ -3073,7 +3309,7 @@ test iocmd.tf-28.7 {chan tell, regular return} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 current} 88} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.8 {chan tell, negative return} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return -1}
@@ -3087,7 +3323,7 @@ test iocmd.tf-28.8 {chan tell, negative return} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 current} 1 {Tried to seek before origin}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.9 {chan tell, string return} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return BOGUS}
@@ -3101,7 +3337,7 @@ test iocmd.tf-28.9 {chan tell, string return} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 current} 1 {expected integer but got "BOGUS"}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.10 {chan seek, not supported by handler} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
@@ -3115,7 +3351,7 @@ test iocmd.tf-28.10 {chan seek, not supported by handler} -match glob -body {
rename foo {}
set res
} -result {1 {error during seek on "rc*": invalid argument}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.11 {chan seek, error return} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return -code error BOOM!}
@@ -3129,7 +3365,7 @@ test iocmd.tf-28.11 {chan seek, error return} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 start} 1 BOOM!} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.12 {chan seek, break return is error} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return -code break BOOM!}
@@ -3143,7 +3379,7 @@ test iocmd.tf-28.12 {chan seek, break return is error} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 start} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.13 {chan seek, continue return is error} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
@@ -3157,7 +3393,7 @@ test iocmd.tf-28.13 {chan seek, continue return is error} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 start} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.14 {chan seek, custom return is error} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return -code 99 BOOM!}
@@ -3171,7 +3407,7 @@ test iocmd.tf-28.14 {chan seek, custom return is error} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 start} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.15 {chan seek, level is ignored} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return -level 33 -code 99 BANG}
@@ -3186,7 +3422,7 @@ test iocmd.tf-28.15 {chan seek, level is ignored} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 start} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.16 {chan seek, bogus return, negative location} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return -45}
@@ -3200,7 +3436,7 @@ test iocmd.tf-28.16 {chan seek, bogus return, negative location} -match glob -bo
rename foo {}
set res
} -result {{seek rc* 0 start} 1 {Tried to seek before origin}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.17 {chan seek, bogus return, string return} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return BOGUS}
@@ -3214,7 +3450,7 @@ test iocmd.tf-28.17 {chan seek, bogus return, string return} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 start} 1 {expected integer but got "BOGUS"}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-28.18 {chan seek, ok result} -match glob -body {
set res {}
proc foo {args} {oninit seek; onfinal; track; return 23}
@@ -3227,7 +3463,7 @@ test iocmd.tf-28.18 {chan seek, ok result} -match glob -body {
rename foo {}
set res
} -result {{seek rc* 0 current} {}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
foreach {testname code} {
iocmd.tf-28.19.0 start
iocmd.tf-28.19.1 current
@@ -3245,7 +3481,7 @@ foreach {testname code} {
rename foo {}
set res
} -result [list [list seek rc* 0 $code] {}] \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
}
# --- === *** ###########################
@@ -3263,7 +3499,7 @@ test iocmd.tf-29.1 {chan blocking, no handler support} -match glob -body {
rename foo {}
set res
} -result {1} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-29.2 {chan blocking, no handler support} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
@@ -3277,7 +3513,7 @@ test iocmd.tf-29.2 {chan blocking, no handler support} -match glob -body {
rename foo {}
set res
} -result {{} 0} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-29.3 {chan blocking, retrieval, handler support} -match glob -body {
set res {}
proc foo {args} {oninit blocking; onfinal; track; note MUST_NOT_HAPPEN; return}
@@ -3290,7 +3526,7 @@ test iocmd.tf-29.3 {chan blocking, retrieval, handler support} -match glob -body
rename foo {}
set res
} -result {1} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-29.4 {chan blocking, resetting, handler support} -match glob -body {
set res {}
proc foo {args} {oninit blocking; onfinal; track; return}
@@ -3304,7 +3540,7 @@ test iocmd.tf-29.4 {chan blocking, resetting, handler support} -match glob -body
rename foo {}
set res
} -result {{blocking rc* 0} {} 0} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-29.5 {chan blocking, setting, handler support} -match glob -body {
set res {}
proc foo {args} {oninit blocking; onfinal; track; return}
@@ -3318,7 +3554,7 @@ test iocmd.tf-29.5 {chan blocking, setting, handler support} -match glob -body {
rename foo {}
set res
} -result {{blocking rc* 1} {} 1} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-29.6 {chan blocking, error return} -match glob -body {
set res {}
proc foo {args} {oninit blocking; onfinal; track; error BOOM!}
@@ -3333,7 +3569,7 @@ test iocmd.tf-29.6 {chan blocking, error return} -match glob -body {
rename foo {}
set res
} -result {{blocking rc* 0} 1 BOOM!} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-29.7 {chan blocking, break return is error} -match glob -body {
set res {}
proc foo {args} {oninit blocking; onfinal; track; return -code break BOOM!}
@@ -3347,7 +3583,7 @@ test iocmd.tf-29.7 {chan blocking, break return is error} -match glob -body {
rename foo {}
set res
} -result {{blocking rc* 0} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-29.8 {chan blocking, continue return is error} -match glob -body {
set res {}
proc foo {args} {oninit blocking; onfinal; track; return -code continue BOOM!}
@@ -3361,7 +3597,7 @@ test iocmd.tf-29.8 {chan blocking, continue return is error} -match glob -body {
rename foo {}
set res
} -result {{blocking rc* 0} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-29.9 {chan blocking, custom return is error} -match glob -body {
set res {}
proc foo {args} {oninit blocking; onfinal; track; return -code 44 BOOM!}
@@ -3375,7 +3611,7 @@ test iocmd.tf-29.9 {chan blocking, custom return is error} -match glob -body {
rename foo {}
set res
} -result {{blocking rc* 0} 1 *bad code*} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-29.10 {chan blocking, level is ignored} -match glob -body {
set res {}
proc foo {args} {oninit blocking; onfinal; track; return -level 99 -code 44 BANG}
@@ -3390,7 +3626,7 @@ test iocmd.tf-29.10 {chan blocking, level is ignored} -match glob -body {
rename foo {}
set res
} -result {{blocking rc* 0} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "blocking"*}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
test iocmd.tf-29.11 {chan blocking, regular return ok, value ignored} -match glob -body {
set res {}
proc foo {args} {oninit blocking; onfinal; track; return BOGUS}
@@ -3404,7 +3640,7 @@ test iocmd.tf-29.11 {chan blocking, regular return ok, value ignored} -match glo
rename foo {}
set res
} -result {{blocking rc* 0} 0 {}} \
- -constraints {testchannel testthread}
+ -constraints {testchannel thread}
# --- === *** ###########################
# method watch
@@ -3420,7 +3656,7 @@ test iocmd.tf-30.1 {chan watch, read interest, some return} -match glob -body {
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{watch rc* read} {watch rc* {}} {}}
+} -constraints {testchannel thread} -result {{watch rc* read} {watch rc* {}} {}}
test iocmd.tf-30.2 {chan watch, write interest, error return} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; return -code error BOOM!_IGNORED}
@@ -3433,7 +3669,7 @@ test iocmd.tf-30.2 {chan watch, write interest, error return} -match glob -body
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} -result {{watch rc* write} {watch rc* {}} {} {}}
+} -constraints {testchannel thread} -result {{watch rc* write} {watch rc* {}} {} {}}
test iocmd.tf-30.3 {chan watch, accumulated interests} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; return}
@@ -3448,7 +3684,7 @@ test iocmd.tf-30.3 {chan watch, accumulated interests} -match glob -body {
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} \
+} -constraints {testchannel thread} \
-result {{watch rc* write} {watch rc* {read write}} {watch rc* read} {watch rc* {}} {} {} {} {}}
test iocmd.tf-30.4 {chan watch, unchanged interest not forwarded} -match glob -body {
set res {}
@@ -3463,7 +3699,7 @@ test iocmd.tf-30.4 {chan watch, unchanged interest not forwarded} -match glob -b
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} \
+} -constraints {testchannel thread} \
-result {{watch rc* write} {watch rc* {read write}} {watch rc* write} {watch rc* {}} {} {} {}}
# --- === *** ###########################
@@ -3483,7 +3719,7 @@ test iocmd.tf-31.8 {chan postevent, bad input} -match glob -body {
} c]
rename foo {}
set res
-} -constraints {testchannel testthread} \
+} -constraints {testchannel thread} \
-result {{can not find reflected channel named "rc*"}}
# --- === *** ###########################
@@ -3494,12 +3730,15 @@ test iocmd.tf-31.8 {chan postevent, bad input} -match glob -body {
test iocmd.tf-32.0 {origin thread of moved channel gone} -match glob -body {
#puts <<$tcltest::mainThread>>main
- set tida [testthread create];#puts <<$tida>>
- set tidb [testthread create];#puts <<$tidb>>
+ set tida [thread::create -preserved];#puts <<$tida>>
+ thread::send $tida {load {} Tcltest}
+
+ set tidb [thread::create -preserved];#puts <<$tidb>>
+ thread::send $tidb {load {} Tcltest}
# Set up channel in thread
- testthread send $tida $helperscript
- set chan [testthread send $tida {
+ thread::send $tida $helperscript
+ set chan [thread::send $tida {
proc foo {args} {oninit seek; onfinal; track; return}
set chan [chan create {r w} foo]
fconfigure $chan -buffering none
@@ -3507,67 +3746,82 @@ test iocmd.tf-32.0 {origin thread of moved channel gone} -match glob -body {
}]
# Move channel to 2nd thread.
- testthread send $tida [list testchannel cut $chan]
- testthread send $tidb [list testchannel splice $chan]
+ thread::send $tida [list testchannel cut $chan]
+ thread::send $tidb [list testchannel splice $chan]
# Kill origin thread, then access channel from 2nd thread.
- testthread send -async $tida {testthread exit}
- after 100
+ thread::release $tida
set res {}
- lappend res [catch {testthread send $tidb [list puts $chan shoo]} msg] $msg
+ lappend res [catch {thread::send $tidb [list puts $chan shoo]} msg] $msg
- lappend res [catch {testthread send $tidb [list tell $chan]} msg] $msg
- lappend res [catch {testthread send $tidb [list seek $chan 1]} msg] $msg
- lappend res [catch {testthread send $tidb [list gets $chan]} msg] $msg
- lappend res [catch {testthread send $tidb [list close $chan]} msg] $msg
- tcltest::threadReap
+ lappend res [catch {thread::send $tidb [list tell $chan]} msg] $msg
+ lappend res [catch {thread::send $tidb [list seek $chan 1]} msg] $msg
+ lappend res [catch {thread::send $tidb [list gets $chan]} msg] $msg
+ lappend res [catch {thread::send $tidb [list close $chan]} msg] $msg
+ thread::release $tidb
set res
-} -constraints {testchannel testthread} \
+} -constraints {testchannel thread} \
-result {1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
+
+# The test iocmd.tf-32.1 unavoidably exhibits a memory leak. We are testing
+# the ability of the reflected channel system to react to the situation where
+# the thread in which the driver routines runs exits during driver operations.
+# In this case, thread exit handlers signal back to the owner thread so that the
+# channel operation does not hang. There's no way to test this without actually
+# exiting a thread in mid-operation, and that action is unavoidably leaky (which
+# is why [thread::exit] is advised against).
+#
+# 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
- set tida [testthread create];#puts <<$tida>>
- set tidb [testthread create];#puts <<$tidb>>
+ set tida [thread::create -preserved];#puts <<$tida>>
+ thread::send $tida {load {} Tcltest}
+ set tidb [thread::create -preserved];#puts <<$tidb>>
+ thread::send $tidb {load {} Tcltest}
# Set up channel in thread
- set chan [testthread send $tida $helperscript]
- set chan [testthread send $tida {
+ thread::send $tida $helperscript
+ set chan [thread::send $tida {
proc foo {args} {
oninit; onfinal; track;
# destroy thread during channel access
- testthread exit
- return}
+ thread::exit
+ }
set chan [chan create {r w} foo]
fconfigure $chan -buffering none
set chan
}]
# Move channel to 2nd thread.
- testthread send $tida [list testchannel cut $chan]
- testthread send $tidb [list testchannel splice $chan]
+ thread::send $tida [list testchannel cut $chan]
+ thread::send $tidb [list testchannel splice $chan]
# Run access from thread B, wait for response from A (A is not
# using event loop at this point, so the event pile up in the
# queue.
- testthread send $tidb [list set chan $chan]
- testthread send $tidb [list set mid $tcltest::mainThread]
- testthread send -async $tidb {
+ thread::send $tidb [list set chan $chan]
+ thread::send $tidb [list set mid [thread::id]]
+ thread::send -async $tidb {
# wait a bit, give the main thread the time to start its event
# loop to wait for the response from B
after 2000
catch { puts $chan shoo } res
- testthread send -async $mid [list set ::res $res]
+ thread::send -async $mid [list set ::res $res]
}
vwait ::res
- tcltest::threadReap
+ catch {thread::release $tida}
+ thread::release $tidb
set res
-} -constraints {testchannel testthread} \
+} -constraints {testchannel thread notValgrind} \
-result {Owner lost}
# ### ### ### ######### ######### #########
diff --git a/tests/ioTrans.test b/tests/ioTrans.test
index d8defcc..7f4f7f0 100644
--- a/tests/ioTrans.test
+++ b/tests/ioTrans.test
@@ -16,12 +16,15 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
# Custom constraints used in this file
testConstraint testchannel [llength [info commands testchannel]]
-testConstraint testthread [llength [info commands testthread]]
+testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
# testchannel cut|splice Both needed to test the reflection in threads.
-# testthread send
+# thread::send
#----------------------------------------------------------------------
@@ -280,6 +283,8 @@ test iortrans-3.1 {chan finalize, handler destruction has no effect on channel}
lappend res [catch {close $c} msg] $msg
lappend res [file channels file*]
lappend res [file channels rt*]
+} -cleanup {
+ tempdone
} -result {{initialize rt* {read write}} file* file* {} 1 {invalid command name "foo"} {} {}}
test iortrans-3.2 {chan finalize, for close} -setup {
set res {}
@@ -297,6 +302,7 @@ test iortrans-3.2 {chan finalize, for close} -setup {
lappend res [info command foo]
} -cleanup {
rename foo {}
+ tempdone
} -result {{initialize rt* {read write}} file* {finalize rt*} {} foo}
test iortrans-3.3 {chan finalize, for close, error, close error} -setup {
set res {}
@@ -312,6 +318,7 @@ test iortrans-3.3 {chan finalize, for close, error, close error} -setup {
lappend res [file channels rt*]
} -cleanup {
rename foo {}
+ tempdone
} -result {{initialize rt* {read write}} file* {finalize rt*} 1 5 {}}
test iortrans-3.4 {chan finalize, for close, error, close error} -setup {
set res {}
@@ -325,6 +332,7 @@ test iortrans-3.4 {chan finalize, for close, error, close error} -setup {
lappend res [catch {close $c} msg] $msg $::errorInfo
} -cleanup {
rename foo {}
+ tempdone
} -result {{initialize rt* {read write}} file* {finalize rt*} 1 FOO {FOO
*"close $c"}}
test iortrans-3.5 {chan finalize, for close, arbitrary result, ignored} -setup {
@@ -339,6 +347,7 @@ test iortrans-3.5 {chan finalize, for close, arbitrary result, ignored} -setup {
lappend res [catch {close $c} msg] $msg
} -cleanup {
rename foo {}
+ tempdone
} -result {{initialize rt* {read write}} file* {finalize rt*} 0 {}}
test iortrans-3.6 {chan finalize, for close, break, close error} -setup {
set res {}
@@ -352,6 +361,7 @@ test iortrans-3.6 {chan finalize, for close, break, close error} -setup {
lappend res [catch {close $c} msg] $msg
} -cleanup {
rename foo {}
+ tempdone
} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
test iortrans-3.7 {chan finalize, for close, continue, close error} -setup {
set res {}
@@ -365,6 +375,7 @@ test iortrans-3.7 {chan finalize, for close, continue, close error} -setup {
lappend res [catch {close $c} msg] $msg
} -cleanup {
rename foo {}
+ tempdone
} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
test iortrans-3.8 {chan finalize, for close, custom code, close error} -setup {
set res {}
@@ -378,6 +389,7 @@ test iortrans-3.8 {chan finalize, for close, custom code, close error} -setup {
lappend res [catch {close $c} msg] $msg
} -cleanup {
rename foo {}
+ tempdone
} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
test iortrans-3.9 {chan finalize, for close, ignore level, close error} -setup {
set res {}
@@ -392,6 +404,7 @@ test iortrans-3.9 {chan finalize, for close, ignore level, close error} -setup {
noteOpts $opt
} -match glob -cleanup {
rename foo {}
+ tempdone
} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}}
# --- === *** ###########################
@@ -526,7 +539,46 @@ test iortrans-4.8 {chan read, read, bug 2921116} -setup {
tempdone
rename foo {}
} -result {{read rt* {test data
-}} file*}
+}} {}}
+test iortrans-4.8.1 {chan read, bug 721ec69271} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {fd args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ # Kill and recreate transform while it is operating
+ chan pop $fd
+ chan push $fd [list foo $fd]
+ }
+ set c [chan push [set c [tempchan]] [list foo $c]]
+ chan configure $c -buffersize 2
+ lappend res [read $c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* te} {read rt* st} {read rt* { d}} {read rt* at} {read rt* {a
+}} {}}
+test iortrans-4.8.2 {chan read, bug 721ec69271} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {fd args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ # Kill and recreate transform while it is operating
+ chan pop $fd
+ chan push $fd [list foo $fd]
+ return x
+ }
+ set c [chan push [set c [tempchan]] [list foo $c]]
+ chan configure $c -buffersize 1
+ lappend res [read $c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* t} {read rt* e} {read rt* s} {read rt* t} {read rt* { }} {read rt* d} {read rt* a} {read rt* t} {read rt* a} {read rt* {
+}} {}}
test iortrans-4.9 {chan read, gets, bug 2921116} -setup {
set res {}
} -match glob -body {
@@ -544,7 +596,7 @@ test iortrans-4.9 {chan read, gets, bug 2921116} -setup {
tempdone
rename foo {}
} -result {{read rt* {test data
-}} file*}
+}} {}}
# --- === *** ###########################
# method write (via puts)
@@ -1033,6 +1085,8 @@ test iortrans-11.2 {delete interp of reflected transform} -setup {
chan event $c readable no-op
}
interp delete slave
+} -cleanup {
+ tempdone
} -result {}
# ### ### ### ######### ######### #########
@@ -1046,22 +1100,6 @@ test iortrans-11.2 {delete interp of reflected transform} -setup {
## gaps due to tests not applicable to forwarding are left to keep this
## association.
-# Duplicate of code in "thread.test", and "ioCmd.test". Find a better way of
-# doing this without duplication. Maybe placement into a proc which transforms
-# to nop after the first call, and placement of its defintion in a central
-# location.
-
-if {[testConstraint testthread]} {
- testthread errorproc ThreadError
- proc ThreadError {id info} {
- global threadError
- set threadError $info
- }
- proc ThreadNullError {id info} {
- # ignore
- }
-}
-
# ### ### ### ######### ######### #########
## Helper command. Runs a script in a separate thread and returns the result.
## A channel is transfered into the thread as well, and a list of configuation
@@ -1069,7 +1107,8 @@ if {[testConstraint testthread]} {
proc inthread {chan script args} {
# Test thread.
- set tid [testthread create]
+ set tid [thread::create -preserved]
+ thread::send $tid {load {} Tcltest}
# Init thread configuration.
# - Listed variables
@@ -1078,10 +1117,10 @@ proc inthread {chan script args} {
foreach v $args {
upvar 1 $v x
- testthread send $tid [list set $v $x]
+ thread::send $tid [list set $v $x]
}
- testthread send $tid [list set mid $tcltest::mainThread]
- testthread send $tid {
+ thread::send $tid [list set mid [thread::id]]
+ thread::send $tid {
proc notes {} {
return $::notes
}
@@ -1092,27 +1131,27 @@ proc inthread {chan script args} {
} $opts]
}
}
- testthread send $tid [list proc s {} [list uplevel 1 $script]]; # (*)
+ thread::send $tid [list proc s {} [list uplevel 1 $script]]; # (*)
# Transfer channel (cut/splice aka detach/attach)
testchannel cut $chan
- testthread send $tid [list testchannel splice $chan]
+ thread::send $tid [list testchannel splice $chan]
# Run test script, also run local event loop! The local event loop waits
# for the result to come back. It is also necessary for the execution of
# forwarded channel operations.
set ::tres ""
- testthread send -async $tid {
+ thread::send -async $tid {
after 50
catch {s} res; # This runs the script, 's' was defined at (*)
- testthread send -async $mid [list set ::tres $res]
+ thread::send -async $mid [list set ::tres $res]
}
vwait ::tres
# Remove test thread, and return the captured result.
- tcltest::threadReap
+ thread::release $tid
return $::tres
}
@@ -1120,7 +1159,7 @@ proc inthread {chan script args} {
test iortrans.tf-3.2 {chan finalize, for close} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
lappend ::res $args
handle.initialize
@@ -1139,7 +1178,7 @@ test iortrans.tf-3.2 {chan finalize, for close} -setup {
} -result {{initialize rt* {read write}} file* {finalize rt*} {} foo}
test iortrans.tf-3.3 {chan finalize, for close, error, close error} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
lappend ::res $args
handle.initialize
@@ -1157,7 +1196,7 @@ test iortrans.tf-3.3 {chan finalize, for close, error, close error} -setup {
} -result {{initialize rt* {read write}} file* {finalize rt*} 1 5 {}}
test iortrans.tf-3.4 {chan finalize, for close, error, close errror} -setup {
set res {}
-} -constraints {testchannel testthread} -body {
+} -constraints {testchannel thread} -body {
proc foo {args} {
lappend ::res $args
handle.initialize
@@ -1173,7 +1212,7 @@ test iortrans.tf-3.4 {chan finalize, for close, error, close errror} -setup {
} -result {{initialize rt* {read write}} file* {finalize rt*} 1 FOO}
test iortrans.tf-3.5 {chan finalize, for close, arbitrary result} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
lappend ::res $args
handle.initialize
@@ -1189,7 +1228,7 @@ test iortrans.tf-3.5 {chan finalize, for close, arbitrary result} -setup {
} -result {{initialize rt* {read write}} file* {finalize rt*} 0 {}}
test iortrans.tf-3.6 {chan finalize, for close, break, close error} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
lappend ::res $args
handle.initialize
@@ -1205,7 +1244,7 @@ test iortrans.tf-3.6 {chan finalize, for close, break, close error} -setup {
} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
test iortrans.tf-3.7 {chan finalize, for close, continue, close error} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
lappend ::res $args
handle.initialize
@@ -1221,7 +1260,7 @@ test iortrans.tf-3.7 {chan finalize, for close, continue, close error} -setup {
} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
test iortrans.tf-3.8 {chan finalize, for close, custom code, close error} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
lappend ::res $args
handle.initialize
@@ -1237,7 +1276,7 @@ test iortrans.tf-3.8 {chan finalize, for close, custom code, close error} -setup
} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
test iortrans.tf-3.9 {chan finalize, for close, ignore level, close error} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
lappend ::res $args
handle.initialize
@@ -1258,7 +1297,7 @@ test iortrans.tf-3.9 {chan finalize, for close, ignore level, close error} -setu
test iortrans.tf-4.1 {chan read, transform call and return} -setup {
set res {}
-} -constraints {testchannel testthread} -body {
+} -constraints {testchannel thread} -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1278,7 +1317,7 @@ test iortrans.tf-4.1 {chan read, transform call and return} -setup {
}} snarf}
test iortrans.tf-4.2 {chan read, for non-readable channel} -setup {
set res {}
-} -constraints {testchannel testthread} -body {
+} -constraints {testchannel thread} -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1296,7 +1335,7 @@ test iortrans.tf-4.2 {chan read, for non-readable channel} -setup {
} -match glob -result {1 {channel "file*" wasn't opened for reading}}
test iortrans.tf-4.3 {chan read, error return} -setup {
set res {}
-} -constraints {testchannel testthread} -body {
+} -constraints {testchannel thread} -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1316,7 +1355,7 @@ test iortrans.tf-4.3 {chan read, error return} -setup {
}} 1 BOOM!}
test iortrans.tf-4.4 {chan read, break return is error} -setup {
set res {}
-} -constraints {testchannel testthread} -body {
+} -constraints {testchannel thread} -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1336,7 +1375,7 @@ test iortrans.tf-4.4 {chan read, break return is error} -setup {
}} 1 *bad code*}
test iortrans.tf-4.5 {chan read, continue return is error} -setup {
set res {}
-} -constraints {testchannel testthread} -body {
+} -constraints {testchannel thread} -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1356,7 +1395,7 @@ test iortrans.tf-4.5 {chan read, continue return is error} -setup {
}} 1 *bad code*}
test iortrans.tf-4.6 {chan read, custom return is error} -setup {
set res {}
-} -constraints {testchannel testthread} -body {
+} -constraints {testchannel thread} -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1376,7 +1415,7 @@ test iortrans.tf-4.6 {chan read, custom return is error} -setup {
}} 1 *bad code*}
test iortrans.tf-4.7 {chan read, level is squashed} -setup {
set res {}
-} -constraints {testchannel testthread} -body {
+} -constraints {testchannel thread} -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1401,7 +1440,7 @@ test iortrans.tf-4.7 {chan read, level is squashed} -setup {
test iortrans.tf-5.1 {chan write, regular write} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1421,7 +1460,7 @@ test iortrans.tf-5.1 {chan write, regular write} -setup {
} -result {{write rt* snarf} transformresult}
test iortrans.tf-5.2 {chan write, no write is ok, no change to file} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1441,7 +1480,7 @@ test iortrans.tf-5.2 {chan write, no write is ok, no change to file} -setup {
} -result {{write rt* snarfsnarfsnarf} {test data}}
test iortrans.tf-5.3 {chan write, failed write} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1461,7 +1500,7 @@ test iortrans.tf-5.3 {chan write, failed write} -setup {
} -result {{write rt* snarfsnarfsnarf} 1 FAIL!}
test iortrans.tf-5.4 {chan write, non-writable channel} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1483,7 +1522,7 @@ test iortrans.tf-5.4 {chan write, non-writable channel} -setup {
} -result {1 {channel "file*" wasn't opened for writing}}
test iortrans.tf-5.5 {chan write, failed write, error return} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1505,7 +1544,7 @@ test iortrans.tf-5.5 {chan write, failed write, error return} -setup {
} -result {{write rt* snarfsnarfsnarf} 1 BOOM!}
test iortrans.tf-5.6 {chan write, failed write, error return} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1527,7 +1566,7 @@ test iortrans.tf-5.6 {chan write, failed write, error return} -setup {
} -result {{write rt* snarfsnarfsnarf} 1 BOOM!}
test iortrans.tf-5.7 {chan write, failed write, break return is error} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1549,7 +1588,7 @@ test iortrans.tf-5.7 {chan write, failed write, break return is error} -setup {
} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
test iortrans.tf-5.8 {chan write, failed write, continue return is error} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1570,7 +1609,7 @@ test iortrans.tf-5.8 {chan write, failed write, continue return is error} -setup
} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
test iortrans.tf-5.9 {chan write, failed write, custom return is error} -setup {
set res {}
-} -constraints {testchannel testthread} -body {
+} -constraints {testchannel thread} -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1592,7 +1631,7 @@ test iortrans.tf-5.9 {chan write, failed write, custom return is error} -setup {
} -match glob -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
test iortrans.tf-5.10 {chan write, failed write, level is ignored} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize
handle.finalize
@@ -1619,7 +1658,7 @@ test iortrans.tf-5.10 {chan write, failed write, level is ignored} -setup {
test iortrans.tf-6.1 {chan read, read limits} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize limit?
handle.finalize
@@ -1640,7 +1679,7 @@ test iortrans.tf-6.1 {chan read, read limits} -setup {
}} {limit? rt*} @@}
test iortrans.tf-6.2 {chan read, read transform drain on eof} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize drain
handle.finalize
@@ -1665,7 +1704,7 @@ test iortrans.tf-6.2 {chan read, read transform drain on eof} -setup {
test iortrans.tf-7.1 {chan write, write clears read buffers} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize clear
handle.finalize
@@ -1686,7 +1725,7 @@ test iortrans.tf-7.1 {chan write, write clears read buffers} -setup {
} -result {{clear rt*} {write rt* snarf}}
test iortrans.tf-7.2 {seek clears read buffers} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize clear
handle.finalize
@@ -1705,7 +1744,7 @@ test iortrans.tf-7.2 {seek clears read buffers} -setup {
} -result {{clear rt*}}
test iortrans.tf-7.3 {clear, any result is ignored} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize clear
handle.finalize
@@ -1728,7 +1767,7 @@ test iortrans.tf-7.3 {clear, any result is ignored} -setup {
test iortrans.tf-8.1 {seek flushes write buffers, ignores data} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize flush
handle.finalize
@@ -1755,7 +1794,7 @@ test iortrans.tf-8.1 {seek flushes write buffers, ignores data} -setup {
} -result {{flush rt*} {flush rt*} | {} | {teXt data}}
test iortrans.tf-8.2 {close flushes write buffers, writes data} -setup {
set res {}
-} -constraints {testchannel testthread} -match glob -body {
+} -constraints {testchannel thread} -match glob -body {
proc foo {args} {
handle.initialize flush
lappend ::res $args
@@ -1785,13 +1824,15 @@ test iortrans.tf-8.2 {close flushes write buffers, writes data} -setup {
test iortrans.tf-11.0 {origin thread of moved transform gone} -setup {
#puts <<$tcltest::mainThread>>main
- set tida [testthread create]; #puts <<$tida>>
- set tidb [testthread create]; #puts <<$tidb>>
-} -constraints {testchannel testthread} -match glob -body {
+ set tida [thread::create -preserved]; #puts <<$tida>>
+ thread::send $tida {load {} Tcltest}
+ set tidb [thread::create -preserved]; #puts <<$tida>>
+ thread::send $tidb {load {} Tcltest}
+} -constraints {testchannel thread} -match glob -body {
# Set up channel in thread
- testthread send $tida $helperscript
- testthread send $tidb $helperscript
- set chan [testthread send $tida {
+ thread::send $tida $helperscript
+ thread::send $tidb $helperscript
+ set chan [thread::send $tida {
proc foo {args} {
handle.initialize clear drain flush limit? read write
handle.finalize
@@ -1802,65 +1843,73 @@ test iortrans.tf-11.0 {origin thread of moved transform gone} -setup {
fconfigure $chan -buffering none
set chan
}]
+
# Move channel to 2nd thread, transform goes with it.
- testthread send $tida [list testchannel cut $chan]
- testthread send $tidb [list testchannel splice $chan]
+ thread::send $tida [list testchannel cut $chan]
+ thread::send $tidb [list testchannel splice $chan]
+
# Kill origin thread, then access channel from 2nd thread.
- testthread send -async $tida {testthread exit}
- after 50
- set res {}
- lappend res [catch {testthread send $tidb [list puts $chan shoo]} msg] $msg
- lappend res [catch {testthread send $tidb [list tell $chan]} msg] $msg
- lappend res [catch {testthread send $tidb [list seek $chan 1]} msg] $msg
- lappend res [catch {testthread send $tidb [list gets $chan]} msg] $msg
- lappend res [catch {testthread send $tidb [list close $chan]} msg] $msg
+ thread::release -wait $tida
+
+ set res {}
+ lappend res [catch {thread::send $tidb [list puts $chan shoo]} msg] $msg
+ lappend res [catch {thread::send $tidb [list tell $chan]} msg] $msg
+ lappend res [catch {thread::send $tidb [list seek $chan 1]} msg] $msg
+ lappend res [catch {thread::send $tidb [list gets $chan]} msg] $msg
+ lappend res [catch {thread::send $tidb [list close $chan]} msg] $msg
# The 'tell' is ok, as it passed through the transform to the base
# channel without invoking the transform handler.
} -cleanup {
- testthread send $tidb tempdone
- tcltest::threadReap
+ thread::send $tidb tempdone
+ thread::release $tidb
} -result {1 {Owner lost} 0 0 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
+
+testConstraint notValgrind [expr {![testConstraint valgrind]}]
+
test iortrans.tf-11.1 {origin thread of moved transform destroyed during access} -setup {
#puts <<$tcltest::mainThread>>main
- set tida [testthread create]; #puts <<$tida>>
- set tidb [testthread create]; #puts <<$tidb>>
-} -constraints {testchannel testthread} -match glob -body {
+ set tida [thread::create -preserved]; #puts <<$tida>>
+ thread::send $tida {load {} Tcltest}
+ set tidb [thread::create -preserved]; #puts <<$tidb>>
+ thread::send $tidb {load {} Tcltest}
+} -constraints {testchannel thread notValgrind} -match glob -body {
# Set up channel in thread
- testthread send $tida $helperscript
- testthread send $tidb $helperscript
- set chan [testthread send $tida {
+ thread::send $tida $helperscript
+ thread::send $tidb $helperscript
+ set chan [thread::send $tida {
proc foo {args} {
handle.initialize clear drain flush limit? read write
handle.finalize
lappend ::res $args
# destroy thread during channel access
- testthread exit
- return
+ thread::exit
}
set chan [chan push [tempchan] foo]
fconfigure $chan -buffering none
set chan
}]
+
# Move channel to 2nd thread, transform goes with it.
- testthread send $tida [list testchannel cut $chan]
- testthread send $tidb [list testchannel splice $chan]
+ thread::send $tida [list testchannel cut $chan]
+ thread::send $tidb [list testchannel splice $chan]
+
# Run access from thread B, wait for response from A (A is not using event
# loop at this point, so the event pile up in the queue.
- testthread send $tidb [list set chan $chan]
- testthread send $tidb [list set mid $tcltest::mainThread]
- testthread send -async $tidb {
+ thread::send $tidb [list set chan $chan]
+ thread::send $tidb [list set mid [thread::id]]
+ thread::send -async $tidb {
# Wait a bit, give the main thread the time to start its event loop to
# wait for the response from B
after 50
catch { puts $chan shoo } res
catch { close $chan }
- testthread send -async $mid [list set ::res $res]
+ thread::send -async $mid [list set ::res $res]
}
vwait ::res
- return $res
+ set res
} -cleanup {
- testthread send $tidb tempdone
- tcltest::threadReap
+ thread::send $tidb tempdone
+ thread::release $tidb
} -result {Owner lost}
# ### ### ### ######### ######### #########
diff --git a/tests/iogt.test b/tests/iogt.test
index 60d7ab8..ded8bb9 100644
--- a/tests/iogt.test
+++ b/tests/iogt.test
@@ -14,6 +14,10 @@ if {[catch {package require tcltest 2.1}]} {
puts stderr "Skipping tests in [info script]. tcltest 2.1 required."
return
}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
namespace eval ::tcl::test::iogt {
namespace import ::tcltest::*
@@ -216,6 +220,26 @@ proc id_fulltrail {var op data} {
return $res
}
+proc id_torture {chan op data} {
+ switch -- $op {
+ create/write -
+ create/read -
+ delete/write -
+ delete/read -
+ clear_read {;#ignore}
+ flush/write -
+ flush/read {}
+ write -
+ read {
+ testchannel unstack $chan
+ testchannel transform $chan \
+ -command [namespace code [list id_torture $chan]]
+ return $data
+ }
+ query/maxRead {return -1}
+ }
+}
+
proc counter {var op data} {
namespace upvar [namespace current] $var n
@@ -322,6 +346,11 @@ proc audit_ops {var -attach channel} {
proc audit_flow {var -attach channel} {
testchannel transform $channel -command [namespace code [list id_fulltrail $var]]
}
+
+proc torture {-attach channel} {
+ testchannel transform $channel -command [namespace code [list id_torture $channel]]
+}
+
proc stopafter {var n -attach channel} {
namespace upvar [namespace current] $var vn
set vn $n
@@ -542,6 +571,16 @@ delete/read {} *ignored*
flush/write {} {}
delete/write {} *ignored*}
+test iogt-2.4 {basic I/O, mixed trail} {testchannel} {
+ set fh [open $path(dummy) r]
+ torture -attach $fh
+ chan configure $fh -buffersize 2
+ set x [read $fh]
+ testchannel unstack $fh
+ close $fh
+ set x
+} {}
+
test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} -setup {
proc DoneCopy {n {err {}}} {
variable copy 1
diff --git a/tests/lindex.test b/tests/lindex.test
index 07abff8..b86e2e0 100644
--- a/tests/lindex.test
+++ b/tests/lindex.test
@@ -17,6 +17,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
set minus -
testConstraint testevalex [llength [info commands testevalex]]
diff --git a/tests/link.test b/tests/link.test
index 60d0799..00e490c 100644
--- a/tests/link.test
+++ b/tests/link.test
@@ -16,6 +16,9 @@ if {"::tcltest" ni [namespace children]} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testlink [llength [info commands testlink]]
foreach i {int real bool string} {
diff --git a/tests/listObj.test b/tests/listObj.test
index 53017b1..d7fb46c 100644
--- a/tests/listObj.test
+++ b/tests/listObj.test
@@ -16,6 +16,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testobj [llength [info commands testobj]]
catch {unset x}
@@ -193,6 +196,10 @@ test listobj-10.1 {Bug [2971669]} {*}{
-result {{a b c d e} {} {a b c d e f}}
}
+test listobj-11.1 {Bug 3598580: Tcl_ListObjReplace refcount management} testobj {
+ testobj bug3598580
+} 123
+
# cleanup
::tcltest::cleanupTests
return
diff --git a/tests/lmap.test b/tests/lmap.test
new file mode 100644
index 0000000..08035d9
--- /dev/null
+++ b/tests/lmap.test
@@ -0,0 +1,471 @@
+# Commands covered: lmap, continue, break
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 2011 Trevor Davel
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: $
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+unset -nocomplain a b i x
+
+# ----- Non-compiled operation -----------------------------------------------
+
+# Basic "lmap" operation (non-compiled)
+test lmap-1.1 {basic lmap tests} {
+ set a {}
+ lmap i {a b c d} {
+ set a [concat $a $i]
+ }
+} {a {a b} {a b c} {a b c d}}
+test lmap-1.2 {basic lmap tests} {
+ lmap i {a b {{c d} e} {123 {{x}}}} {
+ set i
+ }
+} {a b {{c d} e} {123 {{x}}}}
+test lmap-1.2a {basic lmap tests} {
+ lmap i {a b {{c d} e} {123 {{x}}}} {
+ return -level 0 $i
+ }
+} {a b {{c d} e} {123 {{x}}}}
+test lmap-1.4 {basic lmap tests} -returnCodes error -body {
+ lmap
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-1.6 {basic lmap tests} -returnCodes error -body {
+ lmap i
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-1.8 {basic lmap tests} -returnCodes error -body {
+ lmap i j
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-1.10 {basic lmap tests} -returnCodes error -body {
+ lmap i j k l
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-1.11 {basic lmap tests} {
+ lmap i {} {
+ set i
+ }
+} {}
+test lmap-1.12 {basic lmap tests} {
+ lmap i {} {
+ return -level 0 x
+ }
+} {}
+test lmap-1.13 {lmap errors} -returnCodes error -body {
+ lmap {{a}{b}} {1 2 3} {}
+} -result {list element in braces followed by "{b}" instead of space}
+test lmap-1.14 {lmap errors} -returnCodes error -body {
+ lmap a {{1 2}3} {}
+} -result {list element in braces followed by "3" instead of space}
+unset -nocomplain a
+test lmap-1.15 {lmap errors} -setup {
+ unset -nocomplain a
+} -body {
+ set a(0) 44
+ list [catch {lmap a {1 2 3} {}} msg o] $msg $::errorInfo
+} -result {1 {can't set "a": variable is array} {can't set "a": variable is array
+ (setting lmap loop variable "a")
+ invoked from within
+"lmap a {1 2 3} {}"}}
+test lmap-1.16 {lmap errors} -returnCodes error -body {
+ lmap {} {} {}
+} -result {lmap varlist is empty}
+unset -nocomplain a
+
+# Parallel "lmap" operation (non-compiled)
+test lmap-2.1 {parallel lmap tests} {
+ lmap {a b} {1 2 3 4} {
+ list $b $a
+ }
+} {{2 1} {4 3}}
+test lmap-2.2 {parallel lmap tests} {
+ lmap {a b} {1 2 3 4 5} {
+ list $b $a
+ }
+} {{2 1} {4 3} {{} 5}}
+test lmap-2.3 {parallel lmap tests} {
+ lmap a {1 2 3} b {4 5 6} {
+ list $b $a
+ }
+} {{4 1} {5 2} {6 3}}
+test lmap-2.4 {parallel lmap tests} {
+ lmap a {1 2 3} b {4 5 6 7 8} {
+ list $b $a
+ }
+} {{4 1} {5 2} {6 3} {7 {}} {8 {}}}
+test lmap-2.5 {parallel lmap tests} {
+ lmap {a b} {a b A B aa bb} c {c C cc CC} {
+ list $a $b $c
+ }
+} {{a b c} {A B C} {aa bb cc} {{} {} CC}}
+test lmap-2.6 {parallel lmap tests} {
+ lmap a {1 2 3} b {1 2 3} c {1 2 3} d {1 2 3} e {1 2 3} {
+ list $a$b$c$d$e
+ }
+} {11111 22222 33333}
+test lmap-2.7 {parallel lmap tests} {
+ lmap a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
+ set x $a$b$c$d$e
+ }
+} {{1111 2} 222 33 4}
+test lmap-2.8 {parallel lmap tests} {
+ lmap a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
+ join [list $a $b $c $d $e] .
+ }
+} {{.1.1.1.1 2} .2.2.2. .3..3. ...4.}
+test lmap-2.9 {lmap only sets vars if repeating loop} {
+ namespace eval ::lmap_test {
+ set rgb {65535 0 0}
+ lmap {r g b} [set rgb] {}
+ set ::x "r=$r, g=$g, b=$b"
+ }
+ namespace delete ::lmap_test
+ set x
+} {r=65535, g=0, b=0}
+test lmap-2.10 {lmap only supports local scalar variables} -setup {
+ unset -nocomplain a
+} -body {
+ lmap {a(3)} {1 2 3 4} {set {a(3)}}
+} -result {1 2 3 4}
+unset -nocomplain a
+
+# "lmap" with "continue" and "break" (non-compiled)
+test lmap-3.1 {continue tests} {
+ lmap i {a b c d} {
+ if {[string compare $i "b"] == 0} continue
+ set i
+ }
+} {a c d}
+test lmap-3.2 {continue tests} {
+ set x 0
+ list [lmap i {a b c d} {
+ incr x
+ if {[string compare $i "b"] != 0} continue
+ set i
+ }] $x
+} {b 4}
+test lmap-3.3 {break tests} {
+ set x 0
+ list [lmap i {a b c d} {
+ incr x
+ if {[string compare $i "c"] == 0} break
+ set i
+ }] $x
+} {{a b} 3}
+# Check for bug similar to #406709
+test lmap-3.4 {break tests} {
+ set a 1
+ lmap b b {list [concat a; break]; incr a}
+ incr a
+} {2}
+
+# ----- Compiled operation ---------------------------------------------------
+
+# Basic "lmap" operation (compiled)
+test lmap-4.1 {basic lmap tests} {
+ apply {{} {
+ set a {}
+ lmap i {a b c d} {
+ set a [concat $a $i]
+ }
+ }}
+} {a {a b} {a b c} {a b c d}}
+test lmap-4.2 {basic lmap tests} {
+ apply {{} {
+ lmap i {a b {{c d} e} {123 {{x}}}} {
+ set i
+ }
+ }}
+} {a b {{c d} e} {123 {{x}}}}
+test lmap-4.2a {basic lmap tests} {
+ apply {{} {
+ lmap i {a b {{c d} e} {123 {{x}}}} {
+ return -level 0 $i
+ }
+ }}
+} {a b {{c d} e} {123 {{x}}}}
+test lmap-4.4 {basic lmap tests} -returnCodes error -body {
+ apply {{} { lmap }}
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-4.6 {basic lmap tests} -returnCodes error -body {
+ apply {{} { lmap i }}
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-4.8 {basic lmap tests} -returnCodes error -body {
+ apply {{} { lmap i j }}
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-4.10 {basic lmap tests} -returnCodes error -body {
+ apply {{} { lmap i j k l }}
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-4.11 {basic lmap tests} {
+ apply {{} { lmap i {} { set i } }}
+} {}
+test lmap-4.12 {basic lmap tests} {
+ apply {{} { lmap i {} { return -level 0 x } }}
+} {}
+test lmap-4.13 {lmap errors} -returnCodes error -body {
+ apply {{} { lmap {{a}{b}} {1 2 3} {} }}
+} -result {list element in braces followed by "{b}" instead of space}
+test lmap-4.14 {lmap errors} -returnCodes error -body {
+ apply {{} { lmap a {{1 2}3} {} }}
+} -result {list element in braces followed by "3" instead of space}
+unset -nocomplain a
+test lmap-4.15 {lmap errors} {
+ apply {{} {
+ set a(0) 44
+ list [catch {lmap a {1 2 3} {}} msg o] $msg $::errorInfo
+ }}
+} {1 {can't set "a": variable is array} {can't set "a": variable is array
+ while executing
+"lmap a {1 2 3} {}"}}
+test lmap-4.16 {lmap errors} -returnCodes error -body {
+ apply {{} {
+ lmap {} {} {}
+ }}
+} -result {lmap varlist is empty}
+unset -nocomplain a
+
+# Parallel "lmap" operation (compiled)
+test lmap-5.1 {parallel lmap tests} {
+ apply {{} {
+ lmap {a b} {1 2 3 4} {
+ list $b $a
+ }
+ }}
+} {{2 1} {4 3}}
+test lmap-5.2 {parallel lmap tests} {
+ apply {{} {
+ lmap {a b} {1 2 3 4 5} {
+ list $b $a
+ }
+ }}
+} {{2 1} {4 3} {{} 5}}
+test lmap-5.3 {parallel lmap tests} {
+ apply {{} {
+ lmap a {1 2 3} b {4 5 6} {
+ list $b $a
+ }
+ }}
+} {{4 1} {5 2} {6 3}}
+test lmap-5.4 {parallel lmap tests} {
+ apply {{} {
+ lmap a {1 2 3} b {4 5 6 7 8} {
+ list $b $a
+ }
+ }}
+} {{4 1} {5 2} {6 3} {7 {}} {8 {}}}
+test lmap-5.5 {parallel lmap tests} {
+ apply {{} {
+ lmap {a b} {a b A B aa bb} c {c C cc CC} {
+ list $a $b $c
+ }
+ }}
+} {{a b c} {A B C} {aa bb cc} {{} {} CC}}
+test lmap-5.6 {parallel lmap tests} {
+ apply {{} {
+ lmap a {1 2 3} b {1 2 3} c {1 2 3} d {1 2 3} e {1 2 3} {
+ list $a$b$c$d$e
+ }
+ }}
+} {11111 22222 33333}
+test lmap-5.7 {parallel lmap tests} {
+ apply {{} {
+ lmap a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
+ set x $a$b$c$d$e
+ }
+ }}
+} {{1111 2} 222 33 4}
+test lmap-5.8 {parallel lmap tests} {
+ apply {{} {
+ lmap a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
+ join [list $a $b $c $d $e] .
+ }
+ }}
+} {{.1.1.1.1 2} .2.2.2. .3..3. ...4.}
+test lmap-5.9 {lmap only sets vars if repeating loop} {
+ apply {{} {
+ set rgb {65535 0 0}
+ lmap {r g b} [set rgb] {}
+ return "r=$r, g=$g, b=$b"
+ }}
+} {r=65535, g=0, b=0}
+test lmap-5.10 {lmap only supports local scalar variables} {
+ apply {{} {
+ lmap {a(3)} {1 2 3 4} {set {a(3)}}
+ }}
+} {1 2 3 4}
+
+# "lmap" with "continue" and "break" (compiled)
+test lmap-6.1 {continue tests} {
+ apply {{} {
+ lmap i {a b c d} {
+ if {[string compare $i "b"] == 0} continue
+ set i
+ }
+ }}
+} {a c d}
+test lmap-6.2 {continue tests} {
+ apply {{} {
+ list [lmap i {a b c d} {
+ incr x
+ if {[string compare $i "b"] != 0} continue
+ set i
+ }] $x
+ }}
+} {b 4}
+test lmap-6.3 {break tests} {
+ apply {{} {
+ list [lmap i {a b c d} {
+ incr x
+ if {[string compare $i "c"] == 0} break
+ set i
+ }] $x
+ }}
+} {{a b} 3}
+# Check for bug similar to #406709
+test lmap-6.4 {break tests} {
+ apply {{} {
+ set a 1
+ lmap b b {list [concat a; break]; incr a}
+ incr a
+ }}
+} {2}
+
+# ----- Special cases and bugs -----------------------------------------------
+test lmap-7.1 {compiled lmap backward jump works correctly} -setup {
+ unset -nocomplain x
+} -body {
+ array set x {0 zero 1 one 2 two 3 three}
+ lsort [apply {{arrayName} {
+ upvar 1 $arrayName a
+ lmap member [array names a] {
+ list $member [set a($member)]
+ }
+ }} x]
+} -result [lsort {{0 zero} {1 one} {2 two} {3 three}}]
+test lmap-7.2 {noncompiled lmap and shared variable or value list objects that are converted to another type} -setup {
+ unset -nocomplain x
+} -body {
+ lmap {12.0} {a b c} {
+ set x 12.0
+ set x [expr $x + 1]
+ }
+} -result {13.0 13.0 13.0}
+# Test for incorrect "double evaluation" semantics
+test lmap-7.3 {delayed substitution of body} {
+ apply {{} {
+ set a 0
+ lmap a [list 1 2 3] "
+ set x $a
+ "
+ return $x
+ }}
+} {0}
+# Related to "foreach" test for [Bug 1189274]; crash on failure
+test lmap-7.4 {empty list handling} {
+ proc crash {} {
+ rename crash {}
+ set a "x y z"
+ set b ""
+ lmap aa $a bb $b { set x "aa = $aa bb = $bb" }
+ }
+ crash
+} {{aa = x bb = } {aa = y bb = } {aa = z bb = }}
+# Related to [Bug 1671138]; infinite loop with empty var list in bytecompiled
+# version.
+test lmap-7.5 {compiled empty var list} -returnCodes error -body {
+ proc foo {} {
+ lmap {} x {
+ error "reached body"
+ }
+ }
+ foo
+} -cleanup {
+ catch {rename foo ""}
+} -result {lmap varlist is empty}
+test lmap-7.6 {lmap: related to "foreach" [Bug 1671087]} -setup {
+ proc demo {} {
+ set vals {1 2 3 4}
+ trace add variable x write {string length $vals ;# }
+ lmap {x y} $vals {format $y}
+ }
+} -body {
+ demo
+} -cleanup {
+ rename demo {}
+} -result {2 4}
+# Huge lists must not overflow the bytecode interpreter (development bug)
+test lmap-7.7 {huge list non-compiled} -setup {
+ unset -nocomplain a b x
+} -body {
+ set x [lmap a [lrepeat 1000000 x] { set b y$a }]
+ list $b [llength $x] [string length $x]
+} -result {yx 1000000 2999999}
+test lmap-7.8 {huge list compiled} -setup {
+ unset -nocomplain a b x
+} -body {
+ set x [apply {{times} {
+ global b
+ lmap a [lrepeat $times x] { set b Y$a }
+ }} 1000000]
+ list $b [llength $x] [string length $x]
+} -result {Yx 1000000 2999999}
+test lmap-7.9 {error then dereference loop var (dev bug)} {
+ catch { lmap a 0 b {1 2 3} { error x } }
+ set a
+} 0
+test lmap-7.9a {error then dereference loop var (dev bug)} {
+ catch { lmap a 0 b {1 2 3} { incr a $b; error x } }
+ set a
+} 1
+
+# ----- Coroutines -----------------------------------------------------------
+test lmap-8.1 {lmap non-compiled with coroutines} -body {
+ coroutine coro apply {{} {
+ set values [yield [info coroutine]]
+ eval lmap i [list $values] {{ yield $i }}
+ }} ;# returns 'coro'
+ coro {a b c d e f} ;# -> a
+ coro 1 ;# -> b
+ coro 2 ;# -> c
+ coro 3 ;# -> d
+ coro 4 ;# -> e
+ coro 5 ;# -> f
+ list [coro 6] [info commands coro]
+} -cleanup {
+ catch {rename coro ""}
+} -result {{1 2 3 4 5 6} {}}
+test lmap-8.2 {lmap compiled with coroutines} -body {
+ coroutine coro apply {{} {
+ set values [yield [info coroutine]]
+ lmap i $values { yield $i }
+ }} ;# returns 'coro'
+ coro {a b c d e f} ;# -> a
+ coro 1 ;# -> b
+ coro 2 ;# -> c
+ coro 3 ;# -> d
+ coro 4 ;# -> e
+ coro 5 ;# -> f
+ list [coro 6] [info commands coro]
+} -cleanup {
+ catch {rename coro ""}
+} -result {{1 2 3 4 5 6} {}}
+
+# cleanup
+unset -nocomplain a x
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/load.test b/tests/load.test
index b7c1a59..9536271 100644
--- a/tests/load.test
+++ b/tests/load.test
@@ -15,6 +15,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
# Figure out what extension is used for shared libraries on this
# platform.
if {![info exists ext]} {
@@ -44,32 +47,38 @@ testConstraint testsimplefilesystem \
test load-1.1 {basic errors} {} {
list [catch {load} msg] $msg
-} "1 {wrong \# args: should be \"load fileName ?packageName? ?interp?\"}"
+} "1 {wrong \# args: should be \"load ?-global? ?-lazy? ?--? fileName ?packageName? ?interp?\"}"
test load-1.2 {basic errors} {} {
list [catch {load a b c d} msg] $msg
-} "1 {wrong \# args: should be \"load fileName ?packageName? ?interp?\"}"
+} "1 {wrong \# args: should be \"load ?-global? ?-lazy? ?--? fileName ?packageName? ?interp?\"}"
test load-1.3 {basic errors} {} {
list [catch {load a b foobar} msg] $msg
} {1 {could not find interpreter "foobar"}}
test load-1.4 {basic errors} {} {
- list [catch {load {}} msg] $msg
+ list [catch {load -global {}} msg] $msg
} {1 {must specify either file name or package name}}
test load-1.5 {basic errors} {} {
- list [catch {load {} {}} msg] $msg
+ list [catch {load -lazy {} {}} msg] $msg
} {1 {must specify either file name or package name}}
test load-1.6 {basic errors} {} {
list [catch {load {} Unknown} msg] $msg
} {1 {package "Unknown" isn't loaded statically}}
+test load-1.7 {basic errors} {} {
+ list [catch {load -abc foo} msg] $msg
+} "1 {bad option \"-abc\": must be -global, -lazy, or --}"
+test load-1.8 {basic errors} {} {
+ list [catch {load -global} msg] $msg
+} "1 {couldn't figure out package name for -global}"
test load-2.1 {basic loading, with guess for package name} \
[list $dll $loaded] {
- load [file join $testDir pkga$ext]
+ load -global [file join $testDir pkga$ext]
list [pkga_eq abc def] [lsort [info commands pkga_*]]
} {0 {pkga_eq pkga_quote}}
interp create -safe child
test load-2.2 {loading into a safe interpreter, with package name conversion} \
[list $dll $loaded] {
- load [file join $testDir pkgb$ext] pKgB child
+ load -lazy [file join $testDir pkgb$ext] pKgB child
list [child eval pkgb_sub 44 13] [catch {child eval pkgb_unsafe} msg] $msg \
[catch {pkgb_sub 12 10} msg2] $msg2
} {31 1 {invalid command name "pkgb_unsafe"} 1 {invalid command name "pkgb_sub"}}
@@ -123,7 +132,7 @@ test load-5.1 {file name not specified and no static package: pick default} \
[list $dll $loaded] {
catch {interp delete x}
interp create x
- load [file join $testDir pkga$ext] pkga
+ load -global [file join $testDir pkga$ext] pkga
load {} pkga x
set result [info loaded x]
interp delete x
@@ -179,7 +188,7 @@ test load-8.3 {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded]
test load-8.4 {TclGetLoadedPackages procedure} [list $dll $loaded teststaticpkg] {
load [file join $testDir pkgb$ext] pkgb
list [info loaded {}] [lsort [info commands pkgb_*]]
-} [list [concat [list [list [file join $testDir pkgb$ext] Pkgb] {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded] {pkgb_sub pkgb_unsafe}]
+} [list [concat [list [list [file join $testDir pkgb$ext] Pkgb] {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded] {pkgb_demo pkgb_sub pkgb_unsafe}]
interp delete child
test load-9.1 {Tcl_StaticPackage, load already-loaded package into another interp} \
@@ -197,7 +206,7 @@ test load-9.1 {Tcl_StaticPackage, load already-loaded package into another inter
[child1 eval { info loaded {} }] \
[child2 eval { info loaded {} }]
} \
- -result {{{{} Loadninepointone} {{} Tcltest}} {{{} Loadninepointone} {{} Tcltest}}} \
+ -match glob -result {{{{} Loadninepointone} {* Tcltest}} {{{} Loadninepointone} {* Tcltest}}} \
-cleanup { interp delete child1 ; interp delete child2 }
test load-10.1 {load from vfs} \
@@ -206,6 +215,12 @@ test load-10.1 {load from vfs} \
-body {list [catch {load simplefs:/pkgd$ext pkgd} msg] $msg} \
-result {0 {}} \
-cleanup {testsimplefilesystem 0; cd $dir; unset dir}
+
+test load-11.1 {Load TclOO extension using Stubs (Bug [f51efe99a7])} \
+ [list $dll $loaded] {
+ load [file join $testDir pkgooa$ext]
+ list [pkgooa_stubsok] [lsort [info commands pkgooa_*]]
+} {1 pkgooa_stubsok}
# cleanup
unset ext
diff --git a/tests/lrange.test b/tests/lrange.test
index 6c81872..17a757e 100644
--- a/tests/lrange.test
+++ b/tests/lrange.test
@@ -15,7 +15,7 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
namespace import -force ::tcltest::*
}
-
+
test lrange-1.1 {range of list elements} {
lrange {a b c d} 1 2
} {b c}
@@ -61,9 +61,11 @@ test lrange-1.14 {range of list elements} {
test lrange-1.15 {range of list elements} {
concat \"[lrange {a b \{\ } 0 2]"
} {"a b \{\ "}
+# emacs highlighting bug workaround --> "
test lrange-1.16 {list element quoting} {
lrange {[append a .b]} 0 end
} {{[append} a .b\]}
+
test lrange-2.1 {error conditions} {
list [catch {lrange a b} msg] $msg
} {1 {wrong # args: should be "lrange list first last"}}
@@ -83,6 +85,16 @@ test lrange-2.6 {error conditions} {
list [catch {lrange "a b c \{ d e" 1 4} msg] $msg
} {1 {unmatched open brace in list}}
+test lrange-3.1 {Bug 3588366: end-offsets before start} {
+ apply {l {
+ lrange $l 0 end-5
+ }} {1 2 3 4 5}
+} {}
+
# cleanup
::tcltest::cleanupTests
return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/lset.test b/tests/lset.test
index 3f4914d..1c1300b 100644
--- a/tests/lset.test
+++ b/tests/lset.test
@@ -16,6 +16,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
proc failTrace {name1 name2 op} {
error "trace failed"
}
diff --git a/tests/lsetComp.test b/tests/lsetComp.test
index 6846cbf..6846cbf 100755..100644
--- a/tests/lsetComp.test
+++ b/tests/lsetComp.test
diff --git a/tests/main.test b/tests/main.test
index f1dc7fd..351fd4f 100644
--- a/tests/main.test
+++ b/tests/main.test
@@ -129,7 +129,7 @@ namespace eval ::tcl::test::main {
set script [makeFile {} script]
file delete $script
set f [open $script w]
- fconfigure $f -encoding utf-8
+ chan configure $f -encoding utf-8
puts $f {puts [list $argv0 $argv $tcl_interactive]}
puts -nonewline $f {puts [string equal \u20ac }
puts $f "\u20ac]"
@@ -150,7 +150,7 @@ namespace eval ::tcl::test::main {
set script [makeFile {} script]
file delete $script
set f [open $script w]
- fconfigure $f -encoding utf-8
+ chan configure $f -encoding utf-8
puts $f {puts [list $argv0 $argv $tcl_interactive]}
puts -nonewline $f {puts [string equal \u20ac }
puts $f "\u20ac]"
@@ -171,7 +171,7 @@ namespace eval ::tcl::test::main {
set script [makeFile {} script]
file delete $script
set f [open $script w]
- fconfigure $f -encoding utf-8
+ chan configure $f -encoding utf-8
puts $f {puts [list $argv0 $argv $tcl_interactive]}
puts -nonewline $f {puts [string equal \u20ac }
puts $f "\u20ac]"
@@ -592,7 +592,7 @@ namespace eval ::tcl::test::main {
catch {set f [open "|[list [interpreter]]" w+]}
} -body {
type $f {
- fconfigure stdin -blocking 0
+ chan configure stdin -blocking 0
puts SUCCESS
}
list [catch {gets $f} line] $line
@@ -606,19 +606,19 @@ namespace eval ::tcl::test::main {
exec
} -setup {
catch {set f [open "|[list [interpreter]]" w+]}
- catch {fconfigure $f -blocking 0}
+ catch {chan configure $f -blocking 0}
} -body {
- type $f "fconfigure stdin -eofchar \\032
+ type $f "chan configure stdin -eofchar \\032
if 1 \{\n\032"
variable wait
- fileevent $f readable \
+ chan event $f readable \
[list set [namespace which -variable wait] "child exit"]
set id [after 2000 [list set [namespace which -variable wait] timeout]]
vwait [namespace which -variable wait]
after cancel $id
set wait
} -cleanup {
- if {[string equal timeout $wait] && [testConstraint unix]} {
+ if {$wait eq "timeout" && [testConstraint unix]} {
exec kill [pid $f]
}
close $f
@@ -631,17 +631,17 @@ namespace eval ::tcl::test::main {
} -setup {
set cmd {makeFile "if 1 \{" script}
catch {set f [open "|[list [interpreter]] < [list [eval $cmd]]" r]}
- catch {fconfigure $f -blocking 0}
+ catch {chan configure $f -blocking 0}
} -body {
variable wait
- fileevent $f readable \
+ chan event $f readable \
[list set [namespace which -variable wait] "child exit"]
set id [after 2000 [list set [namespace which -variable wait] timeout]]
vwait [namespace which -variable wait]
after cancel $id
set wait
} -cleanup {
- if {[string equal timeout $wait] && [testConstraint unix]} {
+ if {$wait eq "timeout" && [testConstraint unix]} {
exec kill [pid $f]
}
close $f
@@ -748,7 +748,7 @@ namespace eval ::tcl::test::main {
exec Tcltest
} -setup {
catch {set f [open "|[list [interpreter]]" w+]}
- catch {fconfigure $f -blocking 0}
+ catch {chan configure $f -blocking 0}
} -body {
type $f "testsetmainloop
after 2000 testexitmainloop
@@ -983,7 +983,7 @@ namespace eval ::tcl::test::main {
} -body {
exec [interpreter] << {
testsetmainloop
- fconfigure stdin -blocking 0
+ chan configure stdin -blocking 0
testexitmainloop
} >& result
set f [open result]
diff --git a/tests/misc.test b/tests/misc.test
index fe19ebe..d4ece74 100644
--- a/tests/misc.test
+++ b/tests/misc.test
@@ -17,6 +17,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testhashsystemhash [llength [info commands testhashsystemhash]]
test misc-1.1 {error in variable ref. in command in array reference} {
@@ -56,12 +59,7 @@ test misc-1.2 {error in variable ref. in command in array reference} {
missing close-brace for variable name
missing close-brace for variable name
while executing
-"set tst $a([winfo name $\{zz)
- # this is a bogus comment
- # this is a bogus comment
- # this is a bogus comment
- # this is a bogus comment
- # this is a ..."
+"set tst $a([winfo name $\{"
(procedure "tstProc" line 4)
invoked from within
"tstProc"}]
diff --git a/tests/msgcat.test b/tests/msgcat.test
index 0669810..050b592 100644
--- a/tests/msgcat.test
+++ b/tests/msgcat.test
@@ -12,13 +12,13 @@
# Note that after running these tests, entries will be left behind in the
# message catalogs for locales foo, foo_BAR, and foo_BAR_baz.
-package require Tcl 8.2
+package require Tcl 8.5
if {[catch {package require tcltest 2}]} {
puts stderr "Skipping tests in [info script]. tcltest 2 required."
return
}
-if {[catch {package require msgcat 1.4.2}]} {
- puts stderr "Skipping tests in [info script]. No msgcat 1.4.2 found to test."
+if {[catch {package require msgcat 1.5}]} {
+ puts stderr "Skipping tests in [info script]. No msgcat 1.5 found to test."
return
}
@@ -56,6 +56,13 @@ namespace eval ::msgcat::test {
set result [string tolower \
[msgcat::ConvertLocale $::tcl::mac::locale]]
} else {
+ if {([info sharedlibextension] eq ".dll")
+ && ![catch {package require registry}]} {
+ # Windows and Cygwin have other ways to determine the
+ # locale when the environment variables are missing
+ # and the registry package is present
+ continue
+ }
set result c
}
}
@@ -65,7 +72,7 @@ namespace eval ::msgcat::test {
variable var
foreach var $envVars {
catch {variable $var $::env($var)}
- catch {unset ::env($var)}
+ unset -nocomplain ::env($var)
}
foreach var $setVars {
set ::env($var) $var
@@ -77,13 +84,13 @@ namespace eval ::msgcat::test {
} -cleanup {
interp delete [namespace current]::i
foreach var $envVars {
- catch {unset ::env($var)}
+ unset -nocomplain ::env($var)
catch {set ::env($var) [set [namespace current]::$var]}
}
} -body {i eval msgcat::mclocale} -result $result
incr count
}
- catch {unset result}
+ unset -nocomplain result
# Could add tests of initialization from Windows registry here.
# Use a fake registry package.
@@ -317,7 +324,7 @@ namespace eval ::msgcat::test {
incr count
}
}
- catch {unset result}
+ unset -nocomplain result
# Tests msgcat-4.*: [mcunknown]
@@ -611,6 +618,45 @@ namespace eval ::msgcat::test {
mc "this is a %s" "good test"
} -result "this is a good test"
+ # Tests msgcat-8.*: [mcflset]
+
+ set msgdir1 [makeDirectory msgdir1]
+ makeFile {::msgcat::mcflset k1 v1} l1.msg $msgdir1
+
+ test msgcat-8.1 {mcflset} -setup {
+ variable locale [mclocale]
+ mclocale l1
+ mcload $msgdir1
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc k1
+ } -result v1
+
+ removeFile l1.msg $msgdir1
+ removeDirectory msgdir1
+
+ set msgdir2 [makeDirectory msgdir2]
+ set msgdir3 [makeDirectory msgdir3]
+ makeFile "::msgcat::mcflset k2 v2 ; ::msgcat::mcload [list $msgdir3]"\
+ l2.msg $msgdir2
+ makeFile {::msgcat::mcflset k3 v3} l2.msg $msgdir3
+
+ # chained mcload
+ test msgcat-8.2 {mcflset} -setup {
+ variable locale [mclocale]
+ mclocale l2
+ mcload $msgdir2
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ return [mc k2][mc k3]
+ } -result v2v3
+
+ removeFile l2.msg $msgdir2
+ removeDirectory msgdir2
+ removeDirectory msgdir3
+
cleanupTests
}
namespace delete ::msgcat::test
diff --git a/tests/namespace.test b/tests/namespace.test
index f4e50bc..fab0040 100644
--- a/tests/namespace.test
+++ b/tests/namespace.test
@@ -16,6 +16,9 @@ package require tcltest 2
namespace import -force ::tcltest::*
testConstraint memory [llength [info commands memory]]
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
#
# REMARK: the tests for 'namespace upvar' are not done here. They are to be
# found in the file 'upvar.test'.
@@ -300,7 +303,7 @@ test namespace-9.4 {Tcl_Import, simple import} {
}
test_ns_import::p
} {cmd1: 123}
-test namespace-9.5 {Tcl_Import, can't redefine cmd unless allowOverwrite!=0} {
+test namespace-9.5 {Tcl_Import, RFE 1230597} {
list [catch {namespace eval test_ns_import {namespace import ::test_ns_export::*}} msg] $msg
} {0 {}}
test namespace-9.6 {Tcl_Import, cmd redefinition ok if allowOverwrite!=0} {
@@ -555,6 +558,15 @@ test namespace-13.1 {DeleteImportedCmd, deletes imported cmds} {
lappend l [info commands ::test_ns_import::*]
}
} {::test_ns_import::cmd1 {}}
+test namespace-13.2 {DeleteImportedCmd, Bug a4494e28ed} {
+ # Will panic if still buggy
+ namespace eval src {namespace export foo; proc foo {} {}}
+ namespace eval dst {namespace import [namespace parent]::src::foo}
+ trace add command src::foo delete \
+ "[list namespace delete [namespace current]::dst] ;#"
+ proc src::foo {} {}
+ namespace delete src
+} {}
test namespace-14.1 {TclGetNamespaceForQualName, absolute names} {
catch {namespace delete {*}[namespace children :: test_ns_*]}
@@ -1108,6 +1120,14 @@ test namespace-26.7 {NamespaceExportCmd, -clear resets export list} {
}
list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd4 hello]
} [list [lsort {::test_ns_2::cmd4 ::test_ns_2::cmd1 ::test_ns_2::cmd3}] {cmd4: hello}]
+test namespace-26.8 {NamespaceExportCmd, -clear resets export list} {
+ catch {namespace delete foo}
+ namespace eval foo {
+ namespace export x
+ namespace export -clear
+ }
+ list [namespace eval foo namespace export] [namespace delete foo]
+} {{} {}}
test namespace-27.1 {NamespaceForgetCmd, no args} {
catch {namespace delete {*}[namespace children :: test_ns_*]}
@@ -2480,7 +2500,7 @@ test namespace-51.16 {Bug 1566526} {
test namespace-51.17 {resolution epoch handling: Bug 2898722} -setup {
set result {}
catch {namespace delete ::a}
-} -constraints knownBug -body {
+} -body {
namespace eval ::a {
proc c {} {lappend ::result A}
c
diff --git a/tests/notify.test b/tests/notify.test
index ba52c50..d2b9123 100755..100644
--- a/tests/notify.test
+++ b/tests/notify.test
@@ -18,6 +18,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testevent [llength [info commands testevent]]
test notify-1.1 {Tcl_QueueEvent and delivery of a single event} \
diff --git a/tests/nre.test b/tests/nre.test
index 295f02e..b5eb032 100644
--- a/tests/nre.test
+++ b/tests/nre.test
@@ -14,6 +14,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testnrelevels [llength [info commands testnrelevels]]
#
@@ -71,7 +74,6 @@ test nre-1.1 {self-recursive procs} -setup {
} -constraints {
testnrelevels
} -result {{0 1 1 1} 0}
-
test nre-1.2 {self-recursive lambdas} -setup {
set a [list i [makebody {apply $::a $i}]]
} -body {
@@ -82,7 +84,6 @@ test nre-1.2 {self-recursive lambdas} -setup {
} -constraints {
testnrelevels
} -result {{0 1 1 1} 0}
-
test nre-1.3 {mutually recursive procs and lambdas} -setup {
proc a i {
apply $::b [incr i]
@@ -161,8 +162,7 @@ test nre-5.1 {[namespace eval] is not recursive} -setup {
namespace delete ::foo
} -constraints {
testnrelevels
-} -result {{0 3 2 2} 0}
-
+} -result {{0 2 2 2} 0}
test nre-5.2 {[namespace eval] is not recursive} -setup {
namespace eval ::foo {
setabs
@@ -174,7 +174,7 @@ test nre-5.2 {[namespace eval] is not recursive} -setup {
namespace delete ::foo
} -constraints {
testnrelevels
-} -result {{0 3 2 2} 0}
+} -result {{0 2 2 2} 0}
test nre-6.1 {[uplevel] is not recursive} -setup {
proc a i [makebody {uplevel 1 [list a $i]}]
@@ -186,7 +186,6 @@ test nre-6.1 {[uplevel] is not recursive} -setup {
} -constraints {
testnrelevels
} -result {{0 2 2 0} 0}
-
test nre-6.2 {[uplevel] is not recursive} -setup {
setabs
proc a i [makebody {uplevel 1 "set x $i; a $i"}]
@@ -208,7 +207,6 @@ test nre-7.1 {[catch] is not recursive} -setup {
} -constraints {
testnrelevels
} -result {{0 3 3 0} 0}
-
test nre-7.2 {[if] is not recursive} -setup {
setabs
proc a i [makebody {uplevel 1 "if 1 {a $i}"}]
@@ -219,7 +217,6 @@ test nre-7.2 {[if] is not recursive} -setup {
} -constraints {
testnrelevels
} -result {{0 2 2 0} 0}
-
test nre-7.3 {[while] is not recursive} -setup {
setabs
proc a i [makebody {uplevel 1 "while 1 {set res \[a $i\]; break}; set res"}]
@@ -230,7 +227,6 @@ test nre-7.3 {[while] is not recursive} -setup {
} -constraints {
testnrelevels
} -result {{0 2 2 0} 0}
-
test nre-7.4 {[for] is not recursive} -setup {
setabs
proc a i [makebody {uplevel 1 "for {set j 0} {\$j < 10} {incr j} {set res \[a $i\]; break}; set res"}]
@@ -241,7 +237,6 @@ test nre-7.4 {[for] is not recursive} -setup {
} -constraints {
testnrelevels
} -result {{0 2 2 0} 0}
-
test nre-7.5 {[foreach] is not recursive} -setup {
#
# Enable once [foreach] is NR-enabled
@@ -255,7 +250,6 @@ test nre-7.5 {[foreach] is not recursive} -setup {
} -constraints {
testnrelevels
} -result {{0 3 3 0} 0}
-
test nre-7.6 {[eval] is not recursive} -setup {
proc a i [makebody {eval [list a $i]}]
} -body {
@@ -266,7 +260,6 @@ test nre-7.6 {[eval] is not recursive} -setup {
} -constraints {
testnrelevels
} -result {{0 2 2 1} 0}
-
test nre-7.7 {[eval] is not recursive} -setup {
proc a i [makebody {eval "a $i"}]
} -body {
@@ -277,7 +270,6 @@ test nre-7.7 {[eval] is not recursive} -setup {
} -constraints {
testnrelevels
} -result {{0 2 2 1} 0}
-
test nre-7.8 {bug #2910748: switch out of stale BC is not nre-aware} -setup {
proc foo args {}
foo
@@ -292,18 +284,15 @@ test nre-7.8 {bug #2910748: switch out of stale BC is not nre-aware} -setup {
} -body {
# if switching to plain eval is not nre aware, this will cause a "cannot
# yield" error
-
list [bar] [bar] [bar]
} -cleanup {
rename bar {}
rename foo {}
} -result {1 2 3}
-
test nre-8.1 {nre and {*}} -body {
# force an expansion that grows the evaluation stack, check that nre
# adapts the TEBCdataPtr. This crashes on failure.
-
proc inner {} {
set long [lrepeat 1000000 1]
list {*}$long
@@ -318,21 +307,18 @@ test nre-8.2 {nre and {*}, [Bug 2415422]} -body {
# force an expansion that grows the evaluation stack, check that nre
# adapts the bcFramePtr. This causes an NRE assertion to fail if it is not
# done properly.
-
proc nop {} {}
proc crash {} {
foreach val [list {*}[lrepeat 100000 x]] {
nop
}
}
-
crash
} -cleanup {
rename nop {}
rename crash {}
}
-
#
# Basic TclOO tests
#
@@ -348,7 +334,6 @@ test nre-oo.1 {really deep calls in oo - direct} -setup {
} -constraints {
testnrelevels
} -result {{0 1 1 1} 0}
-
test nre-oo.2 {really deep calls in oo - call via [self]} -setup {
oo::object create foo
oo::objdefine foo method bar i [makebody {[self] bar $i}]
@@ -360,7 +345,6 @@ test nre-oo.2 {really deep calls in oo - call via [self]} -setup {
} -constraints {
testnrelevels
} -result {{0 1 1 1} 0}
-
test nre-oo.3 {really deep calls in oo - private calls} -setup {
oo::object create foo
oo::objdefine foo method bar i [makebody {my bar $i}]
@@ -372,7 +356,6 @@ test nre-oo.3 {really deep calls in oo - private calls} -setup {
} -constraints {
testnrelevels
} -result {{0 1 1 1} 0}
-
test nre-oo.4 {really deep calls in oo - overriding} -setup {
oo::class create foo {
method bar i [makebody {my bar $i}]
@@ -389,7 +372,6 @@ test nre-oo.4 {really deep calls in oo - overriding} -setup {
} -constraints {
testnrelevels
} -result {{0 1 1 1} 0}
-
test nre-oo.5 {really deep calls in oo - forwards} -setup {
oo::object create foo
set body [makebody {my boo $i}]
@@ -406,7 +388,6 @@ test nre-oo.5 {really deep calls in oo - forwards} -setup {
testnrelevels
} -result {{0 2 1 1} 0}
-
#
# NASTY BUG found by tcllib's interp package
#
diff --git a/tests/obj.test b/tests/obj.test
index 126d5ca..151abfb 100644
--- a/tests/obj.test
+++ b/tests/obj.test
@@ -16,6 +16,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testobj [llength [info commands testobj]]
testConstraint longIs32bit [expr {int(0x80000000) < 0}]
testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}]
@@ -602,7 +605,7 @@ test obj-33.2 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
set x 0xffff; append x ffff
list [string is integer $x] [expr { wide($x) }]
} {1 4294967295}
-test obj-33.3 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+test obj-33.3 {integer overflow on input} {
set x 0x10000; append x 0000
list [string is integer $x] [expr { wide($x) }]
} {0 4294967296}
@@ -618,7 +621,7 @@ test obj-33.6 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
set x -0xffff; append x ffff
list [string is integer $x] [expr { wide($x) }]
} {1 -4294967295}
-test obj-33.7 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+test obj-33.7 {integer overflow on input} {
set x -0x10000; append x 0000
list [string is integer $x] [expr { wide($x) }]
} {0 -4294967296}
diff --git a/tests/oo.test b/tests/oo.test
index b12cb42..d63e931 100644
--- a/tests/oo.test
+++ b/tests/oo.test
@@ -2,12 +2,12 @@
# Sourcing this file into Tcl runs the tests and generates output for errors.
# No output means no errors were found.
#
-# Copyright (c) 2006-2011 Donal K. Fellows
+# Copyright (c) 2006-2013 Donal K. Fellows
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
-package require -exact TclOO 0.6.3 ;# Must match value in generic/tclOO.h
+package require TclOO 1.0.1
package require tcltest 2
if {"::tcltest" in [namespace children]} {
namespace import -force ::tcltest::*
@@ -101,7 +101,7 @@ test oo-0.8 {leak in variable management} -setup {
test oo-0.9 {various types of presence of the TclOO package} {
list [lsearch -nocase -all -inline [package names] tcloo] \
[package present TclOO] [package versions TclOO]
-} [list TclOO $::oo::version $::oo::version]
+} [list TclOO $::oo::patchlevel $::oo::patchlevel]
test oo-1.1 {basic test of OO functionality: no classes} {
set result {}
@@ -131,6 +131,13 @@ test oo-1.4 {basic test of OO functionality} -body {
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}
+test oo-1.5.1 {basic test of OO functionality} -setup {
+ oo::object create aninstance
+} -returnCodes error -body {
+ aninstance
+} -cleanup {
+ rename aninstance {}
+} -result {wrong # args: should be "aninstance method ?arg ...?"}
test oo-1.6 {basic test of OO functionality} -setup {
oo::object create aninstance
} -body {
@@ -330,6 +337,45 @@ test oo-2.6 {OO constructor and tailcall - Bug 2414858} -setup {
} -cleanup {
foo destroy
} -result good
+test oo-2.7 {construction, method calls and ensembles - Bug 3514761} -setup {
+ namespace eval k {}
+} -body {
+ namespace eval k {
+ oo::class create s {
+ constructor {j} {
+ # nothing
+ }
+ }
+ namespace export s
+ namespace ensemble create
+ }
+ k s create X
+} -returnCodes error -cleanup {
+ namespace delete k
+} -result {wrong # args: should be "k s create X j"}
+test oo-2.8 {construction, method calls and ensembles - Bug 3514761} -setup {
+ namespace eval k {}
+} -body {
+ namespace eval k {
+ oo::class create s {
+ constructor {j} {
+ # nothing
+ }
+ }
+ oo::class create t {
+ superclass s
+ constructor args {
+ k next {*}$args
+ }
+ }
+ interp alias {} ::k::next {} ::oo::Helpers::next
+ namespace export t next
+ namespace ensemble create
+ }
+ k t create X
+} -returnCodes error -cleanup {
+ namespace delete k
+} -result {wrong # args: should be "k next j"}
test oo-3.1 {basic test of OO functionality: destructor} -setup {
# This is a bit complex because it needs to run in a sub-interp as we're
@@ -748,6 +794,211 @@ test oo-6.7 {OO: forward resolution scope is per-object} -setup {
} -cleanup {
fooClass destroy
} -result 1
+test oo-6.8 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler
+ method handler {a b c} {}
+ }
+ fooClass create ::foo
+ foo test
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.9 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler
+ method handler {a b c} {list $a,$b,$c}
+ }
+ fooClass create ::foo
+ foo test 1 2 3
+} -cleanup {
+ fooClass destroy
+} -result 1,2,3
+test oo-6.10 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler
+ method handler {a b c} {list $a,$b,$c}
+ }
+ fooClass create ::foo
+ foo test 1 2
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.11 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo {
+ forward test my handler
+ method handler {a b c} {}
+ }
+ foo test
+} -returnCodes error -cleanup {
+ foo destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.12 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo {
+ forward test my handler
+ method handler {a b c} {list $a,$b,$c}
+ }
+ foo test 1 2 3
+} -cleanup {
+ foo destroy
+} -result 1,2,3
+test oo-6.13 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo {
+ forward test my handler
+ method handler {a b c} {list $a,$b,$c}
+ }
+ foo test 1 2
+} -returnCodes error -cleanup {
+ foo destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.14 {Bug 3400658: forwarding and wrongargs rewriting - multistep} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler1 p
+ forward handler1 my handler q
+ method handler {a b c} {}
+ }
+ fooClass create ::foo
+ foo test
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test c"}
+test oo-6.15 {Bug 3400658: forwarding and wrongargs rewriting - multistep} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler1 p
+ forward handler1 my handler q
+ method handler {a b c} {list $a,$b,$c}
+ }
+ fooClass create ::foo
+ foo test 1
+} -cleanup {
+ fooClass destroy
+} -result q,p,1
+test oo-6.16 {Bug 3400658: forwarding and wrongargs rewriting - via alias} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test handler1 foo bar
+ forward handler2 my handler x
+ method handler {a b c d} {list $a,$b,$c,$d}
+ export eval
+ }
+ fooClass create ::foo
+ foo eval {
+ interp alias {} [namespace current]::handler1 \
+ {} [namespace current]::my handler2
+ }
+ foo test 1 2 3
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test d"}
+test oo-6.17 {Bug 3400658: forwarding and wrongargs rewriting - via ensemble} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test handler1 foo bar boo
+ forward handler2 my handler
+ method handler {a b c d} {list $a,$b,$c,$d}
+ export eval
+ }
+ fooClass create ::foo
+ foo eval {
+ namespace ensemble create \
+ -command [namespace current]::handler1 -parameters {p q} \
+ -map [list boo [list [namespace current]::my handler2]]
+ }
+ foo test 1 2 3
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test c d"}
+test oo-6.18 {Bug 3408830: more forwarding cases} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward len string length
+ }
+ [fooClass create foo] len a b
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "::foo len string"}
+test oo-6.19 {Bug 3610404: forwarding resolution + traces} -setup {
+ oo::object create foo
+ unset -nocomplain ::result
+ set ::result {}
+} -body {
+ proc ::my {method} {lappend ::result global}
+ oo::objdefine foo {
+ method target {} {lappend ::result instance}
+ forward bar my target
+ method bump {} {
+ set ns [info object namespace ::foo]
+ rename ${ns}::my ${ns}::
+ rename ${ns}:: ${ns}::my
+ }
+ }
+ proc harness {} {
+ foo target
+ foo bar
+ foo target
+ }
+ trace add execution harness enterstep {apply {{cmd args} {foo bump}}}
+ foo target
+ foo bar
+ foo bump
+ foo bar
+ harness
+} -cleanup {
+ catch {rename harness {}}
+ catch {rename ::my {}}
+ foo destroy
+} -result {instance instance instance instance instance instance}
+test oo-6.20 {Bug 3610404: forwarding resolution + traces} -setup {
+ oo::class create fooClass
+ fooClass create foo
+ unset -nocomplain ::result
+ set ::result {}
+} -body {
+ proc ::my {method} {lappend ::result global}
+ oo::define fooClass {
+ method target {} {lappend ::result class}
+ forward bar my target
+ method bump {} {
+ set ns [info object namespace [self]]
+ rename ${ns}::my ${ns}::
+ rename ${ns}:: ${ns}::my
+ }
+ }
+ proc harness {} {
+ foo target
+ foo bar
+ foo target
+ }
+ trace add execution harness enterstep {apply {{cmd args} {foo bump}}}
+ foo target
+ foo bar
+ foo bump
+ foo bar
+ harness
+} -cleanup {
+ catch {rename harness {}}
+ catch {rename ::my {}}
+ fooClass destroy
+} -result {class class class class class class}
test oo-7.1 {OO: inheritance 101} -setup {
oo::class create superClass
@@ -1508,6 +1759,116 @@ test oo-15.3 {OO: class cloning} {
bar destroy
return $result
} {::foo->::baseline ::foo->::baseline ::bar->::tester ::bar->::tester}
+test oo-15.4 {OO: object cloning - Bug 3474460} -setup {
+ oo::class create ArbitraryClass
+} -body {
+ ArbitraryClass create foo
+ oo::objdefine foo variable a b c
+ oo::copy foo bar
+ info object variable bar
+} -cleanup {
+ ArbitraryClass destroy
+} -result {a b c}
+test oo-15.5 {OO: class cloning - Bug 3474460} -setup {
+ oo::class create ArbitraryClass
+} -body {
+ oo::class create Foo {
+ superclass ArbitraryClass
+ variable a b c
+ }
+ oo::copy Foo Bar
+ info class variable Bar
+} -cleanup {
+ ArbitraryClass destroy
+} -result {a b c}
+test oo-15.6 {OO: object cloning copies namespace contents} -setup {
+ oo::class create ArbitraryClass {export eval}
+} -body {
+ ArbitraryClass create a
+ a eval {proc foo x {
+ variable y
+ return [string repeat $x [incr y]]
+ }}
+ set result [list [a eval {foo 2}] [a eval {foo 3}]]
+ oo::copy a b
+ a eval {rename foo bar}
+ lappend result [b eval {foo 2}] [b eval {foo 3}] [a eval {bar 4}]
+} -cleanup {
+ ArbitraryClass destroy
+} -result {2 33 222 3333 444}
+test oo-15.7 {OO: classes can be cloned anonymously} -setup {
+ oo::class create ArbitraryClassA
+ oo::class create ArbitraryClassB {superclass ArbitraryClassA}
+} -body {
+ info object isa class [oo::copy ArbitraryClassB]
+} -cleanup {
+ ArbitraryClassA destroy
+} -result 1
+test oo-15.8 {OO: intercept object cloning} -setup {
+ oo::class create Foo
+ set result {}
+} -body {
+ oo::define Foo {
+ constructor {msg} {
+ variable v $msg
+ }
+ method <cloned> {from} {
+ next $from
+ lappend ::result cloned $from [self]
+ }
+ method check {} {
+ variable v
+ lappend ::result check [self] $v
+ }
+ }
+ Foo create foo ok
+ oo::copy foo bar
+ foo check
+ bar check
+} -cleanup {
+ Foo destroy
+} -result {cloned ::foo ::bar check ::foo ok check ::bar ok}
+test oo-15.9 {ensemble rewriting must not bleed through oo::copy} -setup {
+ oo::class create Foo
+} -body {
+ oo::define Foo {
+ method <cloned> {a b} {}
+ }
+ interp alias {} Bar {} oo::copy [Foo create foo]
+ Bar bar
+} -returnCodes error -cleanup {
+ Foo destroy
+} -result {wrong # args: should be "::bar <cloned> a b"}
+test oo-15.10 {variable binding must not bleed through oo::copy} -setup {
+ oo::class create FooClass
+ set result {}
+} -body {
+ set obj1 [FooClass new]
+ oo::objdefine $obj1 {
+ variable var
+ method m {} {
+ set var foo
+ }
+ method get {} {
+ return $var
+ }
+ export eval
+ }
+
+ $obj1 m
+ lappend result [$obj1 get]
+ set obj2 [oo::copy $obj1]
+ $obj2 eval {
+ set var bar
+ }
+ lappend result [$obj2 get]
+ $obj1 eval {
+ set var grill
+ }
+ lappend result [$obj1 get] [$obj2 get]
+} -cleanup {
+ FooClass destroy
+} -result {foo bar grill bar}
test oo-16.1 {OO: object introspection} -body {
info object
@@ -1603,10 +1964,10 @@ test oo-16.11 {OO: object introspection} -setup {
} -body {
oo::define foo method spong {} {...}
oo::objdefine bar method boo {a {b c} args} {the body}
- list [info object methods bar -all] [info object methods bar -all -private]
+ list [lsort [info object methods bar -all]] [lsort [info object methods bar -all -private]]
} -cleanup {
foo destroy
-} -result {{boo destroy spong} {boo destroy eval spong unknown variable varname}}
+} -result {{boo destroy spong} {<cloned> boo destroy eval spong unknown variable varname}}
test oo-16.12 {OO: object introspection} -setup {
oo::object create foo
} -cleanup {
@@ -1687,11 +2048,11 @@ test oo-17.9 {OO: class introspection} -setup {
}
}
oo::define subfoo method boo {a {b c} args} {the body}
- list [info class methods subfoo -all] \
- [info class methods subfoo -all -private]
+ list [lsort [info class methods subfoo -all]] \
+ [lsort [info class methods subfoo -all -private]]
} -cleanup {
foo destroy
-} -result {{bar boo destroy} {bar boo destroy eval unknown variable varname}}
+} -result {{bar boo destroy} {<cloned> bar boo destroy eval unknown variable varname}}
test oo-17.10 {OO: class introspection} -setup {
oo::class create foo
} -cleanup {
@@ -1706,7 +2067,7 @@ test oo-18.1 {OO: define command support} {
} {1 foo {foo
while executing
"error foo"
- (in definition script for object "oo::object" line 1)
+ (in definition script for class "::oo::object" line 1)
invoked from within
"oo::define oo::object {error foo}"}}
test oo-18.2 {OO: define command support} {
@@ -1719,7 +2080,7 @@ test oo-18.3 {OO: define command support} {
} {1 bar {bar
while executing
"error bar"
- (in definition script for object "::foo" line 1)
+ (in definition script for class "::foo" line 1)
invoked from within
"oo::class create foo {error bar}"}}
test oo-18.3a {OO: define command support} {
@@ -1729,7 +2090,7 @@ test oo-18.3a {OO: define command support} {
} {1 bar {bar
while executing
"error bar"
- (in definition script for object "::foo" line 2)
+ (in definition script for class "::foo" line 2)
invoked from within
"oo::class create foo {
error bar
@@ -1747,7 +2108,7 @@ test oo-18.3b {OO: define command support} {
("eval" body line 1)
invoked from within
"eval eval error bar"
- (in definition script for object "::foo" line 2)
+ (in definition script for class "::foo" line 2)
invoked from within
"oo::class create foo {
eval eval error bar
@@ -1802,6 +2163,106 @@ test oo-18.5 {OO: more error traces from the guts} -setup {
(class "::cls" method "eval" line 1)
invoked from within
"obj eval {error bar}"}}
+test oo-18.6 {class construction reference management and errors} -setup {
+ oo::class create super_abc
+} -body {
+ catch {
+oo::class create abc {
+ superclass super_abc
+ ::rename abc ::def
+ ::error foo
+}
+ } msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ super_abc destroy
+} -result {foo
+ while executing
+"::error foo"
+ (in definition script for class "::def" line 4)
+ invoked from within
+"oo::class create abc {
+ superclass super_abc
+ ::rename abc ::def
+ ::error foo
+}"}
+test oo-18.7 {OO: objdefine command support} -setup {
+ oo::object create ::inst
+} -body {
+ list [catch {oo::objdefine inst {rename ::inst ::INST;error foo}} msg] $msg $errorInfo
+} -cleanup {
+ catch {::inst destroy}
+ catch {::INST destroy}
+} -result {1 foo {foo
+ while executing
+"error foo"
+ (in definition script for object "::INST" line 1)
+ invoked from within
+"oo::objdefine inst {rename ::inst ::INST;error foo}"}}
+test oo-18.8 {OO: define/self command support} -setup {
+ oo::class create master
+ oo::class create ::foo {superclass master}
+} -body {
+ catch {oo::define foo {rename ::foo ::bar; self {error foobar}}} msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ master destroy
+} -result {foobar
+ while executing
+"error foobar"
+ (in definition script for class object "::bar" line 1)
+ invoked from within
+"self {error foobar}"
+ (in definition script for class "::bar" line 1)
+ invoked from within
+"oo::define foo {rename ::foo ::bar; self {error foobar}}"}
+test oo-18.9 {OO: define/self command support} -setup {
+ oo::class create master
+ set c [oo::class create now_this_is_a_very_very_long_class_name_indeed {
+ superclass master
+ }]
+} -body {
+ catch {oo::define $c {error err}} msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ master destroy
+} -result {err
+ while executing
+"error err"
+ (in definition script for class "::now_this_is_a_very_very_long..." line 1)
+ invoked from within
+"oo::define $c {error err}"}
+test oo-18.10 {OO: define/self command support} -setup {
+ oo::class create master
+ oo::class create ::foo {superclass master}
+} -body {
+ catch {oo::define foo {self {rename ::foo {}; error foobar}}} msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ master destroy
+} -result {foobar
+ while executing
+"error foobar"
+ (in definition script for class object "::foo" line 1)
+ invoked from within
+"self {rename ::foo {}; error foobar}"
+ (in definition script for class "::foo" line 1)
+ invoked from within
+"oo::define foo {self {rename ::foo {}; error foobar}}"}
+test oo-18.11 {OO: define/self command support} -setup {
+ oo::class create master
+ oo::class create ::foo {superclass master}
+} -body {
+ catch {oo::define foo {rename ::foo {}; self {error foobar}}} msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ master destroy
+} -result {this command cannot be called when the object has been deleted
+ while executing
+"self {error foobar}"
+ (in definition script for class "::foo" line 1)
+ invoked from within
+"oo::define foo {rename ::foo {}; self {error foobar}}"}
test oo-19.1 {OO: varname method} -setup {
oo::object create inst
@@ -1836,6 +2297,25 @@ test oo-19.2 {OO: varname method: Bug 2883857} -setup {
} -cleanup {
SpecialClass destroy
} -result ::oo_test::x(y)
+test oo-19.3 {OO: varname method and variable decl: Bug 3603695} -setup {
+ oo::class create testClass {
+ variable foo
+ export varname
+ constructor {} {
+ variable foo x
+ }
+ method bar {obj} {
+ my varname foo
+ $obj varname foo
+ }
+ }
+} -body {
+ testClass create A
+ testClass create B
+ lsearch [list [A varname foo] [B varname foo]] [B bar A]
+} -cleanup {
+ testClass destroy
+} -result 0
test oo-20.1 {OO: variable method} -body {
oo::class create testClass {
@@ -2225,7 +2705,7 @@ test oo-22.1 {OO and info frame} -setup {
list [i level] [i frames] [dict get [c frame] object]
} -cleanup {
c destroy
-} -result {1 {{type source line * file * cmd {info frame 0} method frames class ::c level 0} {type source line * file * cmd {info frame 0} method frames object ::i level 0}} ::c}
+} -result {1 {{* cmd {info frame 0} method frames class ::c level 0} {* cmd {info frame 0} method frames object ::i level 0}} ::c}
test oo-22.2 {OO and info frame: Bug 3001438} -setup {
oo::class create c
} -body {
@@ -2296,6 +2776,16 @@ test oo-24.2 {unknown method method - Bug 1965063} -setup {
}
obj foo bar
} -result {unknown method "foo": must be destroy, dummy, dummy2 or unknown}
+test oo-24.3 {unknown method method - absent method name} -setup {
+ set o [oo::object new]
+} -cleanup {
+ $o destroy
+} -body {
+ oo::objdefine $o method unknown args {
+ return "unknown: >>$args<<"
+ }
+ list [$o] [$o foobar] [$o foo bar]
+} -result {{unknown: >><<} {unknown: >>foobar<<} {unknown: >>foo bar<<}}
# Probably need a better set of tests, but this is quite difficult to devise
test oo-25.1 {call chain caching} -setup {
@@ -2587,6 +3077,173 @@ test oo-27.13 {variables declaration: Bug 3185009: require refcount management}
} -cleanup {
foo destroy
} -result {0 7 1 7 {} 0 1 {can't read "x": no such variable}}
+test oo-27.14 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x
+ variable y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -result {1,1 2,2}
+test oo-27.15 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable
+ variable x y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -result {1,1 2,2}
+test oo-27.16 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x
+ variable -clear
+ variable y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -result {1,1 1,2}
+test oo-27.17 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x
+ variable -set y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -result {1,1 1,2}
+test oo-27.18 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x
+ variable -? y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -returnCodes error -match glob -result {unknown method "-?": must be *}
+test oo-27.19 {variables declaration and [info vars]: Bug 2712377} -setup {
+ oo::class create Foo
+ set result {}
+} -body {
+ # This is really a test of problems to do with Tcl's introspection when a
+ # variable resolver is present...
+ oo::define Foo {
+ variable foo bar
+ method setvars {f b} {
+ set foo $f
+ set bar $b
+ }
+ method dump1 {} {
+ lappend ::result <1>
+ foreach v [lsort [info vars *]] {
+ lappend ::result $v=[set $v]
+ }
+ lappend ::result [info locals] [info locals *]
+ }
+ method dump2 {} {
+ lappend ::result <2>
+ foreach v [lsort [info vars *]] {
+ lappend ::result $v=[set $v]
+ }
+ lappend ::result | foo=$foo [info locals] [info locals *]
+ }
+ }
+ Foo create stuff
+ stuff setvars what ever
+ stuff dump1
+ stuff dump2
+ return $result
+} -cleanup {
+ Foo destroy
+} -result {<1> bar=ever foo=what v v <2> bar=ever foo=what | foo=what v v}
+test oo-27.20 {variables declaration and [info vars]: Bug 2712377} -setup {
+ oo::class create Foo
+ set result {}
+} -body {
+ # This is really a test of problems to do with Tcl's introspection when a
+ # variable resolver is present...
+ oo::define Foo {
+ variable foo bar
+ method setvars {f b} {
+ set foo $f
+ set bar $b
+ }
+ method dump1 {} {
+ lappend ::result <1>
+ foreach v [lsort [info vars *o]] {
+ lappend ::result $v=[set $v]
+ }
+ lappend ::result [info locals] [info locals *]
+ }
+ method dump2 {} {
+ lappend ::result <2>
+ foreach v [lsort [info vars *o]] {
+ lappend ::result $v=[set $v]
+ }
+ lappend ::result | foo=$foo [info locals] [info locals *]
+ }
+ }
+ Foo create stuff
+ stuff setvars what ever
+ stuff dump1
+ stuff dump2
+ return $result
+} -cleanup {
+ Foo destroy
+} -result {<1> foo=what v v <2> foo=what | foo=what v v}
+test oo-27.21 {variables declaration uniqueifies: Bug 3396896} -setup {
+ oo::class create Foo
+} -body {
+ oo::define Foo variable v v v t t v t
+ info class variable Foo
+} -cleanup {
+ Foo destroy
+} -result {v t}
+test oo-27.22 {variables declaration uniqueifies: Bug 3396896} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo variable v v v t t v t
+ info object variable foo
+} -cleanup {
+ foo destroy
+} -result {v t}
# A feature that's not supported because the mechanism may change without
# warning, but is supposed to work...
@@ -2668,6 +3325,184 @@ test oo-31.2 {Bug 3111059: when objects and coroutines entangle} -setup {
} -cleanup {
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
+ }
+}
+
+test oo-32.1 {TIP 380: slots - class test} -setup {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ rename sampleSlot {}
+} -result {0 {a b c} {}}
+test oo-32.2 {TIP 380: slots - class test} -setup {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot -clear] \
+ [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ rename sampleSlot {}
+} -result {0 {} {} {1 Set {}}}
+test oo-32.3 {TIP 380: slots - class test} -setup {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot -append g h i] \
+ [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ 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 {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot -set d e f] \
+ [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ rename sampleSlot {}
+} -result {0 {} {d e f} {1 Set {d e f}}}
+test oo-32.5 {TIP 380: slots - class test} -setup {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot -set d e f] [sampleSlot -append g h i] \
+ [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ 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}}}
+
+test oo-33.1 {TIP 380: slots - defaulting} -setup {
+ set s [SampleSlot new]
+} -body {
+ list [$s x y] [$s contents]
+} -cleanup {
+ rename $s {}
+} -result {{} {a b c x y}}
+test oo-33.2 {TIP 380: slots - defaulting} -setup {
+ set s [SampleSlot new]
+} -body {
+ list [$s destroy; $s unknown] [$s contents]
+} -cleanup {
+ rename $s {}
+} -result {{} {a b c destroy unknown}}
+test oo-33.3 {TIP 380: slots - defaulting} -setup {
+ set s [SampleSlot new]
+} -body {
+ oo::objdefine $s forward --default-operation my -set
+ list [$s destroy; $s unknown] [$s contents] [$s ops]
+} -cleanup {
+ rename $s {}
+} -result {{} unknown {1 Set destroy 1 Set unknown}}
+test oo-33.4 {TIP 380: slots - errors} -setup {
+ set s [SampleSlot new]
+} -body {
+ # Method names beginning with "-" are special to slots
+ $s -grill q
+} -returnCodes error -cleanup {
+ rename $s {}
+} -result {unknown method "-grill": must be -append, -clear, -set, contents or ops}
+
+SampleSlot destroy
+
+test oo-34.1 {TIP 380: slots - presence} -setup {
+ set obj [oo::object new]
+ set result {}
+} -body {
+ oo::define oo::object {
+ ::lappend ::result [::info object class filter]
+ ::lappend ::result [::info object class mixin]
+ ::lappend ::result [::info object class superclass]
+ ::lappend ::result [::info object class variable]
+ }
+ oo::objdefine $obj {
+ ::lappend ::result [::info object class filter]
+ ::lappend ::result [::info object class mixin]
+ ::lappend ::result [::info object class variable]
+ }
+ return $result
+} -cleanup {
+ $obj destroy
+} -result {::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot}
+test oo-34.2 {TIP 380: slots - presence} {
+ lsort [info class instances oo::Slot]
+} {::oo::define::filter ::oo::define::mixin ::oo::define::superclass ::oo::define::variable ::oo::objdefine::filter ::oo::objdefine::mixin ::oo::objdefine::variable}
+proc getMethods obj {
+ list [lsort [info object methods $obj -all]] \
+ [lsort [info object methods $obj -private]]
+}
+test oo-34.3 {TIP 380: slots - presence} {
+ getMethods oo::define::filter
+} {{-append -clear -set} {Get Set}}
+test oo-34.4 {TIP 380: slots - presence} {
+ getMethods oo::define::mixin
+} {{-append -clear -set} {--default-operation Get Set}}
+test oo-34.5 {TIP 380: slots - presence} {
+ getMethods oo::define::superclass
+} {{-append -clear -set} {--default-operation Get Set}}
+test oo-34.6 {TIP 380: slots - presence} {
+ getMethods oo::define::variable
+} {{-append -clear -set} {Get Set}}
+test oo-34.7 {TIP 380: slots - presence} {
+ getMethods oo::objdefine::filter
+} {{-append -clear -set} {Get Set}}
+test oo-34.8 {TIP 380: slots - presence} {
+ getMethods oo::objdefine::mixin
+} {{-append -clear -set} {--default-operation Get Set}}
+test oo-34.9 {TIP 380: slots - presence} {
+ getMethods oo::objdefine::variable
+} {{-append -clear -set} {Get Set}}
+
+test oo-35.1 {Bug 9d61624b3d: Empty superclass must not cause crash} -setup {
+ oo::class create fruit {
+ method eat {} {}
+ }
+ set result {}
+} -body {
+ lappend result [fruit create ::apple] [info class superclasses fruit]
+ oo::define fruit superclass
+ lappend result [info class superclasses fruit] \
+ [info object class apple oo::object] \
+ [info class call fruit destroy] \
+ [catch { apple }]
+} -cleanup {
+ unset -nocomplain result
+ fruit destroy
+} -result {::apple ::oo::object ::oo::object 1 {{method destroy ::oo::object {core method: "destroy"}}} 1}
+test oo-35.2 {Bug 9d61624b3d: Empty superclass must not cause crash} -setup {
+ oo::class create fruitMetaclass {
+ superclass oo::class
+ method eat {} {}
+ }
+ set result {}
+} -body {
+ lappend result [fruitMetaclass create ::appleClass] \
+ [appleClass create orange] \
+ [info class superclasses fruitMetaclass]
+ oo::define fruitMetaclass superclass
+ lappend result [info class superclasses fruitMetaclass] \
+ [info object class appleClass oo::class] \
+ [catch { orange }] [info object class orange] \
+ [appleClass create pear]
+} -cleanup {
+ unset -nocomplain result
+ fruitMetaclass destroy
+} -result {::appleClass ::orange ::oo::class ::oo::class 1 1 ::appleClass ::pear}
cleanupTests
return
diff --git a/tests/ooNext2.test b/tests/ooNext2.test
index eeade11..a47aa91 100644
--- a/tests/ooNext2.test
+++ b/tests/ooNext2.test
@@ -2,16 +2,14 @@
# Sourcing this file into Tcl runs the tests and generates output for errors.
# No output means no errors were found.
#
-# Copyright (c) 2006-2008 Donal K. Fellows
+# Copyright (c) 2006-2011 Donal K. Fellows
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# RCS: @(#) $Id: oo.test,v 1.59 2011/01/18 16:10:48 dkf Exp $
-package require -exact TclOO 0.6.3 ;# Must match value in configure.in
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest 2
+package require TclOO 1.0.1
+package require tcltest 2
+if {"::tcltest" in [namespace children]} {
namespace import -force ::tcltest::*
}
diff --git a/tests/parse.test b/tests/parse.test
index 3523975..01443c9 100644
--- a/tests/parse.test
+++ b/tests/parse.test
@@ -16,6 +16,9 @@ if {[catch {package require tcltest 2.0.2}]} {
namespace eval ::tcl::test::parse {
namespace import ::tcltest::*
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testparser [llength [info commands testparser]]
testConstraint testevalobjv [llength [info commands testevalobjv]]
testConstraint testevalex [llength [info commands testevalex]]
@@ -23,6 +26,8 @@ testConstraint testparsevarname [llength [info commands testparsevarname]]
testConstraint testparsevar [llength [info commands testparsevar]]
testConstraint testasync [llength [info commands testasync]]
testConstraint testcmdtrace [llength [info commands testcmdtrace]]
+testConstraint testevent [llength [info commands testevent]]
+testConstraint memory [llength [info commands memory]]
test parse-1.1 {Tcl_ParseCommand procedure, computing string length} testparser {
testparser [bytestring "foo\0 bar"] -1
@@ -435,7 +440,7 @@ test parse-8.12 {Tcl_EvalObjv procedure, TCL_EVAL_INVOKE} {
test parse-9.1 {Tcl_LogCommandInfo, line numbers} testevalex {
- catch {unset x}
+ unset -nocomplain x
list [catch {testevalex {for {} 1 {} {
@@ -476,7 +481,7 @@ test parse-10.3 {Tcl_EvalTokens, nested commands} testevalex {
testevalex {concat [expr 2 + 6]}
} {8}
test parse-10.4 {Tcl_EvalTokens, nested commands} testevalex {
- catch {unset a}
+ unset -nocomplain a
list [catch {testevalex {concat xxx[expr $a]}} msg] $msg
} {1 {can't read "a": no such variable}}
test parse-10.5 {Tcl_EvalTokens, simple variables} testevalex {
@@ -484,21 +489,21 @@ test parse-10.5 {Tcl_EvalTokens, simple variables} testevalex {
testevalex {concat $a}
} {hello}
test parse-10.6 {Tcl_EvalTokens, array variables} testevalex {
- catch {unset a}
+ unset -nocomplain a
set a(12) 46
testevalex {concat $a(12)}
} {46}
test parse-10.7 {Tcl_EvalTokens, array variables} testevalex {
- catch {unset a}
+ unset -nocomplain a
set a(12) 46
testevalex {concat $a(1[expr 3 - 1])}
} {46}
test parse-10.8 {Tcl_EvalTokens, array variables} testevalex {
- catch {unset a}
+ unset -nocomplain a
list [catch {testevalex {concat $x($a)}} msg] $msg
} {1 {can't read "a": no such variable}}
test parse-10.9 {Tcl_EvalTokens, array variables} testevalex {
- catch {unset a}
+ unset -nocomplain a
list [catch {testevalex {concat xyz$a(1)}} msg] $msg
} {1 {can't read "a(1)": no such variable}}
test parse-10.10 {Tcl_EvalTokens, object values} testevalex {
@@ -538,11 +543,11 @@ test parse-11.2 {Tcl_EvalEx, error while parsing} testevalex {
list [catch {testevalex {concat "abc}} msg] $msg
} {1 {missing "}}
test parse-11.3 {Tcl_EvalEx, error while collecting words} testevalex {
- catch {unset a}
+ unset -nocomplain a
list [catch {testevalex {concat xyz $a}} msg] $msg
} {1 {can't read "a": no such variable}}
test parse-11.4 {Tcl_EvalEx, error in Tcl_EvalObjv call} testevalex {
- catch {unset a}
+ unset -nocomplain a
list [catch {testevalex {_bogus_ a b c d}} msg] $msg
} {1 {invalid command name "_bogus_"}}
test parse-11.5 {Tcl_EvalEx, exceptional return} testevalex {
@@ -561,7 +566,7 @@ test parse-11.8 {Tcl_EvalEx, multiple commands in script} testevalex {
}] $a $c
} {d b d}
test parse-11.9 {Tcl_EvalEx, freeing memory after error} testevalex {
- catch {unset a}
+ unset -nocomplain a
list [catch {testevalex {concat a b c d e f g h i j k l m n o p q r s t u v w x y z $a}} msg] $msg
} {1 {can't read "a": no such variable}}
test parse-11.10 {Tcl_EvalTokens, empty commands} testevalex {
@@ -667,13 +672,33 @@ test parse-13.3 {Tcl_ParseVar procedure, no variable name} testparsevar {
testparsevar {$.123}
} {{$} .123}
test parse-13.4 {Tcl_ParseVar procedure, error looking up variable} testparsevar {
- catch {unset abc}
+ unset -nocomplain abc
list [catch {testparsevar {$abc}} msg] $msg
} {1 {can't read "abc": no such variable}}
test parse-13.5 {Tcl_ParseVar procedure, error looking up variable} testparsevar {
- catch {unset abc}
+ unset -nocomplain abc
list [catch {testparsevar {$abc([bogus x y z])}} msg] $msg
} {1 {invalid command name "bogus"}}
+test parse-13.6 {Tcl_ParseVar memory leak} -constraints memory -setup {
+ proc getbytes {} {
+ return [lindex [split [memory info] \n] 3 3]
+ }
+} -body {
+ set a() foo
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ set vn {}
+ set res [testparsevar [append vn $ a([string repeat {[]} 19]) bar]]
+ if {$res ne {foo bar}} {error "Unexpected result: $res"}
+
+ set tmp $end
+ set end [getbytes]
+ }
+ expr {$end - $tmp}
+} -cleanup {
+ unset -nocomplain a end i vn res tmp
+ rename getbytes {}
+} -result 0
test parse-14.1 {Tcl_ParseBraces procedure, computing string length} testparser {
testparser [bytestring "foo\0 bar"] -1
@@ -1087,6 +1112,19 @@ test parse-20.12 {TclParseBackslash: truncated escape} testparser {
testparser {\x12X} 5
} {- {\x12X} 1 word {\x12X} 2 backslash {\x12} 0 text X 0 {}}
+test parse-21.0 {Bug 1884496} testevent {
+ set ::script {testevent delete a; set a [p]; set ::done $a}
+ proc ::p {} {string first s $::script}
+ testevent queue a head $::script
+ vwait done
+} {}
+test parse-21.1 {TCL_EVAL_DIRECT coverage} testevent {
+ testevent queue a head {testevent delete a; \
+ set ::done [dict get [info frame 0] line]}
+ vwait done
+ set ::done
+} 2
+
cleanupTests
}
diff --git a/tests/parseExpr.test b/tests/parseExpr.test
index 7673dbe..714c45b 100644
--- a/tests/parseExpr.test
+++ b/tests/parseExpr.test
@@ -8,10 +8,11 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest 2
- namespace import -force ::tcltest::*
-}
+package require tcltest 2
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
# Note that the Tcl expression parser (tclCompExpr.c) does not check
# the semantic validity of the expressions it parses. It does not check,
@@ -997,6 +998,72 @@ test parseExpr-21.63 {error message} -body {
} -returnCodes error -result "missing close-brace
in expression \"...12345678901234567890*\[\{abcdefghijklmnopqrstuv...\""
+test parseExpr-22.1 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser 2a() 1
+} -result {- {} 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-22.2 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser nana() 3
+} -result {- {} 0 subexpr nan 1 text nan 0 {}}
+test parseExpr-22.3 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser 2a() -1
+} -result {- {} 0 subexpr 2a() 1 operator 2a 0 {}}
+test parseExpr-22.4 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser nana() -1
+} -result {- {} 0 subexpr nana() 1 operator nana 0 {}}
+test parseExpr-22.5 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser nan9() -1
+} -result {- {} 0 subexpr nan9() 1 operator nan9 0 {}}
+test parseExpr-22.6 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser 2_() -1
+} -result {- {} 0 subexpr 2_() 1 operator 2_ 0 {}}
+test parseExpr-22.7 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser nan_() -1
+} -result {- {} 0 subexpr nan_() 1 operator nan_ 0 {}}
+test parseExpr-22.8 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser nan!() -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR MISSING}
+test parseExpr-22.9 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser 1e3_() -1
+} -result {- {} 0 subexpr 1e3_() 1 operator 1e3_ 0 {}}
+test parseExpr-22.10 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 1.3_() -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADCHAR}
+test parseExpr-22.11 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 1e-3_() -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADCHAR}
+test parseExpr-22.12 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser naneq() -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR EMPTY}
+test parseExpr-22.13 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser naner() -1
+} -result {- {} 0 subexpr naner() 1 operator naner 0 {}}
+
+test parseExpr-22.14 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 08 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER OCTAL}
+test parseExpr-22.15 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 0o8 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER OCTAL}
+test parseExpr-22.16 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 0o08 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER OCTAL}
+test parseExpr-22.17 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 0b2 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER BINARY}
+test parseExpr-22.18 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 0b02 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER BINARY}
+
+
# cleanup
-::tcltest::cleanupTests
+cleanupTests
return
diff --git a/tests/parseOld.test b/tests/parseOld.test
index 132481c..f3b1591 100644
--- a/tests/parseOld.test
+++ b/tests/parseOld.test
@@ -13,10 +13,11 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest
- namespace import -force ::tcltest::*
-}
+package require tcltest
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
testConstraint testwordend [llength [info commands testwordend]]
@@ -163,25 +164,25 @@ test parseOld-5.6 {variable substitution} {
set msg
} {can't read "_non_existent_": no such variable}
test parseOld-5.7 {array variable substitution} {
- catch {unset a}
+ unset -nocomplain a
set a(xyz) 123
set b $a(xyz)foo
set b
} 123foo
test parseOld-5.8 {array variable substitution} {
- catch {unset a}
+ unset -nocomplain a
set "a(x y z)" 123
set b $a(x y z)foo
set b
} 123foo
test parseOld-5.9 {array variable substitution} {
- catch {unset a}; catch {unset qqq}
+ unset -nocomplain a qqq
set "a(x y z)" qqq
set $a([format x]\ y [format z]) foo
set qqq
} foo
test parseOld-5.10 {array variable substitution} {
- catch {unset a}
+ unset -nocomplain a
list [catch {set b $a(22)} msg] $msg
} {1 {can't read "a(22)": no such variable}}
test parseOld-5.11 {array variable substitution} {
@@ -191,9 +192,9 @@ test parseOld-5.11 {array variable substitution} {
test parseOld-5.12 {empty array name support} {
list [catch {set b a$()} msg] $msg
} {1 {can't read "()": no such variable}}
-catch {unset a}
+unset -nocomplain a
test parseOld-5.13 {array variable substitution} {
- catch {unset a}
+ unset -nocomplain a
set long {This is a very long variable, long enough to cause storage \
allocation to occur in Tcl_ParseVar. If that storage isn't getting \
freed up correctly, then a core leak will occur when this test is \
@@ -208,13 +209,13 @@ test parseOld-5.13 {array variable substitution} {
run. This text is probably beginning to sound like drivel, but I've \
run out of things to say and I need more characters still.}}}
test parseOld-5.14 {array variable substitution} {
- catch {unset a}; catch {unset b}; catch {unset a1}
+ unset -nocomplain a b a1
set a1(22) foo
set a(foo) bar
set b $a($a1(22))
set b
} bar
-catch {unset a}; catch {unset a1}
+unset -nocomplain a a1
test parseOld-7.1 {backslash substitution} {
set a "\a\c\n\]\}"
diff --git a/tests/pkgMkIndex.test b/tests/pkgMkIndex.test
index 0fe394e..84c82ce 100644
--- a/tests/pkgMkIndex.test
+++ b/tests/pkgMkIndex.test
@@ -8,10 +8,8 @@
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest 2
- namespace import -force ::tcltest::*
-}
+package require tcltest 2
+namespace import ::tcltest::*
set fullPkgPath [makeDirectory pkg]
@@ -45,7 +43,7 @@ proc pkgtest::parseArgs { args } {
set a [lindex $args $iarg]
if {[regexp {^-} $a]} {
lappend options $a
- if {[string compare -load $a] == 0} {
+ if {$a eq "-load"} {
incr iarg
lappend options [lindex $args $iarg]
}
@@ -81,7 +79,7 @@ proc pkgtest::parseIndex { filePath } {
$slave eval {
rename package package_original
proc package { args } {
- if {[string compare [lindex $args 0] ifneeded] == 0} {
+ if {[lindex $args 0] eq "ifneeded"} {
set pkg [lindex $args 1]
set ver [lindex $args 2]
set ::PKGS($pkg:$ver) [lindex $args 3]
@@ -111,9 +109,9 @@ proc pkgtest::parseIndex { filePath } {
foreach k [lsort [array names P]] {
lappend PKGS $k $P($k)
}
- } err]} {
- set ei $::errorInfo
- set ec $::errorCode
+ } err opts]} {
+ set ei [dict get $opts -errorinfo]
+ set ec [dict get $opts -errorcode]
catch {interp delete $slave}
diff --git a/tests/platform.test b/tests/platform.test
index 8cb8dcd..6596975 100644
--- a/tests/platform.test
+++ b/tests/platform.test
@@ -9,12 +9,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
- namespace import -force ::tcltest::*
-}
+package require tcltest 2
+
+namespace eval ::tcl::test::platform {
+ namespace import ::tcltest::testConstraint
+ namespace import ::tcltest::test
+ namespace import ::tcltest::cleanupTests
+
+ variable ::tcl_platform
-testConstraint testWinCPUID [llength [info commands testwincpuid]]
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testCPUID [llength [info commands testcpuid]]
test platform-1.1 {TclpSetVariables: tcl_platform} {
interp create i
@@ -36,12 +43,12 @@ test platform-2.1 {tcl_platform(wordSize) indicates size of native word} {
list [expr {$result < 0}] [expr {$result ^ int($result - 1)}]
} {1 -1}
-# On Windows, test that the CPU ID works
+# On Windows/UNIX, test that the CPU ID works
-test platform-3.1 {CPU ID on Windows } \
- -constraints testWinCPUID \
+test platform-3.1 {CPU ID on Windows/UNIX} \
+ -constraints testCPUID \
-body {
- set cpudata [testwincpuid 0]
+ set cpudata [testcpuid 0]
binary format iii \
[lindex $cpudata 1] \
[lindex $cpudata 3] \
@@ -51,7 +58,10 @@ test platform-3.1 {CPU ID on Windows } \
-result {^(?:AuthenticAMD|CentaurHauls|CyrixInstead|GenuineIntel)$}
# cleanup
-::tcltest::cleanupTests
+cleanupTests
+
+}
+namespace delete ::tcl::test::platform
return
# Local Variables:
diff --git a/tests/proc.test b/tests/proc.test
index ed3c4b6..e06720e 100644
--- a/tests/proc.test
+++ b/tests/proc.test
@@ -374,6 +374,15 @@ test proc-7.3 {Returning loop exception from redefined cmd: Bug 729692} -body {
} -cleanup {
namespace delete ugly
} -result 4
+
+test proc-7.4 {Proc struct outlives its interp: Bug 3532959} {
+ set lambda x
+ lappend lambda {set a 1}
+ interp create slave
+ slave eval [list apply $lambda foo]
+ interp delete slave
+ unset lambda
+} {}
# cleanup
catch {rename p ""}
diff --git a/tests/reg.test b/tests/reg.test
index d92339f..e6ce42c 100644
--- a/tests/reg.test
+++ b/tests/reg.test
@@ -13,6 +13,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest 2
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
# All tests require the testregexp command, return if this
# command doesn't exist
@@ -174,14 +177,32 @@ namespace eval RETest {
return $ret
}
+ # Share the generation of the list of test constraints so it is
+ # done the same on all routes.
+ proc TestConstraints {flags} {
+ set constraints [list testregexp]
+
+ variable regBug
+ if {$regBug} {
+ # This will trigger registration as a skipped test
+ lappend constraints knownBug
+ }
+
+ # Tcl locale stuff doesn't do the ch/xy test fakery yet
+ if {[string match *+* $flags]} {
+ # This will trigger registration as a skipped test
+ lappend constraints localeRegexp
+ }
+
+ return $constraints
+ }
+
# match expected, internal routine that does the work
# parameters like the "real" routines except they don't have "opts",
# which is a possibly-empty list of switches for the regexp match attempt
# The ! flag is used to indicate expected match failure (for REG_EXPECT,
# which wants argument testing even in the event of failure).
proc MatchExpected {opts testid flags re target args} {
- variable regBug
-
# if &, test as both BRE and ARE
if {[string match *&* $flags]} {
set f [string map {& {}} $flags]
@@ -190,18 +211,7 @@ namespace eval RETest {
return
}
- set constraints [list testregexp]
-
- if {$regBug} {
- # This will register as a skipped test
- lappend constraints knownBug
- }
-
- # Tcl locale stuff doesn't do the ch/xy test fakery yet
- if {[string match *+* $flags]} {
- # This will register as a skipped test
- lappend constraints localeRegexp
- }
+ set constraints [TestConstraints $flags]
set f [TestFlags $flags]
set infoflags [TestInfoFlags $flags]
@@ -252,13 +262,7 @@ namespace eval RETest {
return
}
- set constraints [list testregexp]
-
- # Tcl locale stuff doesn't do the ch/xy test fakery yet
- if {[string match *+* $flags]} {
- # This will register as a skipped test
- lappend constraints localeRegexp
- }
+ set constraints [TestConstraints $flags]
set cmd [list testregexp -about {*}[TestFlags $flags] $re]
::tcltest::test [TestNum $testid error] [TestDesc $testid error] \
@@ -268,6 +272,7 @@ namespace eval RETest {
# match failure expected
proc expectNomatch {testid flags re target args} {
+ variable regBug
# if &, test as both ARE and BRE
if {[string match *&* $flags]} {
set f [string map {& {}} $flags]
@@ -276,13 +281,7 @@ namespace eval RETest {
return
}
- set constraints [list testregexp]
-
- # Tcl locale stuff doesn't do the ch/xy test fakery yet
- if {[string match *+* $flags]} {
- # This will register as a skipped test
- lappend constraints localeRegexp
- }
+ set constraints [TestConstraints $flags]
set f [TestFlags $flags]
set infoflags [TestInfoFlags $flags]
@@ -331,7 +330,7 @@ namespace eval RETest {
}
}
namespace import RETest::*
-
+
######## the tests themselves ########
# support functions and preliminary misc.
@@ -626,16 +625,24 @@ expectMatch 13.13 P "a\\nb" "a\nb" "a\nb"
expectMatch 13.14 P "a\\rb" "a\rb" "a\rb"
expectMatch 13.15 P "a\\tb" "a\tb" "a\tb"
expectMatch 13.16 P "a\\u0008x" "a\bx" "a\bx"
-expectError 13.17 - {a\u008x} EESCAPE
+expectMatch 13.17 P {a\u008x} "a\bx" "a\bx"
expectMatch 13.18 P "a\\u00088x" "a\b8x" "a\b8x"
expectMatch 13.19 P "a\\U00000008x" "a\bx" "a\bx"
-expectError 13.20 - {a\U0000008x} EESCAPE
+expectMatch 13.20 P {a\U0000008x} "a\bx" "a\bx"
expectMatch 13.21 P "a\\vb" "a\vb" "a\vb"
expectMatch 13.22 MP "a\\x08x" "a\bx" "a\bx"
expectError 13.23 - {a\xq} EESCAPE
-expectMatch 13.24 MP "a\\x0008x" "a\bx" "a\bx"
+expectMatch 13.24 MP "a\\x08x" "a\bx" "a\bx"
expectError 13.25 - {a\z} EESCAPE
expectMatch 13.26 MP "a\\010b" "a\bb" "a\bb"
+expectMatch 13.27 P "a\\U00001234x" "a\u1234x" "a\u1234x"
+expectMatch 13.28 P {a\U00001234x} "a\u1234x" "a\u1234x"
+expectMatch 13.29 P "a\\U0001234x" "a\u1234x" "a\u1234x"
+expectMatch 13.30 P {a\U0001234x} "a\u1234x" "a\u1234x"
+expectMatch 13.31 P "a\\U000012345x" "a\u12345x" "a\u12345x"
+expectMatch 13.32 P {a\U000012345x} "a\u12345x" "a\u12345x"
+expectMatch 13.33 P "a\\U1000000x" "a\ufffd0x" "a\ufffd0x"
+expectMatch 13.34 P {a\U1000000x} "a\ufffd0x" "a\ufffd0x"
doing 14 "back references"
@@ -660,6 +667,9 @@ expectMatch 14.17 RP {a([bc])(\1*)} ab ab b ""
expectError 14.18 - {a((b)\1)} ESUBREG
expectError 14.19 - {a(b)c\2} ESUBREG
expectMatch 14.20 bR {a\(b*\)c\1} abbcbb abbcbb bb
+expectMatch 14.21 RP {^([bc])\1*$} bbb bbb b
+expectMatch 14.22 RP {^([bc])\1*$} ccc ccc c
+knownBug expectNomatch 14.23 R {^([bc])\1*$} bcb
doing 15 "octal escapes vs back references"
@@ -682,6 +692,7 @@ expectError 15.9 - {a((((((((((b\10))))))))))c} ESUBREG
expectMatch 15.10 MP "a\\12b" "a\nb" "a\nb"
expectError 15.11 b {a\12b} ESUBREG
expectMatch 15.12 eAS {a\12b} a12b a12b
+expectMatch 15.13 MP {a\701b} a\u00381b a\u00381b
doing 16 "expanded syntax"
@@ -1069,7 +1080,89 @@ test reg-33.13 {Bug 1810264 - infinite loop} {
test reg-33.14 {Bug 1810264 - super-expensive expression} nonPortable {
regexp {(x{200}){200}$y} {x}
} 0
-
+test reg-33.15 {Bug 3603557 - an "in the wild" RE} {
+ lindex [regexp -expanded -about {
+ ^TETRA_MODE_CMD # Message Type
+ ([[:blank:]]+) # Pad
+ (ETS_1_1|ETS_1_2|ETS_2_2) # SystemCode
+ ([[:blank:]]+) # Pad
+ (CONTINUOUS|CARRIER|MCCH|TRAFFIC) # SharingMode
+ ([[:blank:]]+) # Pad
+ ([[:digit:]]{1,2}) # ColourCode
+ ([[:blank:]]+) # Pad
+ (1|2|3|4|6|9|12|18) # TSReservedFrames
+ ([[:blank:]]+) # Pad
+ (PASS|TRUE|FAIL|FALSE) # UPlaneDTX
+ ([[:blank:]]+) # Pad
+ (PASS|TRUE|FAIL|FALSE) # Frame18Extension
+ ([[:blank:]]+) # Pad
+ ([[:digit:]]{1,4}) # MCC
+ ([[:blank:]]+) # Pad
+ ([[:digit:]]{1,5}) # MNC
+ ([[:blank:]]+) # Pad
+ (BOTH|BCAST|ENQRY|NONE) # NbrCellBcast
+ ([[:blank:]]+) # Pad
+ (UNKNOWN|LOW|MEDIUM|HIGH) # CellServiceLevel
+ ([[:blank:]]+) # Pad
+ (PASS|TRUE|FAIL|FALSE) # LateEntryInfo
+ ([[:blank:]]+) # Pad
+ (300|400) # FrequencyBand
+ ([[:blank:]]+) # Pad
+ (NORMAL|REVERSE) # ReverseOperation
+ ([[:blank:]]+) # Pad
+ (NONE|\+6\.25|\-6\.25|\+12\.5) # Offset
+ ([[:blank:]]+) # Pad
+ (10) # DuplexSpacing
+ ([[:blank:]]+) # Pad
+ ([[:digit:]]{1,4}) # MainCarrierNr
+ ([[:blank:]]+) # Pad
+ (0|1|2|3) # NrCSCCH
+ ([[:blank:]]+) # Pad
+ (15|20|25|30|35|40|45) # MSTxPwrMax
+ ([[:blank:]]+) # Pad
+ (\-125|\-120|\-115|\-110|\-105|\-100|\-95|\-90|\-85|\-80|\-75|\-70|\-65|\-60|\-55|\-50)
+ # RxLevAccessMin
+ ([[:blank:]]+) # Pad
+ (\-53|\-51|\-49|\-47|\-45|\-43|\-41|\-39|\-37|\-35|\-33|\-31|\-29|\-27|\-25|\-23)
+ # AccessParameter
+ ([[:blank:]]+) # Pad
+ (DISABLE|[[:digit:]]{3,4}) # RadioDLTimeout
+ ([[:blank:]]+) # Pad
+ (\-[[:digit:]]{2,3}) # RSSIThreshold
+ ([[:blank:]]+) # Pad
+ ([[:digit:]]{1,5}) # CCKIdSCKVerNr
+ ([[:blank:]]+) # Pad
+ ([[:digit:]]{1,5}) # LocationArea
+ ([[:blank:]]+) # Pad
+ ([(1|0)]{16}) # SubscriberClass
+ ([[:blank:]]+) # Pad
+ ([(1|0)]{12}) # BSServiceDetails
+ ([[:blank:]]+) # Pad
+ (RANDOMIZE|IMMEDIATE|[[:digit:]]{1,2}) # IMM
+ ([[:blank:]]+) # Pad
+ ([[:digit:]]{1,2}) # WT
+ ([[:blank:]]+) # Pad
+ ([[:digit:]]{1,2}) # Nu
+ ([[:blank:]]+) # Pad
+ ([0-1]) # FrameLngFctr
+ ([[:blank:]]+) # Pad
+ ([[:digit:]]{1,2}) # TSPtr
+ ([[:blank:]]+) # Pad
+ ([0-7]) # MinPriority
+ ([[:blank:]]+) # Pad
+ (PASS|TRUE|FAIL|FALSE) # ExtdSrvcsEnabled
+ ([[:blank:]]+) # Pad
+ (.*) # ConditionalFields
+ }] 0
+} 68
+test reg-33.16 {Bug [8d2c0da36d]- another "in the wild" RE} {
+ lindex [regexp -about "^MRK:client1: =1339 14HKelly Talisman 10011000 (\[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]*) \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 8 0 8 0 0 0 77 77 1 1 2 0 11 { 1 3 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 13HC6 My Creator 2 3 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 31HC7 Slightly offensive name, huh 3 8 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 23HE-mail:kelly@hotbox.com 4 9 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 17Hcompface must die 5 10 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 0 3HAir 6 12 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 14HPGP public key 7 13 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 16Hkelly@hotbox.com 8 30 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 0 12H2 text/plain 9 30 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 0 13H2 x-kom/basic 10 33 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 1H0 11 14 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 1H3 }\r?"] 0
+} 1
+
# cleanup
::tcltest::cleanupTests
return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/regexp.test b/tests/regexp.test
index 7cafd1b..1b2bec9 100644
--- a/tests/regexp.test
+++ b/tests/regexp.test
@@ -819,6 +819,67 @@ test regexp-22.1 {Bug 1810038} {
test regexp-22.2 {regexp compile and backrefs, Bug 1857126} {
regexp -- {([bc])\1} bb
} 1
+test regexp-22.3 {Bug 3604074} {
+ # This will hang in interps where the bug is not fixed
+ regexp ((((((((a)*)*)*)*)*)*)*)* a
+} 1
+test regexp-22.4 {Bug 3606139} -setup {
+ interp alias {} a {} string repeat a
+} -body {
+ # This crashes in interps where the bug is not fixed
+ regexp [join [list [a 160]([a 55])[a 668]([a 55])[a 669]([a 55]) \
+ [a 668]([a 55])[a 649]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+ [a 672]([a 55])[a 669]([a 55])[a 671]([a 55])[a 671]([a 55]) \
+ [a 672]([a 55])[a 652]([a 55])[a 672]([a 55])[a 671]([a 55]) \
+ [a 671]([a 55])[a 671]([a 55])[a 653]([a 55])[a 672]([a 55]) \
+ [a 653]([a 55])[a 672]([a 55])[a 672]([a 55])[a 652]([a 55]) \
+ [a 671]([a 55])[a 652]([a 55])[a 652]([a 55])[a 672]([a 55]) \
+ [a 672]([a 55])[a 672]([a 55])[a 653]([a 55])[a 671]([a 55]) \
+ [a 669]([a 55])[a 649]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+ [a 668]([a 55])[a 650]([a 55])[a 650]([a 55])[a 672]([a 55]) \
+ [a 669]([a 55])[a 669]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+ [a 668]([a 55])[a 669]([a 55])[a 672]([a 55])[a 669]([a 55]) \
+ [a 669]([a 55])[a 669]([a 55])[a 669]([a 55])[a 672]([a 55]) \
+ [a 670]([a 55])[a 671]([a 55])[a 672]([a 55])[a 672]([a 55]) \
+ [a 671]([a 55])[a 671]([a 55])[a 672]([a 55])[a 669]([a 55]) \
+ [a 668]([a 55])[a 668]([a 55])[a 669]([a 55])[a 668]([a 55]) \
+ [a 669]([a 55])[a 668]([a 55])[a 669]([a 55])[a 669]([a 55]) \
+ [a 668]([a 55])[a 668]([a 55])[a 669]([a 55])[a 668]([a 55]) \
+ [a 669]([a 55])[a 669]([a 55])[a 669]([a 55])[a 669]([a 55]) \
+ [a 668]([a 55])[a 669]([a 55])[a 672]([a 55])[a 669]([a 55]) \
+ [a 669]([a 55])[a 669]([a 55])[a 669]([a 55])[a 668]([a 55]) \
+ [a 669]([a 55])[a 669]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+ [a 668]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \
+ [a 672]([a 55])[a 669]([a 55])[a 669]([a 55])[a 710]([a 55]) \
+ [a 668]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \
+ [a 668]([a 55])[a 669]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+ [a 668]([a 55])[a 668]([a 55])[a 668]([a 55])[a 669]([a 55]) \
+ [a 672]([a 55])[a 669]([a 55])[a 669]([a 55])[a 668]([a 55]) \
+ [a 669]([a 55])[a 669]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+ [a 668]([a 55])[a 668]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+ [a 667]([a 55])[a 668]([a 55])[a 669]([a 55])[a 668]([a 55]) \
+ [a 671]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \
+ [a 669]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \
+ [a 668]([a 55])[a 710]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+ [a 668]([a 55])[a 668]([a 55])[a 668]([a 55])[a 511]] {}] a
+} -cleanup {
+ rename a {}
+} -returnCodes 1 -result {couldn't compile regular expression pattern: nfa has too many states}
+test regexp-22.5 {Bug 3610026} -setup {
+ set e {}
+ set cp 99
+ while {$cp < 32864} {
+ append e [format %c [incr cp]]
+ }
+} -body {
+ regexp -about $e
+} -cleanup {
+ unset -nocomplain e cp
+} -returnCodes error -match glob -result {*too many colors*}
+test regexp-22.6 {Bug 6585b21ca8} {
+ expr {[regexp {(\w).*?\1} Programmer m] ? $m : "<NONE>"}
+} rogr
+
test regexp-23.1 {regexp -all and -line} {
set string ""
diff --git a/tests/registry.test b/tests/registry.test
index 7234a32..77588e3 100644
--- a/tests/registry.test
+++ b/tests/registry.test
@@ -17,13 +17,10 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
testConstraint reg 0
if {[testConstraint win]} {
- catch {
- # Is the registry extension already static to this shell?
- if [catch {load {} Registry; set ::reglib {}}] {
- # try the location given to use on the commandline to tcltest
+ if {![catch {
::tcltest::loadTestedCommands
- load $::reglib Registry
- }
+ set ::regver [package require registry 1.3.0]
+ }]} {
testConstraint reg 1
}
}
@@ -34,6 +31,9 @@ testConstraint english [expr {
&& [string match "English*" [testlocale all ""]]
}]
+test registry-1.0 {check if we are testing the right dll} {win reg} {
+ set ::regver
+} {1.3.0}
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 ...?"}}
@@ -505,6 +505,12 @@ 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} {
+ 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
+ set result
+} [string repeat x 16383]
test registry-7.1 {GetValueNames: bad key} -constraints {win reg english} -setup {
registry delete HKEY_CURRENT_USER\\TclFoobar
diff --git a/tests/rename.test b/tests/rename.test
index 9ac49b4..ebf5425 100644
--- a/tests/rename.test
+++ b/tests/rename.test
@@ -16,6 +16,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testdel [llength [info commands testdel]]
# Must eliminate the "unknown" command while the test is running, especially
@@ -137,6 +140,13 @@ test rename-4.7 {reentrancy issues with command deletion and renaming} testdel {
if {[info exists env(value)]} {
unset env(value)
}
+test rename-4.8 {Bug a16752c252} testdel {
+ set x broken
+ testdel {} foo {set x ok}
+ proc foo args {}
+ rename foo {}
+ return -level 0 $x[unset x]
+} ok
# Save the unknown procedure which is modified by the following test.
diff --git a/tests/resolver.test b/tests/resolver.test
new file mode 100644
index 0000000..e73ea50
--- /dev/null
+++ b/tests/resolver.test
@@ -0,0 +1,203 @@
+# This test collection covers some unwanted interactions between command
+# literal sharing and the use of command resolvers (per-interp) which cause
+# command literals to be re-used with their command references being invalid
+# in the reusing context. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2011 Gustaf Neumann <gustaf.neumann@wu.ac.at>
+# Copyright (c) 2011 Stefan Sobernig <stefan.sobernig@wu.ac.at>
+#
+# 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
+if {"::tcltest" in [namespace children]} {
+ namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testinterpresolver [llength [info commands testinterpresolver]]
+
+test resolver-1.1 {cmdNameObj sharing vs. cmd resolver: namespace import} -setup {
+ testinterpresolver up
+ namespace eval ::ns1 {
+ proc z {} { return Z }
+ namespace export z
+ }
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ # 1) Have the proc body compiled: During compilation or, alternatively,
+ # the first evaluation of the compiled body, the InterpCmdResolver (see
+ # tclTest.c) maps the cmd token "z" to "::y"; this mapping is saved in the
+ # resulting CmdName Tcl_Obj with the print string "z". The CmdName Tcl_Obj
+ # is turned into a command literal shared for a given (here: the global)
+ # namespace.
+ set r0 [x]; # --> The result of [x] is "Y"
+ # 2) After having requested cmd resolution above, we can now use the
+ # globally shared CmdName Tcl_Obj "z", now bound to cmd ::y. This is
+ # certainly questionable, but defensible
+ set r1 [z]; # --> The result of [z] is "Y"
+ # 3) We import from the namespace ns1 another z. [namespace import] takes
+ # care "shadowed" cmd references, however, till now cmd literals have not
+ # been touched. This is, however, necessary since the BC compiler (used in
+ # the [namespace eval]) seems to be eager to reuse CmdName Tcl_Objs as cmd
+ # literals for a given NS scope. We expect, that r2 is "Z", the result of
+ # the namespace imported cmd.
+ namespace eval :: {
+ namespace import ::ns1::z
+ set r2 [z]
+ }
+ list $r0 $r1 $::r2
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ namespace delete ::ns1
+} -result {Y Y Z}
+test resolver-1.2 {cmdNameObj sharing vs. cmd resolver: proc creation} -setup {
+ testinterpresolver up
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ set r0 [x]
+ set r1 [z]
+ proc ::foo {} {
+ proc ::z {} { return Z }
+ return [z]
+ }
+ list $r0 $r1 [::foo]
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ rename ::foo ""
+ rename ::z ""
+} -result {Y Y Z}
+test resolver-1.3 {cmdNameObj sharing vs. cmd resolver: rename} -setup {
+ testinterpresolver up
+ proc ::Z {} { return Z }
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ set r0 [x]
+ set r1 [z]
+ namespace eval :: {
+ rename ::Z ::z
+ set r2 [z]
+ }
+ list $r0 $r1 $r2
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ rename ::z ""
+} -result {Y Y Z}
+test resolver-1.4 {cmdNameObj sharing vs. cmd resolver: interp expose} -setup {
+ testinterpresolver up
+ proc ::Z {} { return Z }
+ interp hide {} Z
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ set r0 [x]
+ set r1 [z]
+ interp expose {} Z z
+ namespace eval :: {
+ set r2 [z]
+ }
+ list $r0 $r1 $r2
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ rename ::z ""
+} -result {Y Y Z}
+test resolver-1.5 {cmdNameObj sharing vs. cmd resolver: other than global NS} -setup {
+ testinterpresolver up
+ namespace eval ::ns1 {
+ proc z {} { return Z }
+ namespace export z
+ }
+ proc ::y {} { return Y }
+ namespace eval ::ns2 {
+ proc x {} {
+ z
+ }
+ }
+} -constraints testinterpresolver -body {
+ set r0 [namespace eval ::ns2 {x}]
+ set r1 [namespace eval ::ns2 {z}]
+ namespace eval ::ns2 {
+ namespace import ::ns1::z
+ set r2 [z]
+ }
+ list $r0 $r1 $r2
+} -cleanup {
+ testinterpresolver down
+ namespace delete ::ns2
+ namespace delete ::ns1
+} -result {Y Y Z}
+test resolver-1.6 {cmdNameObj sharing vs. cmd resolver: interp alias} -setup {
+ testinterpresolver up
+ proc ::Z {} { return Z }
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ set r0 [x]
+ set r1 [z]
+ namespace eval :: {
+ interp alias {} ::z {} ::Z
+ set r2 [z]
+ }
+ list $r0 $r1 $r2
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ rename ::Z ""
+} -result {Y Y Z}
+
+test resolver-2.1 {compiled var resolver: Bug #3383616} -setup {
+ testinterpresolver up
+ # The compiled var resolver fetches just variables starting with a capital
+ # "T" and stores some test information in the resolver-specific resolver
+ # var info.
+ proc ::x {} {
+ set T1 100
+ return $T1
+ }
+} -constraints testinterpresolver -body {
+ # Call "x" the first time, causing a byte code compilation of the body.
+ # During the compilation the compiled var resolver, the resolve-specific
+ # var info is allocated, during the execution of the body, the variable is
+ # fetched and cached.
+ x;
+ # During later calls, the cached variable is reused.
+ x
+ # When the proc is freed, the resolver-specific resolver var info is
+ # freed. This did not happen before fix #3383616.
+ rename ::x ""
+} -cleanup {
+ testinterpresolver down
+} -result {}
+
+cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/result.test b/tests/result.test
index f080654..9e8a66b 100644
--- a/tests/result.test
+++ b/tests/result.test
@@ -10,10 +10,11 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest 2
- namespace import -force ::tcltest::*
-}
+package require tcltest 2
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
# Some tests require the testsaveresult command
diff --git a/tests/safe.test b/tests/safe.test
index 0f82a6a..859f352 100644
--- a/tests/safe.test
+++ b/tests/safe.test
@@ -28,8 +28,6 @@ set ::auto_path [info library]
# thus un-autoindexed) APIs in this test result arguments:
catch {safe::interpConfigure}
-proc equiv {x} {return $x}
-
# testing that nested and statics do what is advertised (we use a static
# package - Tcltest - but it might be absent if we're in standard tclsh)
@@ -94,7 +92,7 @@ test safe-3.2 {calling safe::interpCreate on trusted interp} -setup {
lsort [a aliases]
} -cleanup {
safe::interpDelete a
-} -result {::tcl::info::nameofexecutable clock encoding exit file glob load source}
+} -result {::tcl::file::atime ::tcl::file::attributes ::tcl::file::copy ::tcl::file::delete ::tcl::file::dirname ::tcl::file::executable ::tcl::file::exists ::tcl::file::extension ::tcl::file::isdirectory ::tcl::file::isfile ::tcl::file::link ::tcl::file::lstat ::tcl::file::mkdir ::tcl::file::mtime ::tcl::file::nativename ::tcl::file::normalize ::tcl::file::owned ::tcl::file::readable ::tcl::file::readlink ::tcl::file::rename ::tcl::file::rootname ::tcl::file::size ::tcl::file::stat ::tcl::file::tail ::tcl::file::tempfile ::tcl::file::type ::tcl::file::volumes ::tcl::file::writable ::tcl::info::nameofexecutable clock encoding exit glob load source}
test safe-3.3 {calling safe::interpCreate on trusted interp} -setup {
catch {safe::interpDelete a}
} -body {
@@ -205,7 +203,12 @@ test safe-7.2 {tests specific path and interpFind/AddToAccessPath} -body {
[catch {interp eval $i {package require http 1}} msg] $msg \
[safe::interpConfigure $i]\
[safe::interpDelete $i]
-} -match glob -result "{\$p(:0:)} {\$p(:[expr 1+[llength [tcl::tm::list]]]:)} 1 {can't find package http 1} {-accessPath {[list $tcl_library */dummy/unixlike/test/path]} -statics 0 -nested 1 -deleteHook {}} {}"
+} -match glob -result "{\$p(:0:)} {\$p(:*:)} 1 {can't find package http 1} {-accessPath {[list $tcl_library */dummy/unixlike/test/path]} -statics 0 -nested 1 -deleteHook {}} {}"
+test safe-7.3 {check that safe subinterpreters work} {
+ set i [safe::interpCreate]
+ set j [safe::interpCreate [list $i x]]
+ list [interp eval $j {join {o k} ""}] [safe::interpDelete $i] [interp exists $j]
+} {ok {} 0}
# test source control on file name
test safe-8.1 {safe source control on file} -setup {
@@ -331,6 +334,20 @@ test safe-8.9 {safe source and return} -setup {
catch {safe::interpDelete $i}
removeFile $returnScript
} -result ok
+test safe-8.10 {safe source and return} -setup {
+ set returnScript [makeFile {return -level 2 "ok"} return.tcl]
+ catch {safe::interpDelete $i}
+} -body {
+ safe::interpCreate $i
+ set token [safe::interpAddToAccessPath $i [file dirname $returnScript]]
+ $i eval [list apply {filename {
+ source $filename
+ error boom
+ }} $token/[file tail $returnScript]]
+} -cleanup {
+ catch {safe::interpDelete $i}
+ removeFile $returnScript
+} -result ok
test safe-9.1 {safe interps' deleteHook} -setup {
set i "a"
@@ -408,6 +425,19 @@ test safe-10.1 {testing statics loading} -constraints TcltestPackage -setup {
} -returnCodes error -cleanup {
safe::interpDelete $i
} -result {can't use package in a safe interpreter: no Safepkg1_SafeInit procedure}
+test safe-10.1.1 {testing statics loading} -constraints TcltestPackage -setup {
+ set i [safe::interpCreate]
+} -body {
+ catch {interp eval $i {load {} Safepkg1}} m o
+ dict get $o -errorinfo
+} -returnCodes ok -cleanup {
+ unset -nocomplain m o
+ safe::interpDelete $i
+} -result {can't use package in a safe interpreter: no Safepkg1_SafeInit procedure
+ invoked from within
+"load {} Safepkg1"
+ invoked from within
+"interp eval $i {load {} Safepkg1}"}
test safe-10.2 {testing statics loading / -nostatics} -constraints TcltestPackage -body {
set i [safe::interpCreate -nostatics]
interp eval $i {load {} Safepkg1}
@@ -427,6 +457,18 @@ test safe-10.4 {testing nested statics loading / -nestedloadok} -constraints Tcl
} -returnCodes error -cleanup {
safe::interpDelete $i
} -result {can't use package in a safe interpreter: no Safepkg1_SafeInit procedure}
+test safe-10.4.1 {testing nested statics loading / -nestedloadok} -constraints TcltestPackage -body {
+ set i [safe::interpCreate -nestedloadok]
+ catch {interp eval $i {interp create x; load {} Safepkg1 x}} m o
+ dict get $o -errorinfo
+} -returnCodes ok -cleanup {
+ unset -nocomplain m o
+ safe::interpDelete $i
+} -result {can't use package in a safe interpreter: no Safepkg1_SafeInit procedure
+ invoked from within
+"load {} Safepkg1 x"
+ invoked from within
+"interp eval $i {interp create x; load {} Safepkg1 x}"}
test safe-11.1 {testing safe encoding} -setup {
set i [safe::interpCreate]
@@ -484,6 +526,23 @@ test safe-11.7 {testing safe encoding} -setup {
} -returnCodes error -cleanup {
safe::interpDelete $i
} -result {wrong # args: should be "encoding convertfrom ?encoding? data"}
+test safe-11.7.1 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ catch {interp eval $i encoding convertfrom} m o
+ dict get $o -errorinfo
+} -returnCodes ok -cleanup {
+ unset -nocomplain m o
+ safe::interpDelete $i
+} -result {wrong # args: should be "encoding convertfrom ?encoding? data"
+ while executing
+"encoding convertfrom"
+ invoked from within
+"::interp invokehidden interp1 encoding convertfrom"
+ invoked from within
+"encoding convertfrom"
+ invoked from within
+"interp eval $i encoding convertfrom"}
test safe-11.8 {testing safe encoding} -setup {
set i [safe::interpCreate]
} -body {
@@ -491,6 +550,23 @@ test safe-11.8 {testing safe encoding} -setup {
} -returnCodes error -cleanup {
safe::interpDelete $i
} -result {wrong # args: should be "encoding convertto ?encoding? data"}
+test safe-11.8.1 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ catch {interp eval $i encoding convertto} m o
+ dict get $o -errorinfo
+} -returnCodes ok -cleanup {
+ unset -nocomplain m o
+ safe::interpDelete $i
+} -result {wrong # args: should be "encoding convertto ?encoding? data"
+ while executing
+"encoding convertto"
+ invoked from within
+"::interp invokehidden interp1 encoding convertto"
+ invoked from within
+"encoding convertto"
+ invoked from within
+"interp eval $i encoding convertto"}
test safe-12.1 {glob is restricted [Bug 2906841]} -setup {
set i [safe::interpCreate]
@@ -538,9 +614,235 @@ test safe-12.7 {glob is restricted} -setup {
set i [safe::interpCreate]
} -body {
$i eval glob *
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {permission denied}
+
+proc buildEnvironment {filename} {
+ upvar 1 testdir testdir testdir2 testdir2 testfile testfile
+ set testdir [makeDirectory deletethisdir]
+ set testdir2 [makeDirectory deletemetoo $testdir]
+ set testfile [makeFile {} $filename $testdir2]
+}
+#### New tests for Safe base glob, with patches @ Bug 2964715
+test safe-13.1 {glob is restricted [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob *
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {permission denied}
+test safe-13.2 {mimic the valid glob call by ::tcl::tm::UnknownHandler [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir2
+ set result [$i eval glob -nocomplain -directory $testdir2 *.tm]
+ if {$result eq [list $testfile]} {
+ return "glob match"
+ } else {
+ return "no match: $result"
+ }
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {glob match}
+test safe-13.3 {cf 13.2 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ $i eval glob -directory $testdir2 *.tm
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {permission denied}
+test safe-13.4 {another valid glob call [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir
+ ::safe::interpAddToAccessPath $i $testdir2
+ set result [$i eval \
+ glob -nocomplain -directory $testdir [file join deletemetoo *.tm]]
+ if {$result eq [list $testfile]} {
+ return "glob match"
+ } else {
+ return "no match: $result"
+ }
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {glob match}
+test safe-13.5 {as 13.4 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir2
+ $i eval \
+ glob -directory $testdir [file join deletemetoo *.tm]
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {permission denied}
+test safe-13.6 {as 13.4 but test silent failure when result is outside access_path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir
+ $i eval \
+ glob -nocomplain -directory $testdir [file join deletemetoo *.tm]
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {}
+test safe-13.7 {mimic the glob call by tclPkgUnknown which gives a deliberate error in a safe interpreter [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment pkgIndex.tcl
+} -body {
+ set safeTD [::safe::interpAddToAccessPath $i $testdir]
+ ::safe::interpAddToAccessPath $i $testdir2
+ string map [list $safeTD EXPECTED] [$i eval [list \
+ glob -directory $safeTD -join * pkgIndex.tcl]]
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {{EXPECTED/deletemetoo/pkgIndex.tcl}}
+# Note the extra {} around the result above; that's *expected* because of the
+# format of virtual path roots.
+test safe-13.8 {mimic the glob call by tclPkgUnknown without the deliberate error that is specific to pkgIndex.tcl [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment notIndex.tcl
+} -body {
+ set safeTD [::safe::interpAddToAccessPath $i $testdir]
+ ::safe::interpAddToAccessPath $i $testdir2
+ $i eval [list glob -directory $safeTD -join -nocomplain * notIndex.tcl]
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {}
+test safe-13.9 {as 13.8 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment notIndex.tcl
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir2
+ set result [$i eval \
+ glob -directory $testdir -join -nocomplain * notIndex.tcl]
+ if {$result eq [list $testfile]} {
+ return {glob match}
+ } else {
+ return "no match: $result"
+ }
} -cleanup {
safe::interpDelete $i
-} -match glob -result *
+ removeDirectory $testdir
+} -result {no match: }
+test safe-13.10 {as 13.8 but test silent failure when result is outside access_path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment notIndex.tcl
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir
+ $i eval glob -directory $testdir -join -nocomplain * notIndex.tcl
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {}
+rename buildEnvironment {}
+
+#### Test for the module path
+test safe-14.1 {Check that module path is the same as in the master interpreter [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ set tm {}
+ foreach token [$i eval ::tcl::tm::path list] {
+ lappend tm [dict get [set ::safe::S${i}(access_path,map)] $token]
+ }
+ return $tm
+} -cleanup {
+ safe::interpDelete $i
+} -result [::tcl::tm::path list]
+
+test safe-15.1 {safe file ensemble does not surprise code} -setup {
+ set i [interp create -safe]
+} -body {
+ set result [expr {"file" in [interp hidden $i]}]
+ lappend result [interp eval $i {tcl::file::split a/b/c}]
+ lappend result [catch {interp eval $i {tcl::file::isdirectory .}}]
+ lappend result [interp invokehidden $i file split a/b/c]
+ lappend result [catch {interp eval $i {file split a/b/c}} msg] $msg
+ lappend result [catch {interp invokehidden $i file isdirectory .}]
+ interp expose $i file
+ lappend result [catch {interp eval $i {file split a/b/c}} msg] $msg
+ lappend result [catch {interp eval $i {file isdirectory .}} msg] $msg
+} -cleanup {
+ unset -nocomplain msg
+ interp delete $i
+} -result {1 {a b c} 1 {a b c} 1 {invalid command name "file"} 1 0 {a b c} 1 {not allowed to invoke subcommand isdirectory of file}}
+test safe-15.1.1 {safe file ensemble does not surprise code} -setup {
+ set i [interp create -safe]
+} -body {
+ set result [expr {"file" in [interp hidden $i]}]
+ lappend result [interp eval $i {tcl::file::split a/b/c}]
+ lappend result [catch {interp eval $i {tcl::file::isdirectory .}}]
+ lappend result [interp invokehidden $i file split a/b/c]
+ lappend result [catch {interp eval $i {file split a/b/c}} msg] $msg
+ lappend result [catch {interp invokehidden $i file isdirectory .}]
+ interp expose $i file
+ lappend result [catch {interp eval $i {file split a/b/c}} msg] $msg
+ lappend result [catch {interp eval $i {file isdirectory .}} msg o] [dict get $o -errorinfo]
+} -cleanup {
+ unset -nocomplain msg o
+ interp delete $i
+} -result {1 {a b c} 1 {a b c} 1 {invalid command name "file"} 1 0 {a b c} 1 {not allowed to invoke subcommand isdirectory of file
+ while executing
+"file isdirectory ."
+ invoked from within
+"interp eval $i {file isdirectory .}"}}
+
+### ~ should have no special meaning in paths in safe interpreters
+test safe-16.1 {Bug 3529949: defang ~ in paths} -setup {
+ set savedHOME $env(HOME)
+ set env(HOME) /foo/bar
+ set i [safe::interpCreate]
+} -body {
+ $i eval {
+ set d [format %c 126]
+ list [file join [file dirname $d] [file tail $d]]
+ }
+} -cleanup {
+ safe::interpDelete $i
+ set env(HOME) $savedHOME
+} -result {./~}
+test safe-16.2 {Bug 3529949: defang ~user in paths} -setup {
+ set i [safe::interpCreate]
+ set user $tcl_platform(user)
+} -body {
+ string map [list $user USER] [$i eval \
+ "file join \[file dirname ~$user\] \[file tail ~$user\]"]
+} -cleanup {
+ safe::interpDelete $i
+} -result {./~USER}
+test safe-16.3 {Bug 3529949: defang ~ in globs} -setup {
+ set syntheticHOME [makeDirectory foo]
+ makeFile {} bar $syntheticHOME
+ set savedHOME $env(HOME)
+ set env(HOME) $syntheticHOME
+ set i [safe::interpCreate]
+} -body {
+ ::safe::interpAddToAccessPath $i $syntheticHOME
+ $i eval {glob -nocomplain ~/*}
+} -cleanup {
+ safe::interpDelete $i
+ set env(HOME) $savedHOME
+ removeDirectory $syntheticHOME
+} -result {}
+test safe-16.4 {Bug 3529949: defang ~user in globs} -setup {
+ set i [safe::interpCreate]
+} -body {
+ ::safe::interpAddToAccessPath $i $~$tcl_platform(user)
+ $i eval [list glob -nocomplain ~$tcl_platform(user)/*]
+} -cleanup {
+ safe::interpDelete $i
+} -result {}
set ::auto_path $saveAutoPath
# cleanup
diff --git a/tests/scan.test b/tests/scan.test
index 84f22b4..b57b641 100644
--- a/tests/scan.test
+++ b/tests/scan.test
@@ -1,8 +1,8 @@
# Commands covered: scan
#
-# This file contains a collection of tests for one or more of the Tcl
-# built-in commands. Sourcing this file into Tcl runs the tests and
-# generates output for errors. No output means no errors were found.
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
#
# Copyright (c) 1991-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
@@ -11,14 +11,83 @@
# 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} {
+if {"::tcltest" ni [namespace children]} {
package require tcltest 2
namespace import -force ::tcltest::*
}
+# procedure that returns the range of integers
+
+proc int_range {} {
+ for { set MIN_INT 1 } { int($MIN_INT) > 0 } {} {
+ set MIN_INT [expr { $MIN_INT << 1 }]
+ }
+ set MIN_INT [expr {int($MIN_INT)}]
+ set MAX_INT [expr { ~ $MIN_INT }]
+ return [list $MIN_INT $MAX_INT]
+}
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+
+testConstraint ieeeFloatingPoint [testIEEE]
testConstraint wideIs64bit \
[expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}]
-
+
test scan-1.1 {BuildCharSet, CharInSet} {
list [scan foo {%[^o]} x] $x
} {1 f}
@@ -43,10 +112,11 @@ test scan-1.7 {BuildCharSet, CharInSet} {
test scan-1.8 {BuildCharSet, CharInSet} {
list [scan def-abc {%[^c-a]} x] $x
} {1 def-}
-test scan-1.9 {BuildCharSet, CharInSet no match} {
- catch {unset x}
+test scan-1.9 {BuildCharSet, CharInSet no match} -setup {
+ unset -nocomplain x
+} -body {
list [scan {= f} {= %[TF]} x] [info exists x]
-} {0 0}
+} -result {0 0}
test scan-2.1 {ReleaseCharSet} {
list [scan abcde {%[abc]} x] $x
@@ -55,53 +125,53 @@ test scan-2.2 {ReleaseCharSet} {
list [scan abcde {%[a-c]} x] $x
} {1 abc}
-test scan-3.1 {ValidateFormat} {
- list [catch {scan {} {%d%1$d} x} msg] $msg
-} {1 {cannot mix "%" and "%n$" conversion specifiers}}
-test scan-3.2 {ValidateFormat} {
- list [catch {scan {} {%d%1$d} x} msg] $msg
-} {1 {cannot mix "%" and "%n$" conversion specifiers}}
-test scan-3.3 {ValidateFormat} {
- list [catch {scan {} {%2$d%d} x} msg] $msg
-} {1 {"%n$" argument index out of range}}
+test scan-3.1 {ValidateFormat} -returnCodes error -body {
+ scan {} {%d%1$d} x
+} -result {cannot mix "%" and "%n$" conversion specifiers}
+test scan-3.2 {ValidateFormat} -returnCodes error -body {
+ scan {} {%d%1$d} x
+} -result {cannot mix "%" and "%n$" conversion specifiers}
+test scan-3.3 {ValidateFormat} -returnCodes error -body {
+ scan {} {%2$d%d} x
+} -result {"%n$" argument index out of range}
test scan-3.4 {ValidateFormat} {
# degenerate case, before changed from 8.2 to 8.3
list [catch {scan {} %d} msg] $msg
} {0 {}}
-test scan-3.5 {ValidateFormat} {
- list [catch {scan {} {%10c} a} msg] $msg
-} {1 {field width may not be specified in %c conversion}}
-test scan-3.6 {ValidateFormat} {
- list [catch {scan {} {%*1$d} a} msg] $msg
-} {1 {bad scan conversion character "$"}}
-test scan-3.7 {ValidateFormat} {
- list [catch {scan {} {%1$d%1$d} a} msg] $msg
-} {1 {variable is assigned by multiple "%n$" conversion specifiers}}
-test scan-3.8 {ValidateFormat} {
- list [catch {scan {} a x} msg] $msg
-} {1 {variable is not assigned by any conversion specifiers}}
-test scan-3.9 {ValidateFormat} {
- list [catch {scan {} {%2$s} x y} msg] $msg
-} {1 {variable is not assigned by any conversion specifiers}}
-test scan-3.10 {ValidateFormat} {
- list [catch {scan {} {%[a} x} msg] $msg
-} {1 {unmatched [ in format string}}
-test scan-3.11 {ValidateFormat} {
- list [catch {scan {} {%[^a} x} msg] $msg
-} {1 {unmatched [ in format string}}
-test scan-3.12 {ValidateFormat} {
- list [catch {scan {} {%[]a} x} msg] $msg
-} {1 {unmatched [ in format string}}
-test scan-3.13 {ValidateFormat} {
- list [catch {scan {} {%[^]a} x} msg] $msg
-} {1 {unmatched [ in format string}}
+test scan-3.5 {ValidateFormat} -returnCodes error -body {
+ scan {} {%10c} a
+} -result {field width may not be specified in %c conversion}
+test scan-3.6 {ValidateFormat} -returnCodes error -body {
+ scan {} {%*1$d} a
+} -result {bad scan conversion character "$"}
+test scan-3.7 {ValidateFormat} -returnCodes error -body {
+ scan {} {%1$d%1$d} a
+} -result {variable is assigned by multiple "%n$" conversion specifiers}
+test scan-3.8 {ValidateFormat} -returnCodes error -body {
+ scan {} a x
+} -result {variable is not assigned by any conversion specifiers}
+test scan-3.9 {ValidateFormat} -returnCodes error -body {
+ scan {} {%2$s} x y
+} -result {variable is not assigned by any conversion specifiers}
+test scan-3.10 {ValidateFormat} -returnCodes error -body {
+ scan {} {%[a} x
+} -result {unmatched [ in format string}
+test scan-3.11 {ValidateFormat} -returnCodes error -body {
+ scan {} {%[^a} x
+} -result {unmatched [ in format string}
+test scan-3.12 {ValidateFormat} -returnCodes error -body {
+ scan {} {%[]a} x
+} -result {unmatched [ in format string}
+test scan-3.13 {ValidateFormat} -returnCodes error -body {
+ scan {} {%[^]a} x
+} -result {unmatched [ in format string}
-test scan-4.1 {Tcl_ScanObjCmd, argument checks} {
- list [catch {scan} msg] $msg
-} {1 {wrong # args: should be "scan string format ?varName ...?"}}
-test scan-4.2 {Tcl_ScanObjCmd, argument checks} {
- list [catch {scan string} msg] $msg
-} {1 {wrong # args: should be "scan string format ?varName ...?"}}
+test scan-4.1 {Tcl_ScanObjCmd, argument checks} -returnCodes error -body {
+ scan
+} -result {wrong # args: should be "scan string format ?varName ...?"}
+test scan-4.2 {Tcl_ScanObjCmd, argument checks} -returnCodes error -body {
+ scan string
+} -result {wrong # args: should be "scan string format ?varName ...?"}
test scan-4.3 {Tcl_ScanObjCmd, argument checks} {
# degenerate case, before changed from 8.2 to 8.3
list [catch {scan string format} msg] $msg
@@ -191,99 +261,126 @@ test scan-4.29 {Tcl_ScanObjCmd, character scanning} {
list [scan {abcdef} {%*c%n} x] $x
} {1 1}
-test scan-4.30 {Tcl_ScanObjCmd, base-10 integer scanning} {
+test scan-4.30 {Tcl_ScanObjCmd, base-10 integer scanning} -setup {
set x {}
+} -body {
list [scan {1234567890a} {%3d} x] $x
-} {1 123}
-test scan-4.31 {Tcl_ScanObjCmd, base-10 integer scanning} {
+} -result {1 123}
+test scan-4.31 {Tcl_ScanObjCmd, base-10 integer scanning} -setup {
set x {}
+} -body {
list [scan {1234567890a} {%d} x] $x
-} {1 1234567890}
-test scan-4.32 {Tcl_ScanObjCmd, base-10 integer scanning} {
+} -result {1 1234567890}
+test scan-4.32 {Tcl_ScanObjCmd, base-10 integer scanning} -setup {
set x {}
+} -body {
list [scan {01234567890a} {%d} x] $x
-} {1 1234567890}
-test scan-4.33 {Tcl_ScanObjCmd, base-10 integer scanning} {
+} -result {1 1234567890}
+test scan-4.33 {Tcl_ScanObjCmd, base-10 integer scanning} -setup {
set x {}
+} -body {
list [scan {+01234} {%d} x] $x
-} {1 1234}
-test scan-4.34 {Tcl_ScanObjCmd, base-10 integer scanning} {
+} -result {1 1234}
+test scan-4.34 {Tcl_ScanObjCmd, base-10 integer scanning} -setup {
set x {}
+} -body {
list [scan {-01234} {%d} x] $x
-} {1 -1234}
-test scan-4.35 {Tcl_ScanObjCmd, base-10 integer scanning} {
+} -result {1 -1234}
+test scan-4.35 {Tcl_ScanObjCmd, base-10 integer scanning} -setup {
set x {}
+} -body {
list [scan {a01234} {%d} x] $x
-} {0 {}}
-test scan-4.36 {Tcl_ScanObjCmd, base-10 integer scanning} {
+} -result {0 {}}
+test scan-4.36 {Tcl_ScanObjCmd, base-10 integer scanning} -setup {
set x {}
+} -body {
list [scan {0x10} {%d} x] $x
-} {1 0}
-test scan-4.37 {Tcl_ScanObjCmd, base-8 integer scanning} {
+} -result {1 0}
+test scan-4.37 {Tcl_ScanObjCmd, base-8 integer scanning} -setup {
set x {}
+} -body {
list [scan {012345678} {%o} x] $x
-} {1 342391}
-test scan-4.38 {Tcl_ScanObjCmd, base-8 integer scanning} {
+} -result {1 342391}
+test scan-4.38 {Tcl_ScanObjCmd, base-8 integer scanning} -setup {
set x {}
+} -body {
list [scan {+1238 -1239 123a} {%o%*s%o%*s%o} x y z] $x $y $z
-} {3 83 -83 83}
-test scan-4.39 {Tcl_ScanObjCmd, base-16 integer scanning} {
+} -result {3 83 -83 83}
+test scan-4.39 {Tcl_ScanObjCmd, base-16 integer scanning} -setup {
set x {}
+} -body {
list [scan {+1238 -123a 0123} {%x%x%x} x y z] $x $y $z
-} {3 4664 -4666 291}
-test scan-4.40 {Tcl_ScanObjCmd, base-16 integer scanning} {
+} -result {3 4664 -4666 291}
+test scan-4.40 {Tcl_ScanObjCmd, base-16 integer scanning} -setup {
+ set x {}
+} -body {
# The behavior changed in 8.4a4/8.3.4cvs (6 Feb) to correctly
# return '1' for 0x1 scanned via %x, to comply with 8.0 and C scanf.
# Bug #495213
- set x {}
list [scan {aBcDeF AbCdEf 0x1} {%x%x%x} x y z] $x $y $z
-} {3 11259375 11259375 1}
-test scan-4.40.1 {Tcl_ScanObjCmd, base-16 integer scanning} {
+} -result {3 11259375 11259375 1}
+test scan-4.40.1 {Tcl_ScanObjCmd, base-16 integer scanning} -setup {
set x {}
+} -body {
list [scan {0xF 0x00A0B 0X0XF} {%x %x %x} x y z] $x $y $z
-} {3 15 2571 0}
-test scan-4.40.2 {Tcl_ScanObjCmd, base-16 integer scanning} {
- catch {unset x}
+} -result {3 15 2571 0}
+test scan-4.40.2 {Tcl_ScanObjCmd, base-16 integer scanning} -setup {
+ unset -nocomplain x
+} -body {
list [scan {xF} {%x} x] [info exists x]
-} {0 0}
-test scan-4.40.3 {Tcl_ScanObjCmd, base-2 integer scanning} {
+} -result {0 0}
+test scan-4.40.3 {Tcl_ScanObjCmd, base-2 integer scanning} -setup {
set x {}
+} -body {
list [scan {1001 0b101 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000} {%b %b %llb} x y z] $x $y $z
-} {3 9 5 340282366920938463463374607431768211456}
-test scan-4.41 {Tcl_ScanObjCmd, base-unknown integer scanning} {
+} -result {3 9 5 340282366920938463463374607431768211456}
+test scan-4.41 {Tcl_ScanObjCmd, base-unknown integer scanning} -setup {
set x {}
+} -body {
list [scan {10 010 0x10 0b10} {%i%i%i%i} x y z t] $x $y $z $t
-} {4 10 8 16 0}
-test scan-4.42 {Tcl_ScanObjCmd, base-unknown integer scanning} {
+} -result {4 10 8 16 0}
+test scan-4.42 {Tcl_ScanObjCmd, base-unknown integer scanning} -setup {
set x {}
+} -body {
list [scan {10 010 0X10} {%i%i%i} x y z] $x $y $z
-} {3 10 8 16}
-test scan-4.43 {Tcl_ScanObjCmd, integer scanning, odd cases} {
+} -result {3 10 8 16}
+test scan-4.43 {Tcl_ScanObjCmd, integer scanning, odd cases} -setup {
set x {}
+} -body {
list [scan {+ } {%i} x] $x
-} {0 {}}
-test scan-4.44 {Tcl_ScanObjCmd, integer scanning, odd cases} {
+} -result {0 {}}
+test scan-4.44 {Tcl_ScanObjCmd, integer scanning, odd cases} -setup {
set x {}
+} -body {
list [scan {+} {%i} x] $x
-} {-1 {}}
-test scan-4.45 {Tcl_ScanObjCmd, integer scanning, odd cases} {
+} -result {-1 {}}
+test scan-4.45 {Tcl_ScanObjCmd, integer scanning, odd cases} -setup {
set x {}
+} -body {
list [scan {0x} {%i%s} x y] $x $y
-} {2 0 x}
-test scan-4.46 {Tcl_ScanObjCmd, integer scanning, odd cases} {
+} -result {2 0 x}
+test scan-4.46 {Tcl_ScanObjCmd, integer scanning, odd cases} -setup {
set x {}
+} -body {
list [scan {0X} {%i%s} x y] $x $y
-} {2 0 X}
-test scan-4.47 {Tcl_ScanObjCmd, integer scanning, suppressed} {
+} -result {2 0 X}
+test scan-4.47 {Tcl_ScanObjCmd, integer scanning, suppressed} -setup {
set x {}
+} -body {
list [scan {123def} {%*i%s} x] $x
-} {1 def}
+} -result {1 def}
test scan-4.48 {Tcl_ScanObjCmd, float scanning} {
list [scan {1 2 3} {%e %f %g} x y z] $x $y $z
} {3 1.0 2.0 3.0}
test scan-4.49 {Tcl_ScanObjCmd, float scanning} {
list [scan {.1 0.2 3.} {%e %f %g} x y z] $x $y $z
} {3 0.1 0.2 3.0}
+test scan-4.49-uc-1 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {0.5*0.75} {%E%c%G} x y z] $x $y $z
+} {3 0.5 42 0.75}
+test scan-4.49-uc-2 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {5e-1*75E-2} {%E%c%G} x y z] $x $y $z
+} {3 0.5 42 0.75}
test scan-4.50 {Tcl_ScanObjCmd, float scanning} {
list [scan {1234567890a} %f x] $x
} {1 1234567890.0}
@@ -299,133 +396,137 @@ test scan-4.53 {Tcl_ScanObjCmd, float scanning} {
test scan-4.54 {Tcl_ScanObjCmd, float scanning} {
list [scan {1.0e-1} %f x] $x
} {1 0.1}
-test scan-4.55 {Tcl_ScanObjCmd, odd cases} {
+test scan-4.55 {Tcl_ScanObjCmd, odd cases} -setup {
set x {}
+} -body {
list [scan {+} %f x] $x
-} {-1 {}}
-test scan-4.56 {Tcl_ScanObjCmd, odd cases} {
+} -result {-1 {}}
+test scan-4.56 {Tcl_ScanObjCmd, odd cases} -setup {
set x {}
+} -body {
list [scan {1.0e} %f%s x y] $x $y
-} {2 1.0 e}
-test scan-4.57 {Tcl_ScanObjCmd, odd cases} {
+} -result {2 1.0 e}
+test scan-4.57 {Tcl_ScanObjCmd, odd cases} -setup {
set x {}
+} -body {
list [scan {1.0e+} %f%s x y] $x $y
-} {2 1.0 e+}
-test scan-4.58 {Tcl_ScanObjCmd, odd cases} {
+} -result {2 1.0 e+}
+test scan-4.58 {Tcl_ScanObjCmd, odd cases} -setup {
set x {}
set y {}
+} -body {
list [scan {e1} %f%s x y] $x $y
-} {0 {} {}}
+} -result {0 {} {}}
test scan-4.59 {Tcl_ScanObjCmd, float scanning} {
list [scan {1.0e-1x} %*f%n x] $x
} {1 6}
-test scan-4.60 {Tcl_ScanObjCmd, set errors} {
+test scan-4.60 {Tcl_ScanObjCmd, set errors} -setup {
set x {}
set y {}
- catch {unset z}; array set z {}
- set result [list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] \
- $msg $x $y]
- unset z
- set result
-} {1 {can't set "z": variable is array} abc ghi}
-test scan-4.61 {Tcl_ScanObjCmd, set errors} {
+ unset -nocomplain z
+} -body {
+ array set z {}
+ list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] $msg $x $y
+} -cleanup {
+ unset -nocomplain z
+} -result {1 {can't set "z": variable is array} abc ghi}
+test scan-4.61 {Tcl_ScanObjCmd, set errors} -setup {
set x {}
- catch {unset y}; array set y {}
- catch {unset z}; array set z {}
- set result [list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] \
- $msg $x]
- unset y
- unset z
- set result
-} {1 {can't set "z": variable is array} abc}
-
-# procedure that returns the range of integers
-
-proc int_range {} {
- for { set MIN_INT 1 } { int($MIN_INT) > 0 } {} {
- set MIN_INT [expr { $MIN_INT << 1 }]
- }
- set MIN_INT [expr {int($MIN_INT)}]
- set MAX_INT [expr { ~ $MIN_INT }]
- return [list $MIN_INT $MAX_INT]
-}
+ unset -nocomplain y
+ unset -nocomplain z
+} -body {
+ array set y {}
+ array set z {}
+ list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] $msg $x
+} -cleanup {
+ unset -nocomplain y
+ unset -nocomplain z
+} -result {1 {can't set "z": variable is array} abc}
test scan-4.62 {scanning of large and negative octal integers} {
- foreach { MIN_INT MAX_INT } [int_range] {}
+ lassign [int_range] MIN_INT MAX_INT
set scanstring [format {%o %o %o} -1 $MIN_INT $MAX_INT]
list [scan $scanstring {%o %o %o} a b c] \
[expr { $a == -1 }] [expr { $b == $MIN_INT }] [expr { $c == $MAX_INT }]
} {3 1 1 1}
test scan-4.63 {scanning of large and negative hex integers} {
- foreach { MIN_INT MAX_INT } [int_range] {}
+ lassign [int_range] MIN_INT MAX_INT
set scanstring [format {%x %x %x} -1 $MIN_INT $MAX_INT]
list [scan $scanstring {%x %x %x} a b c] \
[expr { $a == -1 }] [expr { $b == $MIN_INT }] [expr { $c == $MAX_INT }]
} {3 1 1 1}
+test scan-4.64 {scanning of hex with %X} {
+ scan "123 abc f78" %X%X%X
+} {291 2748 3960}
-# clean up from last two tests
-
-catch {
- rename int_range {}
-}
-
-test scan-5.1 {integer scanning} {
+test scan-5.1 {integer scanning} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "-20 1476 \n33 0" "%d %d %d %d" a b c d] $a $b $c $d
-} {4 -20 1476 33 0}
-test scan-5.2 {integer scanning} {
+} -result {4 -20 1476 33 0}
+test scan-5.2 {integer scanning} -setup {
set a {}; set b {}; set c {}
+} -body {
list [scan "-45 16 7890 +10" "%2d %*d %10d %d" a b c] $a $b $c
-} {3 -4 16 7890}
-test scan-5.3 {integer scanning} {
+} -result {3 -4 16 7890}
+test scan-5.3 {integer scanning} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "-45 16 +10 987" "%ld %d %ld %d" a b c d] $a $b $c $d
-} {4 -45 16 10 987}
-test scan-5.4 {integer scanning} {
+} -result {4 -45 16 10 987}
+test scan-5.4 {integer scanning} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "14 1ab 62 10" "%d %x %lo %x" a b c d] $a $b $c $d
-} {4 14 427 50 16}
-test scan-5.5 {integer scanning} {
+} -result {4 14 427 50 16}
+test scan-5.5 {integer scanning} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "12345670 1234567890ab cdefg" "%o %o %x %lx" a b c d] \
$a $b $c $d
-} {4 2739128 342391 561323 52719}
-test scan-5.6 {integer scanning} {
+} -result {4 2739128 342391 561323 52719}
+test scan-5.6 {integer scanning} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "ab123-24642" "%2x %3x %3o %2o" a b c d] $a $b $c $d
-} {4 171 291 -20 52}
-test scan-5.7 {integer scanning} {
+} -result {4 171 291 -20 52}
+test scan-5.7 {integer scanning} -setup {
set a {}; set b {}
+} -body {
list [scan "1234567 234 567 " "%*3x %x %*o %4o" a b] $a $b
-} {2 17767 375}
-test scan-5.8 {integer scanning} {
+} -result {2 17767 375}
+test scan-5.8 {integer scanning} -setup {
set a {}; set b {}
+} -body {
list [scan "a 1234" "%d %d" a b] $a $b
-} {0 {} {}}
-test scan-5.9 {integer scanning} {
- set a {}; set b {}; set c {}; set d {};
+} -result {0 {} {}}
+test scan-5.9 {integer scanning} -setup {
+ set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "12345678" "%2d %2d %2ld %2d" a b c d] $a $b $c $d
-} {4 12 34 56 78}
-test scan-5.10 {integer scanning} {
+} -result {4 12 34 56 78}
+test scan-5.10 {integer scanning} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "1 2 " "%hd %d %d %d" a b c d] $a $b $c $d
-} {2 1 2 {} {}}
+} -result {2 1 2 {} {}}
#
-# The behavior for scaning intergers larger than MAX_INT is
-# not defined by the ANSI spec. Some implementations wrap the
-# input (-16) some return MAX_INT.
+# The behavior for scaning intergers larger than MAX_INT is not defined by the
+# ANSI spec. Some implementations wrap the input (-16) some return MAX_INT.
#
-test scan-5.11 {integer scanning} {nonPortable} {
- set a {}; set b {};
+test scan-5.11 {integer scanning} -constraints {nonPortable} -setup {
+ set a {}; set b {}
+} -body {
list [scan "4294967280 4294967280" "%u %d" a b] $a \
[expr {$b == -16 || $b == 0x7fffffff}]
-} {2 4294967280 1}
-test scan-5.12 {integer scanning} {wideIs64bit} {
+} -result {2 4294967280 1}
+test scan-5.12 {integer scanning} -constraints {wideIs64bit} -setup {
set a {}; set b {}; set c {}
+} -body {
list [scan "7810179016327718216,6c63546f6c6c6548,661432506755433062510" \
%ld,%lx,%lo a b c] $a $b $c
-} {3 7810179016327718216 7810179016327718216 7810179016327718216}
+} -result {3 7810179016327718216 7810179016327718216 7810179016327718216}
test scan-5.13 {integer scanning and overflow} {
# This test used to fail on some 64-bit systems. [Bug 1011860]
scan {300000000 3000000000 30000000000} {%ld %ld %ld}
@@ -435,153 +536,184 @@ test scan-5.14 {integer scanning} {
scan 0xff %u
} 0
-test scan-6.1 {floating-point scanning} {
+test scan-6.1 {floating-point scanning} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "2.1 -3.0e8 .99962 a" "%f%g%e%f" a b c d] $a $b $c $d
-} {3 2.1 -300000000.0 0.99962 {}}
-test scan-6.2 {floating-point scanning} {
+} -result {3 2.1 -300000000.0 0.99962 {}}
+test scan-6.2 {floating-point scanning} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "-1.2345 +8.2 9" "%3e %3lf %f %f" a b c d] $a $b $c $d
-} {4 -1.0 234.0 5.0 8.2}
-test scan-6.3 {floating-point scanning} {
+} -result {4 -1.0 234.0 5.0 8.2}
+test scan-6.3 {floating-point scanning} -setup {
set a {}; set b {}; set c {}
+} -body {
list [scan "1e00004 332E-4 3e+4" "%Lf %*2e %f %f" a b c] $a $c
-} {3 10000.0 30000.0}
+} -result {3 10000.0 30000.0}
#
-# Some libc implementations consider 3.e- bad input. The ANSI
-# spec states that digits must follow the - sign.
+# Some libc implementations consider 3.e- bad input. The ANSI spec states
+# that digits must follow the - sign.
#
-test scan-6.4 {floating-point scanning} {
+test scan-6.4 {floating-point scanning} -setup {
set a {}; set b {}; set c {}
+} -body {
list [scan "1. 47.6 2.e2 3.e-" "%f %*f %f %f" a b c] $a $b $c
-} {3 1.0 200.0 3.0}
-test scan-6.5 {floating-point scanning} {
+} -result {3 1.0 200.0 3.0}
+test scan-6.5 {floating-point scanning} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "4.6 99999.7 876.43e-1 118" "%f %f %f %e" a b c d] $a $b $c $d
-} {4 4.6 99999.7 87.643 118.0}
-test scan-6.6 {floating-point scanning} {
+} -result {4 4.6 99999.7 87.643 118.0}
+test scan-6.6 {floating-point scanning} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "1.2345 697.0e-3 124 .00005" "%f %e %f %e" a b c d] $a $b $c $d
-} {4 1.2345 0.697 124.0 5e-5}
-test scan-6.7 {floating-point scanning} {
+} -result {4 1.2345 0.697 124.0 5e-5}
+test scan-6.7 {floating-point scanning} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "4.6abc" "%f %f %f %f" a b c d] $a $b $c $d
-} {1 4.6 {} {} {}}
-test scan-6.8 {floating-point scanning} {
+} -result {1 4.6 {} {} {}}
+test scan-6.8 {floating-point scanning} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "4.6 5.2" "%f %f %f %f" a b c d] $a $b $c $d
-} {2 4.6 5.2 {} {}}
+} -result {2 4.6 5.2 {} {}}
-test scan-7.1 {string and character scanning} {
+test scan-7.1 {string and character scanning} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "abc defghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d
-} {4 abc def ghijk dum}
-test scan-7.2 {string and character scanning} {
+} -result {4 abc def ghijk dum}
+test scan-7.2 {string and character scanning} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "a bcdef" "%c%c%1s %s" a b c d] $a $b $c $d
-} {4 97 32 b cdef}
-test scan-7.3 {string and character scanning} {
+} -result {4 97 32 b cdef}
+test scan-7.3 {string and character scanning} -setup {
set a {}; set b {}; set c {}
+} -body {
list [scan "123456 test " "%*c%*s %s %s %s" a b c] $a $b $c
-} {1 test {} {}}
-test scan-7.4 {string and character scanning} {
- set a {}; set b {}; set c {}; set d
+} -result {1 test {} {}}
+test scan-7.4 {string and character scanning} -setup {
+ set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "ababcd01234 f 123450" {%4[abcd] %4[abcd] %[^abcdef] %[^0]} a b c d] $a $b $c $d
-} {4 abab cd {01234 } {f 12345}}
-test scan-7.5 {string and character scanning} {
+} -result {4 abab cd {01234 } {f 12345}}
+test scan-7.5 {string and character scanning} -setup {
set a {}; set b {}; set c {}
+} -body {
list [scan "aaaaaabc aaabcdefg + + XYZQR" {%*4[a] %s %*4[a]%s%*4[ +]%c} a b c] $a $b $c
-} {3 aabc bcdefg 43}
-test scan-7.6 {string and character scanning, unicode} {
+} -result {3 aabc bcdefg 43}
+test scan-7.6 {string and character scanning, unicode} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "abc d\u00c7fghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d
-} "4 abc d\u00c7f ghijk dum"
-test scan-7.7 {string and character scanning, unicode} {
+} -result "4 abc d\u00c7f ghijk dum"
+test scan-7.7 {string and character scanning, unicode} -setup {
set a {}; set b {}
+} -body {
list [scan "ab\u00c7cdef" "ab%c%c" a b] $a $b
-} "2 199 99"
-test scan-7.8 {string and character scanning, unicode} {
+} -result "2 199 99"
+test scan-7.8 {string and character scanning, unicode} -setup {
set a {}; set b {}
+} -body {
list [scan "ab\ufeffdef" "%\[ab\ufeff\]" a] $a
-} "1 ab\ufeff"
+} -result "1 ab\ufeff"
-test scan-8.1 {error conditions} {
- catch {scan a}
-} 1
-test scan-8.2 {error conditions} {
- catch {scan a} msg
- set msg
-} {wrong # args: should be "scan string format ?varName ...?"}
-test scan-8.3 {error conditions} {
- list [catch {scan a %D x} msg] $msg
-} {1 {bad scan conversion character "D"}}
-test scan-8.4 {error conditions} {
- list [catch {scan a %O x} msg] $msg
-} {1 {bad scan conversion character "O"}}
-test scan-8.5 {error conditions} {
- list [catch {scan a %X x} msg] $msg
-} {1 {bad scan conversion character "X"}}
-test scan-8.6 {error conditions} {
- list [catch {scan a %F x} msg] $msg
-} {1 {bad scan conversion character "F"}}
-test scan-8.7 {error conditions} {
- list [catch {scan a %E x} msg] $msg
-} {1 {bad scan conversion character "E"}}
-test scan-8.8 {error conditions} {
- list [catch {scan a "%d %d" a} msg] $msg
-} {1 {different numbers of variable names and field specifiers}}
-test scan-8.9 {error conditions} {
- list [catch {scan a "%d %d" a b c} msg] $msg
-} {1 {variable is not assigned by any conversion specifiers}}
-test scan-8.10 {error conditions} {
+test scan-8.1 {error conditions} -body {
+ scan a
+} -returnCodes error -match glob -result *
+test scan-8.2 {error conditions} -returnCodes error -body {
+ scan a
+} -result {wrong # args: should be "scan string format ?varName ...?"}
+test scan-8.3 {error conditions} -returnCodes error -body {
+ scan a %D x
+} -result {bad scan conversion character "D"}
+test scan-8.4 {error conditions} -returnCodes error -body {
+ scan a %O x
+} -result {bad scan conversion character "O"}
+test scan-8.5 {error conditions} -returnCodes error -body {
+ scan a %B x
+} -result {bad scan conversion character "B"}
+test scan-8.6 {error conditions} -returnCodes error -body {
+ scan a %F x
+} -result {bad scan conversion character "F"}
+test scan-8.7 {error conditions} -returnCodes error -body {
+ scan a %p x
+} -result {bad scan conversion character "p"}
+test scan-8.8 {error conditions} -returnCodes error -body {
+ scan a "%d %d" a
+} -result {different numbers of variable names and field specifiers}
+test scan-8.9 {error conditions} -returnCodes error -body {
+ scan a "%d %d" a b c
+} -result {variable is not assigned by any conversion specifiers}
+test scan-8.10 {error conditions} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [expr {[scan " a" " a %d %d %d %d" a b c d] <= 0}] $a $b $c $d
-} {1 {} {} {} {}}
-test scan-8.11 {error conditions} {
+} -result {1 {} {} {} {}}
+test scan-8.11 {error conditions} -setup {
set a {}; set b {}; set c {}; set d {}
+} -body {
list [scan "1 2" "%d %d %d %d" a b c d] $a $b $c $d
-} {2 1 2 {} {}}
-test scan-8.12 {error conditions} {
- catch {unset a}
+} -result {2 1 2 {} {}}
+test scan-8.12 {error conditions} -setup {
+ unset -nocomplain a
+} -body {
set a(0) 44
- list [catch {scan 44 %d a} msg] $msg
-} {1 {can't set "a": variable is array}}
-test scan-8.13 {error conditions} {
- catch {unset a}
+ scan 44 %d a
+} -returnCodes error -cleanup {
+ unset -nocomplain a
+} -result {can't set "a": variable is array}
+test scan-8.13 {error conditions} -setup {
+ unset -nocomplain a
+} -body {
set a(0) 44
- list [catch {scan 44 %c a} msg] $msg
-} {1 {can't set "a": variable is array}}
-test scan-8.14 {error conditions} {
- catch {unset a}
+ scan 44 %c a
+} -returnCodes error -cleanup {
+ unset -nocomplain a
+} -result {can't set "a": variable is array}
+test scan-8.14 {error conditions} -setup {
+ unset -nocomplain a
+} -body {
set a(0) 44
- list [catch {scan 44 %s a} msg] $msg
-} {1 {can't set "a": variable is array}}
-test scan-8.15 {error conditions} {
- catch {unset a}
+ scan 44 %s a
+} -returnCodes error -cleanup {
+ unset -nocomplain a
+} -result {can't set "a": variable is array}
+test scan-8.15 {error conditions} -setup {
+ unset -nocomplain a
+} -body {
set a(0) 44
- list [catch {scan 44 %f a} msg] $msg
-} {1 {can't set "a": variable is array}}
-test scan-8.16 {error conditions} {
- catch {unset a}
+ scan 44 %f a
+} -returnCodes error -cleanup {
+ unset -nocomplain a
+} -result {can't set "a": variable is array}
+test scan-8.16 {error conditions} -setup {
+ unset -nocomplain a
+} -body {
set a(0) 44
- list [catch {scan 44 %f a} msg] $msg
-} {1 {can't set "a": variable is array}}
-catch {unset a}
-test scan-8.17 {error conditions} {
- list [catch {scan 44 %2c a} msg] $msg
-} {1 {field width may not be specified in %c conversion}}
-test scan-8.18 {error conditions} {
- list [catch {scan abc {%[} x} msg] $msg
-} {1 {unmatched [ in format string}}
-test scan-8.19 {error conditions} {
- list [catch {scan abc {%[^a} x} msg] $msg
-} {1 {unmatched [ in format string}}
-test scan-8.20 {error conditions} {
- list [catch {scan abc {%[^]a} x} msg] $msg
-} {1 {unmatched [ in format string}}
-test scan-8.21 {error conditions} {
- list [catch {scan abc {%[]a} x} msg] $msg
-} {1 {unmatched [ in format string}}
+ scan 44 %f a
+} -returnCodes error -cleanup {
+ unset -nocomplain a
+} -result {can't set "a": variable is array}
+test scan-8.17 {error conditions} -returnCodes error -body {
+ scan 44 %2c a
+} -result {field width may not be specified in %c conversion}
+test scan-8.18 {error conditions} -returnCodes error -body {
+ scan abc {%[} x
+} -result {unmatched [ in format string}
+test scan-8.19 {error conditions} -returnCodes error -body {
+ scan abc {%[^a} x
+} -result {unmatched [ in format string}
+test scan-8.20 {error conditions} -returnCodes error -body {
+ scan abc {%[^]a} x
+} -result {unmatched [ in format string}
+test scan-8.21 {error conditions} -returnCodes error -body {
+ scan abc {%[]a} x
+} -result {unmatched [ in format string}
test scan-9.1 {lots of arguments} {
scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20
@@ -591,27 +723,32 @@ test scan-9.2 {lots of arguments} {
set a20
} 200
-test scan-10.1 {miscellaneous tests} {
+test scan-10.1 {miscellaneous tests} -setup {
set a {}
+} -body {
list [scan ab16c ab%dc a] $a
-} {1 16}
-test scan-10.2 {miscellaneous tests} {
+} -result {1 16}
+test scan-10.2 {miscellaneous tests} -setup {
set a {}
+} -body {
list [scan ax16c ab%dc a] $a
-} {0 {}}
-test scan-10.3 {miscellaneous tests} {
+} -result {0 {}}
+test scan-10.3 {miscellaneous tests} -setup {
set a {}
+} -body {
list [catch {scan ab%c114 ab%%c%d a} msg] $msg $a
-} {0 1 114}
-test scan-10.4 {miscellaneous tests} {
+} -result {0 1 114}
+test scan-10.4 {miscellaneous tests} -setup {
set a {}
+} -body {
list [catch {scan ab%c14 ab%%c%d a} msg] $msg $a
-} {0 1 14}
-test scan-10.5 {miscellaneous tests} {
- catch {unset arr}
+} -result {0 1 14}
+test scan-10.5 {miscellaneous tests} -setup {
+ unset -nocomplain arr
+} -body {
set arr(2) {}
list [catch {scan ab%c14 ab%%c%d arr(2)} msg] $msg $arr(2)
-} {0 1 14}
+} -result {0 1 14}
test scan-10.6 {miscellaneous tests} {
scan 5a {%i%[a]}
} {5 a}
@@ -671,9 +808,9 @@ test scan-13.1 {Tcl_ScanObjCmd, inline XPG case} {
test scan-13.2 {Tcl_ScanObjCmd, inline XPG case} {
scan abc {%1$c%2$c%3$c%4$c}
} {97 98 99 {}}
-test scan-13.3 {Tcl_ScanObjCmd, inline XPG case} {
- list [catch {scan abc {%1$c%1$c}} msg] $msg
-} {1 {variable is assigned by multiple "%n$" conversion specifiers}}
+test scan-13.3 {Tcl_ScanObjCmd, inline XPG case} -returnCodes error -body {
+ scan abc {%1$c%1$c}
+} -result {variable is assigned by multiple "%n$" conversion specifiers}
test scan-13.4 {Tcl_ScanObjCmd, inline XPG case} {
scan abc {%2$s%1$c}
} {{} abc}
@@ -692,77 +829,20 @@ test scan-13.8 {Tcl_ScanObjCmd, inline XPG case lots of arguments} {
list [llength $msg] [lindex $msg 99] [lindex $msg 4] [lindex $msg 199]
} {200 10 20 30}
-# Big test for correct ordering of data in [expr]
-
-proc testIEEE {} {
- variable ieeeValues
- binary scan [binary format dd -1.0 1.0] c* c
- switch -exact -- $c {
- {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
- # little endian
- binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
- ieeeValues(-Infinity)
- binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
- ieeeValues(-Normal)
- binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
- ieeeValues(-Subnormal)
- binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
- ieeeValues(-0)
- binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
- ieeeValues(+0)
- binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
- ieeeValues(+Subnormal)
- binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
- ieeeValues(+Normal)
- binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
- ieeeValues(+Infinity)
- binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
- ieeeValues(NaN)
- set ieeeValues(littleEndian) 1
- return 1
- }
- {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
- binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
- ieeeValues(-Infinity)
- binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
- ieeeValues(-Normal)
- binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
- ieeeValues(-Subnormal)
- binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
- ieeeValues(-0)
- binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
- ieeeValues(+0)
- binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
- ieeeValues(+Subnormal)
- binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
- ieeeValues(+Normal)
- binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
- ieeeValues(+Infinity)
- binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
- ieeeValues(NaN)
- set ieeeValues(littleEndian) 0
- return 1
- }
- default {
- return 0
- }
- }
-}
-
-testConstraint ieeeFloatingPoint [testIEEE]
-
# scan infinities - not working
-test scan-14.1 {infinity} ieeeFloatingPoint {
+test scan-14.1 {positive infinity} {
scan Inf %g d
- set d
+ return $d
} Inf
-test scan-14.2 {infinity} ieeeFloatingPoint {
+test scan-14.2 {negative infinity} {
scan -Inf %g d
- set d
+ return $d
} -Inf
# TODO - also need to scan NaN's
+
+catch {rename int_range {}}
# cleanup
::tcltest::cleanupTests
diff --git a/tests/set-old.test b/tests/set-old.test
index 52dc0ff..4c25ec5 100644
--- a/tests/set-old.test
+++ b/tests/set-old.test
@@ -678,6 +678,11 @@ test set-old-8.57 {array command, array get with trivial pattern} {
set a(y) 2
array get a x
} {x 1}
+test set-old-8.58 {array command, array set with LVT and odd length literal} {
+ list [catch {apply {{} {
+ array set a {b c d}
+ }}} msg] $msg
+} {1 {list must have an even number of elements}}
test set-old-9.1 {ids for array enumeration} {
catch {unset a}
diff --git a/tests/set.test b/tests/set.test
index 9e0ddc0..18119f5 100644
--- a/tests/set.test
+++ b/tests/set.test
@@ -15,6 +15,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testset2 [llength [info commands testset2]]
catch {unset x}
@@ -521,6 +524,11 @@ test set-5.1 {error on malformed array name} testset2 {
list $msg $msg1
} {{can't read "z(a)(b)": variable isn't array} {can't read "z(b)(a)": variable isn't array}}
+# In a mem-debug build, this test will crash unless Bug 3602706 is fixed.
+test set-5.2 {Bug 3602706} -body {
+ testset2 ::tcl_platform not-in-there
+} -returnCodes error -result * -match glob
+
# cleanup
catch {unset a}
catch {unset b}
diff --git a/tests/socket.test b/tests/socket.test
index 0ea0eb5..51219e6 100644
--- a/tests/socket.test
+++ b/tests/socket.test
@@ -63,8 +63,8 @@
package require tcltest 2
namespace import -force ::tcltest::*
-# Some tests require the testthread and exec commands
-testConstraint testthread [llength [info commands testthread]]
+# Some tests require the Thread package or exec command
+testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
testConstraint exec [llength [info commands exec]]
# Produce a random port number in the Dynamic/Private range
@@ -1672,9 +1672,9 @@ test socket_$af-12.3 {testing inheritance of accepted sockets} -setup {
catch {close $p}
} -result {accepted socket was not inherited}
-test socket_$af-13.1 {Testing use of shared socket between two threads} -setup {
- threadReap
- set path(script) [makeFile [string map [list @localhost@ $localhost] {
+test socket_$af-13.1 {Testing use of shared socket between two threads} -body {
+ # create a thread
+ set serverthread [thread::create -preserved [string map [list @localhost@ $localhost] {
set f [socket -server accept -myaddr @localhost@ 0]
set listen [lindex [fconfigure $f -sockname] 2]
proc accept {s a p} {
@@ -1696,15 +1696,9 @@ test socket_$af-13.1 {Testing use of shared socket between two threads} -setup {
set i 0
vwait x
close $f
- # thread cleans itself up.
- testthread exit
- }] script]
-} -constraints [list socket supported_$af testthread] -body {
- # create a thread
- set serverthread [testthread create [list source $path(script) ] ]
- update
- set port [testthread send $serverthread {set listen}]
- update
+ thread::wait
+ }]]
+ set port [thread::send $serverthread {set listen}]
set s [socket $localhost $port]
fconfigure $s -buffering line
catch {
@@ -1712,11 +1706,9 @@ test socket_$af-13.1 {Testing use of shared socket between two threads} -setup {
gets $s result
}
close $s
- update
- append result " " [threadReap]
-} -cleanup {
- removeFile script
-} -result {hello 1}
+ thread::release $serverthread
+ append result " " [llength [thread::names]]
+} -result {hello 1} -constraints [list socket supported_$af thread]
# ----------------------------------------------------------------------
@@ -1769,6 +1761,7 @@ test socket-14.1 {[socket -async] fileevent while still connecting} \
set client [socket -async localhost $port]
fileevent $client writable {
lappend x [fconfigure $client -error]
+ fileevent $client writable {}
}
set after [after 1000 {lappend x timeout}]
while {[llength $x] < 2 && "timeout" ni $x} {
@@ -1784,17 +1777,20 @@ test socket-14.1 {[socket -async] fileevent while still connecting} \
test socket-14.2 {[socket -async] fileevent connection refused} \
-constraints [list socket supported_any] \
-body {
- set client [socket -async localhost [randport]]
- fileevent $client writable {set x [fconfigure $client -error]}
- set after [after 1000 {set x timeout}]
- vwait x
- if {$x eq "timeout"} {
- append x ": [fconfigure $client -error]"
- }
+ if {[catch {socket -async localhost [randport]} client]} {
+ regexp {[^:]*: (.*)} $client -> x
+ } else {
+ fileevent $client writable {set x [fconfigure $client -error]}
+ set after [after 1000 {set x timeout}]
+ vwait x
+ after cancel $after
+ if {$x eq "timeout"} {
+ append x ": [fconfigure $client -error]"
+ }
+ close $client
+ }
set x
} -cleanup {
- after cancel $after
- close $client
unset x
} -result "connection refused"
test socket-14.3 {[socket -async] when server only listens on IPv6} \
@@ -1845,6 +1841,7 @@ test socket-14.4 {[socket -async] and both, readdable and writable fileevents} \
after cancel $after
close $client
close $server
+ unset x
} -result {{} bye}
test socket-14.5 {[socket -async] which fails before any connect() can be made} \
-constraints [list socket supported_any] \
@@ -1854,6 +1851,33 @@ test socket-14.5 {[socket -async] which fails before any connect() can be made}
} \
-returnCodes 1 \
-result {couldn't open socket: cannot assign requested address}
+test socket-14.6 {[socket -async] with no event loop and [fconfigure -error] before the socket is connected} \
+ -constraints [list socket supported_inet supported_inet6] \
+ -setup {
+ proc accept {s a p} {
+ puts $s bye
+ close $s
+ }
+ set server [socket -server accept -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $server -sockname] 2]
+ set x ""
+ } \
+ -body {
+ set client [socket -async localhost $port]
+ foreach _ {1 2} {
+ lappend x [lindex [fconfigure $client -sockname] 0]
+ lappend x [fconfigure $client -error]
+ update
+ }
+ lappend x [gets $client]
+ } \
+ -cleanup {
+ close $server
+ close $client
+ unset x
+ } \
+ -result [list ::1 "connection refused" 127.0.0.1 "" bye]
+
::tcltest::cleanupTests
flush stdout
return
diff --git a/tests/source.test b/tests/source.test
index 081a129..0235bd1 100644
--- a/tests/source.test
+++ b/tests/source.test
@@ -107,6 +107,19 @@ test source-2.6 {source error conditions} -setup {
} -match listGlob -result [list 1 \
{couldn't read file "*_non_existent_": no such file or directory} \
{POSIX ENOENT {no such file or directory}}]
+test source-2.7 {utf-8 with BOM} -setup {
+ set sourcefile [makeFile {} source.file]
+} -body {
+ set out [open $sourcefile w]
+ fconfigure $out -encoding utf-8
+ puts $out "\ufeffset y new-y"
+ close $out
+ set y old-y
+ source -encoding utf-8 $sourcefile
+ return $y
+} -cleanup {
+ removeFile $sourcefile
+} -result {new-y}
test source-3.1 {return in middle of source file} -setup {
set sourcefile [makeFile {
@@ -174,6 +187,16 @@ test source-3.5 {return with special code etc.} -setup {
invoked from within
"source $sourcefile"} {a b c}}
+test source-4.1 {continuation line parsing} -setup {
+ set sourcefile [makeFile [string map {CL \\\n} {
+ format %s "[dict get [info frame 0] type]:CL[dict get [info frame 0] line]CL[dict get [info frame 0] line]CL[dict get [info frame 0] line]"
+ }] source.file]
+} -body {
+ source $sourcefile
+} -cleanup {
+ removeFile source.file
+} -result {source: 3 4 5}
+
test source-6.1 {source is binary ok} -setup {
# Note [makeFile] writes in the system encoding.
# [source] defaults to reading in the system encoding.
diff --git a/tests/stack.test b/tests/stack.test
index 873cb08..13bc524 100644
--- a/tests/stack.test
+++ b/tests/stack.test
@@ -9,10 +9,8 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest 2
- namespace import -force ::tcltest::*
-}
+package require tcltest 2
+namespace import ::tcltest::*
# Note that a failure in this test may result in a crash of the executable.
diff --git a/tests/string.test b/tests/string.test
index 1a62a66..cf658a2 100644
--- a/tests/string.test
+++ b/tests/string.test
@@ -17,6 +17,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
# Some tests require the testobj command
testConstraint testobj [expr {[info commands testobj] != {}}]
@@ -312,10 +315,10 @@ test string-6.4 {string is, too many args} {
} {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}}
test string-6.5 {string is, class check} {
list [catch {string is bogus str} msg] $msg
-} {1 {bad class "bogus": must be alnum, alpha, ascii, control, boolean, digit, double, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}}
+} {1 {bad class "bogus": must be alnum, alpha, ascii, control, boolean, digit, double, entier, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}}
test string-6.6 {string is, ambiguous class} {
list [catch {string is al str} msg] $msg
-} {1 {ambiguous class "al": must be alnum, alpha, ascii, control, boolean, digit, double, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}}
+} {1 {ambiguous class "al": must be alnum, alpha, ascii, control, boolean, digit, double, entier, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}}
test string-6.7 {string is alpha, all ok} {
string is alpha -strict -failindex var abc
} 1
@@ -405,13 +408,15 @@ test string-6.35 {string is double, false} {
test string-6.36 {string is double, false} {
list [string is double -fail var "\n"] $var
} {0 0}
-test string-6.37 {string is double, false on int overflow} {
+test string-6.37 {string is double, false on int overflow} -setup {
+ set var priorValue
+} -body {
# Make it the largest int recognizable, with one more digit for overflow
# Since bignums arrived in Tcl 8.5, the sense of this test changed.
# Now integer values that exceed native limits become bignums, and
# bignums can convert to doubles without error.
list [string is double -fail var [largest_int]0] $var
-} {1 0}
+} -result {1 priorValue}
# string-6.38 removed, underflow on input is no longer an error.
test string-6.39 {string is double, false} {
# This test is non-portable because IRIX thinks
@@ -592,7 +597,7 @@ test string-6.90 {string is integer, bad integers} {
foreach num $numbers {
lappend result [string is int -strict $num]
}
- set result
+ return $result
} {1 1 0 0 0 1 0 0}
test string-6.91 {string is double, bad doubles} {
set result ""
@@ -600,7 +605,7 @@ test string-6.91 {string is double, bad doubles} {
foreach num $numbers {
lappend result [string is double -strict $num]
}
- set result
+ return $result
} {1 1 0 0 0 1 0 0}
test string-6.92 {string is integer, 32-bit overflow} {
# Bug 718878
@@ -664,7 +669,7 @@ test string-6.107 {string is integer, bad integers} {
foreach num $numbers {
lappend result [string is wideinteger -strict $num]
}
- set result
+ return $result
} {1 1 0 0 0 1 0 0}
test string-6.108 {string is double, Bug 1382287} {
set x 2turtledoves
@@ -674,6 +679,78 @@ test string-6.108 {string is double, Bug 1382287} {
test string-6.109 {string is double, Bug 1360532} {
string is double 1\u00a0
} 0
+test string-6.110 {string is entier, true} {
+ string is entier +1234567890
+} 1
+test string-6.111 {string is entier, true on type} {
+ string is entier [expr wide(50.0)]
+} 1
+test string-6.112 {string is entier, true} {
+ string is entier [list -10]
+} 1
+test string-6.113 {string is entier, true as hex} {
+ string is entier 0xabcdef
+} 1
+test string-6.114 {string is entier, true as octal} {
+ string is entier 0123456
+} 1
+test string-6.115 {string is entier, true with whitespace} {
+ string is entier " \n1234\v"
+} 1
+test string-6.116 {string is entier, false} {
+ list [string is entier -fail var 123abc] $var
+} {0 3}
+test string-6.117 {string is entier, false} {
+ list [string is entier -fail var 123123123123123123123123123123123123123123123123123123123123123123123123123123123123abc] $var
+} {0 84}
+test string-6.118 {string is entier, false} {
+ list [string is entier -fail var [expr double(1)]] $var
+} {0 1}
+test string-6.119 {string is entier, false} {
+ list [string is entier -fail var " "] $var
+} {0 0}
+test string-6.120 {string is entier, false on bad octal} {
+ list [string is entier -fail var 0o36963] $var
+} {0 4}
+test string-6.121.1 {string is entier, false on bad octal} {
+ list [string is entier -fail var 0o36963] $var
+} {0 4}
+test string-6.122 {string is entier, false on bad hex} {
+ list [string is entier -fail var 0X345XYZ] $var
+} {0 5}
+test string-6.123 {string is entier, bad integers} {
+ # SF bug #634856
+ set result ""
+ set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1"]
+ foreach num $numbers {
+ lappend result [string is entier -strict $num]
+ }
+ return $result
+} {1 1 0 0 0 1 0 0}
+test string-6.124 {string is entier, true} {
+ string is entier +1234567890123456789012345678901234567890
+} 1
+test string-6.125 {string is entier, true} {
+ string is entier [list -10000000000000000000000000000000000000000000000000000000000000000000000000000000000000]
+} 1
+test string-6.126 {string is entier, true as hex} {
+ string is entier 0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef
+} 1
+test string-6.127 {string is entier, true as octal} {
+ string is entier 0123456112341234561234565623456123456123456123456123456123456123456123456123456123456
+} 1
+test string-6.128 {string is entier, true with whitespace} {
+ string is entier " \n12340000000000000000000000000000000000000000000000000000000000000000000000000000000000000\v"
+} 1
+test string-6.129 {string is entier, false on bad octal} {
+ list [string is entier -fail var 0o1234561123412345612345656234561234561234561234561234561234561234561234561234561234536963] $var
+} {0 87}
+test string-6.130.1 {string is entier, false on bad octal} {
+ list [string is entier -fail var 0o1234561123412345612345656234561234561234561234561234561234561234561234561234561234536963] $var
+} {0 87}
+test string-6.131 {string is entier, false on bad hex} {
+ list [string is entier -fail var 0X12345611234123456123456562345612345612345612345612345612345612345612345612345612345345XYZ] $var
+} {0 88}
catch {rename largest_int {}}
@@ -1321,6 +1398,9 @@ test string-15.9 {string tolower} {
test string-15.10 {string tolower, unicode} {
string tolower ABCabc\xc7\xe7
} "abcabc\xe7\xe7"
+test string-15.11 {string tolower, compiled} {
+ lindex [string tolower [list A B [list C]]] 1
+} b
test string-16.1 {string toupper} {
list [catch {string toupper} msg] $msg
@@ -1352,6 +1432,9 @@ test string-16.9 {string toupper} {
test string-16.10 {string toupper, unicode} {
string toupper ABCabc\xc7\xe7
} "ABCABC\xc7\xc7"
+test string-16.11 {string toupper, compiled} {
+ lindex [string toupper [list a b [list c]]] 1
+} B
test string-17.1 {string totitle} {
list [catch {string totitle} msg] $msg
@@ -1374,6 +1457,9 @@ test string-17.6 {string totitle, unicode} {
test string-17.7 {string totitle, unicode} {
string totitle \u01f3BCabc\xc7\xe7
} "\u01f2bcabc\xe7\xe7"
+test string-17.8 {string totitle, compiled} {
+ lindex [string totitle [list aa bb [list cc]]] 0
+} Aa
test string-18.1 {string trim} {
list [catch {string trim} msg] $msg
@@ -1409,8 +1495,8 @@ test string-18.11 {string trim, unicode} {
string trim "\xe7\xe8 AB\xe7C \xe8\xe7" \xe7\xe8
} " AB\xe7C "
test string-18.12 {string trim, unicode default} {
- string trim ABC\u1361\u1680\u3000
-} ABC
+ string trim \ufeff\x00\u0085\u00a0\u1680\u180eABC\u1361\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000
+} ABC\u1361
test string-19.1 {string trimleft} {
list [catch {string trimleft} msg] $msg
@@ -1419,8 +1505,8 @@ test string-19.2 {string trimleft} {
string trimleft " XYZ "
} {XYZ }
test string-19.3 {string trimleft, unicode default} {
- string trimleft \u1361\u1680\u3000ABC
-} ABC
+ string trimleft \ufeff\u0085\u00a0\x00\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000\u1361ABC
+} \u1361ABC
test string-20.1 {string trimright errors} {
list [catch {string trimright} msg] $msg
@@ -1438,8 +1524,8 @@ test string-20.5 {string trimright} {
string trimright ""
} {}
test string-20.6 {string trimright, unicode default} {
- string trimright ABC\u1361\u1680\u3000
-} ABC
+ string trimright ABC\u1361\u0085\x00\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000
+} ABC\u1361
test string-21.1 {string wordend} {
list [catch {string wordend a} msg] $msg
@@ -1623,6 +1709,17 @@ test string-24.12 {string reverse command - corner case} {
set y \udead
string is ascii [string reverse $x$y]
} 0
+test string-24.13 {string reverse command - pure Unicode string} {
+ string reverse [string range \ubeef\udead\ubeef\udead\ubeef\udead 1 5]
+} \udead\ubeef\udead\ubeef\udead
+test string-24.14 {string reverse command - pure bytearray} {
+ binary scan [string reverse [binary format H* 010203]] H* x
+ set x
+} 030201
+test string-24.15 {string reverse command - pure bytearray} {
+ binary scan [tcl::string::reverse [binary format H* 010203]] H* x
+ set x
+} 030201
test string-25.1 {string is list} {
string is list {a b c}
@@ -1690,10 +1787,10 @@ test string-26.3.1 {tcl::prefix, bad args} -body {
} -returnCodes 1 -result {error options must have an even number of elements}
test string-26.3.2 {tcl::prefix, bad args} -body {
tcl::prefix match -error str1 str2
-} -returnCodes 1 -result {missing error options}
+} -returnCodes 1 -result {missing value for -error}
test string-26.4 {tcl::prefix, bad args} -body {
tcl::prefix match -message str1 str2
-} -returnCodes 1 -result {missing message}
+} -returnCodes 1 -result {missing value for -message}
test string-26.5 {tcl::prefix} {
tcl::prefix match {apa bepa cepa depa} cepa
} cepa
diff --git a/tests/stringComp.test b/tests/stringComp.test
index ff18819..165ef20 100644
--- a/tests/stringComp.test
+++ b/tests/stringComp.test
@@ -20,10 +20,29 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
# Some tests require the testobj command
testConstraint testobj [expr {[info commands testobj] != {}}]
-
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+ proc getbytes {} {
+ set lines [split [memory info] \n]
+ return [lindex $lines 3 3]
+ }
+ proc leaktest {script {iterations 3}} {
+ set end [getbytes]
+ for {set i 0} {$i < $iterations} {incr i} {
+ uplevel 1 $script
+ set tmp $end
+ set end [getbytes]
+ }
+ return [expr {$end - $tmp}]
+ }
+}
+
test stringComp-1.1 {error conditions} {
proc foo {} {string gorp a b}
list [catch {foo} msg] $msg
@@ -674,13 +693,33 @@ test stringComp-11.54 {string match, failure} {
} {0 1 1 1 0 0}
## string range
-## not yet bc
+test stringComp-12.1 {Bug 3588366: end-offsets before start} {
+ apply {s {
+ string range $s 0 end-5
+ }} 12345
+} {}
## string repeat
## not yet bc
## string replace
-## not yet bc
+test stringComp-14.1 {Bug 82e7f67325} {
+ apply {x {
+ set a [join $x {}]
+ lappend b [string length [string replace ___! 0 2 $a]]
+ lappend b [string length [string replace ___! 0 2 $a[unset a]]]
+ }} {a b}
+} {3 3}
+test stringComp-14.2 {Bug 82e7f67325} memory {
+ # As in stringComp-14.1, but make sure we don't retain too many refs
+ leaktest {
+ apply {x {
+ set a [join $x {}]
+ lappend b [string length [string replace ___! 0 2 $a]]
+ lappend b [string length [string replace ___! 0 2 $a[unset a]]]
+ }} {a b}
+ }
+} {0}
## string tolower
## not yet bc
@@ -696,8 +735,12 @@ test stringComp-11.54 {string match, failure} {
## string word*
## not yet bc
-
+
# cleanup
catch {rename foo {}}
::tcltest::cleanupTests
return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/stringObj.test b/tests/stringObj.test
index 2f516ec..6f331d3 100644
--- a/tests/stringObj.test
+++ b/tests/stringObj.test
@@ -17,6 +17,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testobj [llength [info commands testobj]]
testConstraint testdstring [llength [info commands testdstring]]
@@ -444,35 +447,35 @@ test stringObj-14.1 {Tcl_SetObjLength on pure unicode object} testobj {
teststringobj get 1
} {bar}
-test stringObj-15.1 {Tcl_Append*ToObj: self appends} {
+test stringObj-15.1 {Tcl_Append*ToObj: self appends} testobj {
teststringobj set 1 foo
teststringobj appendself 1 0
} foofoo
-test stringObj-15.2 {Tcl_Append*ToObj: self appends} {
+test stringObj-15.2 {Tcl_Append*ToObj: self appends} testobj {
teststringobj set 1 foo
teststringobj appendself 1 1
} foooo
-test stringObj-15.3 {Tcl_Append*ToObj: self appends} {
+test stringObj-15.3 {Tcl_Append*ToObj: self appends} testobj {
teststringobj set 1 foo
teststringobj appendself 1 2
} fooo
-test stringObj-15.4 {Tcl_Append*ToObj: self appends} {
+test stringObj-15.4 {Tcl_Append*ToObj: self appends} testobj {
teststringobj set 1 foo
teststringobj appendself 1 3
} foo
-test stringObj-15.5 {Tcl_Append*ToObj: self appends} {
+test stringObj-15.5 {Tcl_Append*ToObj: self appends} testobj {
teststringobj set 1 foo
teststringobj appendself2 1 0
} foofoo
-test stringObj-15.6 {Tcl_Append*ToObj: self appends} {
+test stringObj-15.6 {Tcl_Append*ToObj: self appends} testobj {
teststringobj set 1 foo
teststringobj appendself2 1 1
} foooo
-test stringObj-15.7 {Tcl_Append*ToObj: self appends} {
+test stringObj-15.7 {Tcl_Append*ToObj: self appends} testobj {
teststringobj set 1 foo
teststringobj appendself2 1 2
} fooo
-test stringObj-15.8 {Tcl_Append*ToObj: self appends} {
+test stringObj-15.8 {Tcl_Append*ToObj: self appends} testobj {
teststringobj set 1 foo
teststringobj appendself2 1 3
} foo
diff --git a/tests/subst.test b/tests/subst.test
index 4be4798..7466895 100644
--- a/tests/subst.test
+++ b/tests/subst.test
@@ -293,6 +293,10 @@ test subst-13.1 {Bug 3081065} -setup {
} -cleanup {
removeFile subst13.tcl
}
+test subst-13.2 {Test for segfault} -body {
+ subst {[}
+} -returnCodes error -result * -match glob
+
# cleanup
::tcltest::cleanupTests
diff --git a/tests/switch.test b/tests/switch.test
index 255be00..a03948b 100644
--- a/tests/switch.test
+++ b/tests/switch.test
@@ -536,7 +536,7 @@ test switch-11.6 {-matchvar unwritable} {
test switch-12.1 {regexp matching with -indexvar} {
switch -regexp -indexvar x -- abc {.(.). {set x}}
-} {{0 3} {1 2}}
+} {{0 2} {1 1}}
test switch-12.2 {regexp matching with -indexvar} {
set x GOOD
switch -regexp -indexvar x -- abc {.(.).. {list $x z}}
@@ -544,7 +544,7 @@ test switch-12.2 {regexp matching with -indexvar} {
} GOOD
test switch-12.3 {regexp matching with -indexvar} {
switch -regexp -indexvar x -- "a b c" {.(.). {set x}}
-} {{0 3} {1 2}}
+} {{0 2} {1 1}}
test switch-12.4 {regexp matching with -indexvar} {
set x BAD
switch -regexp -indexvar x -- "a b c" {
@@ -560,22 +560,32 @@ test switch-12.6 {-indexvar unwritable} {
set x {}
list [catch {switch -regexp -indexvar x(x) -- abc . {set x}} msg] $x $msg
} {1 {} {can't set "x(x)": variable isn't array}}
+test switch-12.7 {[Bug 3106532] -indexvar should be directly usable with [string range]} {
+ set str abcdef
+ switch -regexp -indexvar x -- $str ^... {string range $str {*}[lindex $x 0]}
+} abc
+test switch-12.8 {-indexvar and matched empty strings} {
+ switch -regexp -indexvar x -- abcdef ^...(x?) {return $x}
+} {{0 2} {3 2}}
+test switch-12.9 {-indexvar and unmatched strings} {
+ switch -regexp -indexvar x -- abcdef ^...(x)? {return $x}
+} {{0 2} {-1 -1}}
test switch-13.1 {-indexvar -matchvar combinations} {
switch -regexp -indexvar x -matchvar y abc {
. {list $x $y}
}
-} {{{0 1}} a}
+} {{{0 0}} a}
test switch-13.2 {-indexvar -matchvar combinations} {
switch -regexp -indexvar x -matchvar y abc {
.$ {list $x $y}
}
-} {{{2 3}} c}
+} {{{2 2}} c}
test switch-13.3 {-indexvar -matchvar combinations} {
switch -regexp -indexvar x -matchvar y abc {
(.)(.)(.) {list $x $y}
}
-} {{{0 3} {0 1} {1 2} {2 3}} {abc a b c}}
+} {{{0 2} {0 0} {1 1} {2 2}} {abc a b c}}
test switch-13.4 {-indexvar -matchvar combinations} {
set x -
set y -
@@ -597,7 +607,7 @@ test switch-13.6 {-indexvar -matchvar combinations} {
list [catch {
switch -regexp -indexvar x -matchvar y(y) abc {. {list $x $y}}
} msg] $x $y $msg
-} {1 {{0 1}} - {can't set "y(y)": variable isn't array}}
+} {1 {{0 0}} - {can't set "y(y)": variable isn't array}}
test switch-14.1 {-regexp -- compilation [Bug 1854399]} {
switch -regexp -- 0 {
diff --git a/tests/tailcall.test b/tests/tailcall.test
index e9ec188..2d04f82 100644
--- a/tests/tailcall.test
+++ b/tests/tailcall.test
@@ -14,6 +14,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testnrelevels [llength [info commands testnrelevels]]
#
diff --git a/tests/tcltest.test b/tests/tcltest.test
index 86aca6f..ce8d617 100755..100644
--- a/tests/tcltest.test
+++ b/tests/tcltest.test
@@ -80,10 +80,7 @@ proc slave {msgVar args} {
# Need to capture output in msg
- set code [catch {i eval {source $argv0}} foo]
-if $code {
-#puts "$code: $foo\n$::errorInfo"
-}
+ set code [catch {i eval {source $argv0}}]
i eval {close $tcltest::outputChannel}
interp delete [namespace current]::i
set f [open $of]
@@ -99,8 +96,6 @@ if $code {
append msg \n$err
}
return $code
-
-# return [catch {uplevel 1 [linsert $args 0 exec [interpreter]]} msg]
}
test tcltest-2.0 {tcltest (verbose default - 'b')} {unixOrPc} {
set result [slave msg test.tcl]
@@ -549,7 +544,7 @@ set notWriteableDir [file join [temporaryDirectory] notwriteable]
makeDirectory notreadable
makeDirectory notwriteable
switch -- $::tcl_platform(platform) {
- "unix" {
+ unix {
file attributes $notReadableDir -permissions 00333
file attributes $notWriteableDir -permissions 00555
}
@@ -716,8 +711,8 @@ test tcltest-8.60 {::workingDirectory} {
# clean up from directory testing
-switch $::tcl_platform(platform) {
- "unix" {
+switch -- $::tcl_platform(platform) {
+ unix {
file attributes $notReadableDir -permissions 777
file attributes $notWriteableDir -permissions 777
}
@@ -727,7 +722,7 @@ switch $::tcl_platform(platform) {
}
}
-file delete -force $notReadableDir $notWriteableDir
+file delete -force -- $notReadableDir $notWriteableDir
removeFile a.tcl
removeFile thisdirectoryisafile
removeDirectory normaldirectory
@@ -1150,7 +1145,7 @@ test tcltest-19.1 {TCLTEST_OPTIONS default} -setup {
} -cleanup {
interp delete slave2
interp delete slave1
- if {$oldoptions == "none"} {
+ if {$oldoptions eq "none"} {
unset ::env(TCLTEST_OPTIONS)
} else {
set ::env(TCLTEST_OPTIONS) $oldoptions
diff --git a/tests/thread.test b/tests/thread.test
index a6961ed..f32ef61 100644
--- a/tests/thread.test
+++ b/tests/thread.test
@@ -12,274 +12,251 @@
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest
+ package require tcltest 2.2
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
# Some tests require the testthread command
testConstraint testthread [expr {[info commands testthread] != {}}]
-if {[testConstraint testthread]} {
- testthread errorproc ThreadError
+# Some tests require the Thread package
+
+testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
- proc ThreadError {id info} {
- global threadId threadError
- set threadId $id
- set threadError $info
+# Some tests may not work under valgrind
+
+testConstraint notValgrind [expr {![testConstraint valgrind]}]
+
+set threadSuperKillScript {
+ rename catch ""
+ rename while ""
+ rename unknown ""
+ rename update ""
+ thread::release
+}
+
+proc getThreadErrorFromInfo { info } {
+ set list [split $info \n]
+ set idx [lsearch -glob $list "*eval*unwound*"]
+ if {$idx != -1} then {
+ return [lindex $list $idx]
+ }
+ set idx [lsearch -glob $list "*eval*canceled*"]
+ if {$idx != -1} then {
+ return [lindex $list $idx]
}
+ return ""; # some other error we do not care about.
+}
- proc ThreadNullError {id info} {
- # ignore
+proc findThreadError { info } {
+ foreach error [lreverse $info] {
+ set error [getThreadErrorFromInfo $error]
+ if {[string length $error] > 0} then {
+ return $error
+ }
}
+ return ""; # some other error we do not care about.
}
+proc ThreadError {id info} {
+ global threadSawError
+ if {[string length [getThreadErrorFromInfo $info]] > 0} then {
+ global threadId threadError
+ set threadId $id
+ lappend threadError($id) $info
+ }
+ set threadSawError($id) true; # signal main thread to exit [vwait].
+}
-test thread-1.1 {Tcl_ThreadObjCmd: no args} {testthread} {
- list [catch {testthread} msg] $msg
-} {1 {wrong # args: should be "testthread option ?arg ...?"}}
-test thread-1.2 {Tcl_ThreadObjCmd: bad option} {testthread} {
- list [catch {testthread foo} msg] $msg
-} {1 {bad option "foo": must be cancel, create, event, exit, id, join, names, send, wait, or errorproc}}
-test thread-1.3 {Tcl_ThreadObjCmd: initial thread list} {testthread} {
- list [threadReap] [llength [testthread names]]
-} {1 1}
-test thread-1.4 {Tcl_ThreadObjCmd: thread create } {testthread} {
- threadReap
- set serverthread [testthread create]
- update
- set numthreads [llength [testthread names]]
- threadReap
+if {[testConstraint thread]} {
+ thread::errorproc ThreadError
+}
+
+if {[testConstraint testthread]} {
+ proc drainEventQueue {} {
+ while {[set x [testthread event]]} {
+ #puts "WARNING: drained $x event(s) on main thread"
+ }
+ }
+
+ testthread errorproc ThreadError
+}
+
+# Some tests require manual draining of the event queue
+
+testConstraint drainEventQueue [expr {[info commands drainEventQueue] != {}}]
+
+test thread-1.3 {Tcl_ThreadObjCmd: initial thread list} {thread} {
+ llength [thread::names]
+} 1
+test thread-1.4 {Tcl_ThreadObjCmd: thread create } {thread} {
+ set serverthread [thread::create -preserved]
+ set numthreads [llength [thread::names]]
+ thread::release $serverthread
set numthreads
} {2}
-test thread-1.5 {Tcl_ThreadObjCmd: thread create one shot} {testthread} {
- threadReap
- testthread create {set x 5}
+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 [testthread names]]
+ set l [llength [thread::names]]
if {$l == 1} {
break
}
}
- threadReap
set l
} {1}
-test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {testthread} {
- threadReap
- testthread create {testthread exit}
+test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} {
+ thread::create {{*}{}}
update
after 10
- set result [llength [testthread names]]
- threadReap
- set result
+ llength [thread::names]
} {1}
-test thread-1.7 {Tcl_ThreadObjCmd: thread id args} {testthread} {
- set x [catch {testthread id x} msg]
- list $x $msg
-} {1 {wrong # args: should be "testthread id"}}
-test thread-1.8 {Tcl_ThreadObjCmd: thread id} {testthread} {
- string compare [testthread id] $::tcltest::mainThread
-} {0}
-test thread-1.9 {Tcl_ThreadObjCmd: thread names args} {testthread} {
- set x [catch {testthread names x} msg]
- list $x $msg
-} {1 {wrong # args: should be "testthread names"}}
-test thread-1.10 {Tcl_ThreadObjCmd: thread id} {testthread} {
- string compare [testthread names] $::tcltest::mainThread
-} {0}
-test thread-1.11 {Tcl_ThreadObjCmd: send args} {testthread} {
- set x [catch {testthread send} msg]
- list $x $msg
-} {1 {wrong # args: should be "testthread send ?-async? id script"}}
-test thread-1.12 {Tcl_ThreadObjCmd: send nonint} {testthread} {
- set x [catch {testthread send abc command} msg]
- list $x $msg
-} {1 {expected integer but got "abc"}}
-test thread-1.13 {Tcl_ThreadObjCmd: send args} {testthread} {
- threadReap
- set serverthread [testthread create]
- set five [testthread send $serverthread {set x 5}]
- threadReap
+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
set five
} 5
-test thread-1.14 {Tcl_ThreadObjCmd: send bad id} {testthread} {
- set tid [expr $::tcltest::mainThread + 10]
- set x [catch {testthread send $tid {set x 5}} msg]
- list $x $msg
-} {1 {invalid thread id}}
-test thread-1.15 {Tcl_ThreadObjCmd: wait} {testthread} {
- threadReap
- set serverthread [testthread create {set z 5 ; testthread wait}]
- set five [testthread send $serverthread {set z}]
- threadReap
+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
set five
} 5
-test thread-1.16 {Tcl_ThreadObjCmd: errorproc args} {testthread} {
- set x [catch {testthread errorproc foo bar} msg]
- list $x $msg
-} {1 {wrong # args: should be "testthread errorproc proc"}}
-test thread-1.17 {Tcl_ThreadObjCmd: errorproc change} {testthread} {
- testthread errorproc foo
- testthread errorproc ThreadError
-} {}
# The tests above also cover:
# TclCreateThread, except when pthread_create fails
# NewThread, safe and regular
# ThreadErrorProc, except for printing to standard error
-test thread-2.1 {ListUpdateInner and ListRemove} {testthread} {
- threadReap
+test thread-2.1 {ListUpdateInner and ListRemove} {thread} {
catch {unset tid}
foreach t {0 1 2} {
upvar #0 t$t tid
- set tid [testthread create]
+ set tid [thread::create -preserved]
}
- threadReap
+ foreach t {0 1 2} {
+ upvar #0 t$t tid
+ thread::release $tid
+ }
+ llength [thread::names]
} 1
-test thread-3.1 {TclThreadList} {testthread} {
- threadReap
+test thread-3.1 {TclThreadList} {thread} {
catch {unset tid}
- set len [llength [testthread names]]
+ set len [llength [thread::names]]
set l1 {}
foreach t {0 1 2} {
- lappend l1 [testthread create]
+ lappend l1 [thread::create -preserved]
+ }
+ set l2 [thread::names]
+ set c [string compare [lsort [concat [thread::id] $l1]] [lsort $l2]]
+ foreach t $l1 {
+ thread::release $t
}
- set l2 [testthread names]
- list $l1 $l2
- set c [string compare \
- [lsort -integer [concat $::tcltest::mainThread $l1]] \
- [lsort -integer $l2]]
- threadReap
list $len $c
} {1 0}
-test thread-4.1 {TclThreadSend to self} {testthread} {
+test thread-4.1 {TclThreadSend to self} {thread} {
catch {unset x}
- testthread send [testthread id] {
+ thread::send [thread::id] {
set x 4
}
set x
} {4}
-test thread-4.2 {TclThreadSend -async} {testthread} {
- threadReap
- set len [llength [testthread names]]
- set serverthread [testthread create]
- testthread send -async $serverthread {
- after 1000
- testthread exit
+test thread-4.2 {TclThreadSend -async} {thread} {
+ set len [llength [thread::names]]
+ set serverthread [thread::create -preserved]
+ thread::send -async $serverthread {
+ after 1 {thread::release}
}
- set two [llength [testthread names]]
- after 1500 {set done 1}
+ set two [llength [thread::names]]
+ after 100 {set done 1}
vwait done
- threadReap
- list $len [llength [testthread names]] $two
+ list $len [llength [thread::names]] $two
} {1 1 2}
-test thread-4.3 {TclThreadSend preserve errorInfo} {testthread} {
- threadReap
- set len [llength [testthread names]]
- set serverthread [testthread create]
- set x [catch {testthread send $serverthread {set undef}} msg]
+test thread-4.3 {TclThreadSend preserve errorInfo} {thread} {
+ set len [llength [thread::names]]
+ set serverthread [thread::create -preserved]
+ set x [catch {thread::send $serverthread {set undef}} msg]
set savedErrorInfo $::errorInfo
- threadReap
+ thread::release $serverthread
list $len $x $msg $savedErrorInfo
} {1 1 {can't read "undef": no such variable} {can't read "undef": no such variable
while executing
"set undef"
invoked from within
-"testthread send $serverthread {set undef}"}}
-test thread-4.4 {TclThreadSend preserve code} {testthread} {
- threadReap
- set len [llength [testthread names]]
- set serverthread [testthread create]
+"thread::send $serverthread {set undef}"}}
+test thread-4.4 {TclThreadSend preserve code} {thread} {
+ set len [llength [thread::names]]
+ set serverthread [thread::create -preserved]
set ::errorInfo {}
- set x [catch {testthread send $serverthread {set ::errorInfo {}; break}} msg]
+ set x [catch {thread::send $serverthread {set ::errorInfo {}; break}} msg]
set savedErrorInfo $::errorInfo
- threadReap
+ thread::release $serverthread
list $len $x $msg $savedErrorInfo
} {1 3 {} {}}
-test thread-4.5 {TclThreadSend preserve errorCode} {testthread} {
- threadReap
- set ::tcltest::mainThread [testthread names]
- set serverthread [testthread create]
- set x [catch {testthread send $serverthread {error ERR INFO CODE}} msg]
+test thread-4.5 {TclThreadSend preserve errorCode} {thread} {
+ set serverthread [thread::create]
+ set x [catch {thread::send $serverthread {error ERR INFO CODE}} msg]
set savedErrorCode $::errorCode
- threadReap
+ thread::release $serverthread
list $x $msg $savedErrorCode
} {1 ERR CODE}
-test thread-5.0 {Joining threads} {testthread} {
- threadReap
- set serverthread [testthread create -joinable]
- testthread send -async $serverthread {after 1000 ; testthread exit}
- set res [testthread join $serverthread]
- threadReap
- set res
+test thread-5.0 {Joining threads} {thread} {
+ set serverthread [thread::create -joinable -preserved]
+ thread::send -async $serverthread {after 1000 ; thread::release}
+ thread::join $serverthread
} {0}
-test thread-5.1 {Joining threads after the fact} {testthread} {
- threadReap
- set serverthread [testthread create -joinable]
- testthread send -async $serverthread {testthread exit}
+test thread-5.1 {Joining threads after the fact} {thread} {
+ set serverthread [thread::create -joinable -preserved]
+ thread::send -async $serverthread {thread::release}
after 2000
- set res [testthread join $serverthread]
- threadReap
- set res
+ thread::join $serverthread
} {0}
-test thread-5.2 {Try to join a detached thread} {testthread} {
- threadReap
- set serverthread [testthread create]
- testthread send -async $serverthread {after 1000 ; testthread exit}
- catch {set res [testthread join $serverthread]} msg
- threadReap
+test thread-5.2 {Try to join a detached thread} {thread} {
+ set serverthread [thread::create -preserved]
+ thread::send -async $serverthread {after 1000 ; thread::release}
+ catch {set res [thread::join $serverthread]} msg
+ while {[llength [thread::names]] > 1} {
+ after 20
+ }
lrange $msg 0 2
} {cannot join thread}
-test thread-6.1 {freeing very large object trees in a thread} testthread {
+test thread-6.1 {freeing very large object trees in a thread} thread {
# conceptual duplicate of obj-32.1
- threadReap
- set serverthread [testthread create -joinable]
- testthread send -async $serverthread {
+ set serverthread [thread::create -preserved]
+ thread::send -async $serverthread {
set x {}
for {set i 0} {$i<100000} {incr i} {
set x [list $x {}]
}
unset x
- testthread exit
}
- catch {set res [testthread join $serverthread]} msg
- threadReap
- set res
-} {0}
+ thread::release -wait $serverthread
+} 0
# TIP #285: Script cancellation support
-test thread-7.1 {cancel: args} {testthread} {
- set x [catch {testthread cancel} msg]
- list $x $msg
-} {1 {wrong # args: should be "testthread cancel ?-unwind? id ?result?"}}
-test thread-7.2 {cancel: nonint} {testthread} {
- set x [catch {testthread cancel abc} msg]
- list $x $msg
-} {1 {expected integer but got "abc"}}
-test thread-7.3 {cancel: bad id} {testthread} {
- set tid [expr $::tcltest::mainThread + 10]
- set x [catch {testthread cancel $tid} msg]
- list $x $msg
-} {1 {invalid thread id}}
-test thread-7.4 {cancel: pure bytecode loop} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+test thread-7.4 {cancel: pure bytecode loop} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
while {1} {
@@ -287,30 +264,30 @@ test thread-7.4 {cancel: pure bytecode loop} {testthread} {
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval canceled}}
-test thread-7.5 {cancel: pure inside-command loop} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.5 {cancel: pure inside-command loop} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
set while while
@@ -319,30 +296,30 @@ test thread-7.5 {cancel: pure inside-command loop} {testthread} {
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval canceled}}
-test thread-7.6 {cancel: pure bytecode loop -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.6 {cancel: pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
while {1} {
@@ -350,30 +327,30 @@ test thread-7.6 {cancel: pure bytecode loop -unwind} {testthread} {
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel -unwind $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval unwound}}
-test thread-7.7 {cancel: pure inside-command loop -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
- proc foobar {} {
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.7 {cancel: pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
set while while
@@ -382,30 +359,30 @@ test thread-7.7 {cancel: pure inside-command loop -unwind} {testthread} {
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel -unwind $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval unwound}}
-test thread-7.8 {cancel: pure bytecode loop custom result} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.8 {cancel: pure bytecode loop custom result} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
while {1} {
@@ -413,30 +390,33 @@ test thread-7.8 {cancel: pure bytecode loop custom result} {testthread} {
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel $serverthread "the eval was canceled"]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {the eval was canceled}}
-test thread-7.9 {cancel: pure inside-command loop custom result} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
- proc foobar {} {
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread "the eval was canceled"]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was canceled}}
+test thread-7.9 {cancel: pure inside-command loop custom result} -constraints {
+ thread
+ drainEventQueue
+} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
set while while
@@ -445,30 +425,33 @@ test thread-7.9 {cancel: pure inside-command loop custom result} {testthread} {
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel $serverthread "the eval was canceled"]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {the eval was canceled}}
-test thread-7.10 {cancel: pure bytecode loop custom result -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread "the eval was canceled"]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was canceled}}
+test thread-7.10 {cancel: pure bytecode loop custom result -unwind} -constraints {
+ thread
+ drainEventQueue
+} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
while {1} {
@@ -476,30 +459,33 @@ test thread-7.10 {cancel: pure bytecode loop custom result -unwind} {testthread}
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel -unwind $serverthread "the eval was unwound"]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {the eval was unwound}}
-test thread-7.11 {cancel: pure inside-command loop custom result -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
- proc foobar {} {
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread "the eval was unwound"]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was unwound}}
+test thread-7.11 {cancel: pure inside-command loop custom result -unwind} -constraints {
+ thread
+ drainEventQueue
+} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
set while while
@@ -508,383 +494,379 @@ test thread-7.11 {cancel: pure inside-command loop custom result -unwind} {testt
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel -unwind $serverthread "the eval was unwound"]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {the eval was unwound}}
-test thread-7.12 {cancel: after} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread "the eval was unwound"]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was unwound}}
+test thread-7.12 {cancel: after} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
after 30000
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval canceled}}
-test thread-7.13 {cancel: after -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.13 {cancel: after -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
after 30000
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel -unwind $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval unwound}}
-test thread-7.14 {cancel: vwait} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.14 {cancel: vwait} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID [thread::id]] {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
vwait forever
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval canceled}}
-test thread-7.15 {cancel: vwait -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.15 {cancel: vwait -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
vwait forever
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel -unwind $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval unwound}}
-test thread-7.16 {cancel: expr} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.16 {cancel: expr} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID [thread::id]] {
set i [interp create]
- interp alias $i testthread {} testthread
+ $i eval "package require -exact Thread [package present Thread]"
$i eval {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
expr {[while {1} {incr x}]}
}
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval canceled}}
-test thread-7.17 {cancel: expr -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.17 {cancel: expr -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
set i [interp create]
- interp alias $i testthread {} testthread
+ $i eval "package require -exact Thread [package present Thread]"
$i eval {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
expr {[while {1} {incr x}]}
}
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel -unwind $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval unwound}}
-test thread-7.18 {cancel: expr bignum} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
- set i [interp create]
- interp alias $i testthread {} testthread
- $i eval {
- if {![info exists foo]} then {
- # signal the primary thread that we are ready
- # to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
- set foo 1
- }
- #
- # TODO: This will not cancel because libtommath
- # does not check Tcl_Canceled.
- #
- expr {2**99999}
- }
- }]
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.18 {cancel: expr bignum} {thread drainEventQueue knownBug} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ #
+ # BUGBUG: This will not cancel because libtommath
+ # does not check Tcl_Canceled.
+ #
+ expr {2**99999}
+ }
+ }]]
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
- set res [testthread cancel $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread); # WARNING: Never returns (see above).
+ thread::join $serverthread; drainEventQueue; # WARNING: Never returns (see above).
list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
} {{} 1 0 {}}
-test thread-7.19 {cancel: expr bignum -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
- set i [interp create]
- interp alias $i testthread {} testthread
- $i eval {
- if {![info exists foo]} then {
- # signal the primary thread that we are ready
- # to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
- set foo 1
- }
- #
- # TODO: This will not cancel because libtommath
- # does not check Tcl_Canceled.
- #
- expr {2**99999}
- }
- }]
+test thread-7.19 {cancel: expr bignum -unwind} {thread drainEventQueue knownBug} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ #
+ # BUGBUG: This will not cancel because libtommath
+ # does not check Tcl_Canceled.
+ #
+ expr {2**99999}
+ }
+ }]]
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
- set res [testthread cancel -unwind $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread); # WARNING: Never returns (see above).
+ thread::join $serverthread; drainEventQueue; # WARNING: Never returns (see above).
list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
} {{} 1 0 {}}
-test thread-7.20 {cancel: subst} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+test thread-7.20 {cancel: subst} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
set i [interp create]
- interp alias $i testthread {} testthread
+ $i eval "package require -exact Thread [package present Thread]"
$i eval {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
subst {[while {1} {incr x}]}
}
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval canceled}}
-test thread-7.21 {cancel: subst -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.21 {cancel: subst -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
set i [interp create]
- interp alias $i testthread {} testthread
+ $i eval "package require -exact Thread [package present Thread]"
$i eval {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
subst {[while {1} {incr x}]}
}
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel -unwind $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval unwound}}
-test thread-7.22 {cancel: slave interp} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.22 {cancel: slave interp} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
set i [interp create]
- interp alias $i testthread {} testthread
+ $i eval "package require -exact Thread [package present Thread]"
$i eval {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
while {1} {}
}
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval canceled}}
-test thread-7.23 {cancel: slave interp -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.23 {cancel: slave interp -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
set i [interp create]
- interp alias $i testthread {} testthread
+ $i eval "package require -exact Thread [package present Thread]"
$i eval {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
set while while; $while {1} {}
}
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel -unwind $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval unwound}}
-test thread-7.24 {cancel: nested catch inside pure bytecode loop} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.24 {cancel: nested catch inside pure bytecode loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
while {1} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
catch {
@@ -901,25 +883,24 @@ test thread-7.24 {cancel: nested catch inside pure bytecode loop} {testthread} {
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
- set res [testthread cancel $serverthread]
- after 1000; # wait for ThreadErrorProc to be called.
- while {[testthread event]} {}; # force events to service
- catch {testthread send $serverthread {testthread exit}}
- threadReap
+ set res [thread::cancel $serverthread]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
$::threadIdStarted == $serverthread : 0}] \
[expr {[info exists ::threadId] ? \
$::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
} {{} 1 0 {}}
-test thread-7.25 {cancel: nested catch inside pure inside-command loop} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+test thread-7.25 {cancel: nested catch inside pure inside-command loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
set catch catch
set while while
@@ -927,8 +908,7 @@ test thread-7.25 {cancel: nested catch inside pure inside-command loop} {testthr
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
$catch {
@@ -945,61 +925,59 @@ test thread-7.25 {cancel: nested catch inside pure inside-command loop} {testthr
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
- set res [testthread cancel $serverthread]
- after 1000; # wait for ThreadErrorProc to be called.
- while {[testthread event]} {}; # force events to service
- catch {testthread send $serverthread {testthread exit}}
- threadReap
+ set res [thread::cancel $serverthread]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
$::threadIdStarted == $serverthread : 0}] \
[expr {[info exists ::threadId] ? \
$::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
} {{} 1 0 {}}
-test thread-7.26 {cancel: send async cancel bad interp path} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+test thread-7.26 {cancel: send async cancel bad interp path} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
while {1} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
update
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- catch {testthread send $serverthread {interp cancel -- bad}} msg
- threadReap
- list [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- $msg
+ vwait ::threadIdStarted
+ catch {thread::send $serverthread {interp cancel -- bad}} msg
+ thread::send -async $serverthread {interp cancel -unwind}
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list [expr {$::threadIdStarted == $serverthread}] $msg
} {1 {could not find interpreter "bad"}}
-test thread-7.27 {cancel: send async cancel -- switch} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
- interp create -- -unwind
- interp alias -unwind testthread {} testthread
- interp eval -unwind {
+test thread-7.27 {cancel: send async cancel -- switch} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create -- -unwind]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
proc foobar {} {
while {1} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
update
@@ -1007,31 +985,30 @@ test thread-7.27 {cancel: send async cancel -- switch} {testthread} {
}
foobar
}
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread send -async $serverthread {interp cancel -- -unwind}]
- after 1000; # wait for ThreadErrorProc to be called.
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval canceled}}
-test thread-7.28 {cancel: send async cancel nested catch inside pure bytecode loop} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {interp cancel -- -unwind}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.28 {cancel: send async cancel nested catch inside pure bytecode loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
while {1} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
catch {
@@ -1048,25 +1025,24 @@ test thread-7.28 {cancel: send async cancel nested catch inside pure bytecode lo
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
- set res [testthread send -async $serverthread {interp cancel}]
- after 1000; # wait for ThreadErrorProc to be called.
- while {[testthread event]} {}; # force events to service
- catch {testthread send $serverthread {testthread exit}}
- threadReap
+ set res [thread::send -async $serverthread {interp cancel}]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
$::threadIdStarted == $serverthread : 0}] \
[expr {[info exists ::threadId] ? \
$::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 0 {}}
-test thread-7.29 {cancel: send async cancel nested catch pure inside-command loop} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.29 {cancel: send async cancel nested catch pure inside-command loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
set catch catch
set while while
@@ -1074,8 +1050,7 @@ test thread-7.29 {cancel: send async cancel nested catch pure inside-command loo
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
$catch {
@@ -1092,32 +1067,30 @@ test thread-7.29 {cancel: send async cancel nested catch pure inside-command loo
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
- set res [testthread send -async $serverthread {interp cancel}]
- after 1000; # wait for ThreadErrorProc to be called.
- while {[testthread event]} {}; # force events to service
- catch {testthread send $serverthread {testthread exit}}
- threadReap
+ set res [thread::send -async $serverthread {interp cancel}]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
$::threadIdStarted == $serverthread : 0}] \
[expr {[info exists ::threadId] ? \
$::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 0 {}}
-test thread-7.30 {cancel: send async testthread cancel nested catch inside pure bytecode loop} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.30 {cancel: send async thread cancel nested catch inside pure bytecode loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
while {1} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
catch {
@@ -1134,25 +1107,24 @@ test thread-7.30 {cancel: send async testthread cancel nested catch inside pure
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
- set res [testthread send -async $serverthread {testthread cancel [testthread id]}]
- after 1000; # wait for ThreadErrorProc to be called.
- while {[testthread event]} {}; # force events to service
- catch {testthread send $serverthread {testthread exit}}
- threadReap
+ set res [thread::send -async $serverthread {thread::cancel [thread::id]}]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
$::threadIdStarted == $serverthread : 0}] \
[expr {[info exists ::threadId] ? \
$::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 0 {}}
-test thread-7.31 {cancel: send async testthread cancel nested catch pure inside-command loop} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.31 {cancel: send async thread cancel nested catch pure inside-command loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
set catch catch
set while while
@@ -1160,8 +1132,7 @@ test thread-7.31 {cancel: send async testthread cancel nested catch pure inside-
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
$catch {
@@ -1178,32 +1149,31 @@ test thread-7.31 {cancel: send async testthread cancel nested catch pure inside-
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
- set res [testthread send -async $serverthread {testthread cancel [testthread id]}]
- after 1000; # wait for ThreadErrorProc to be called.
- while {[testthread event]} {}; # force events to service
- catch {testthread send $serverthread {testthread exit}}
- threadReap
+ set res [thread::send -async $serverthread {thread::cancel [thread::id]}]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
$::threadIdStarted == $serverthread : 0}] \
[expr {[info exists ::threadId] ? \
$::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 0 {}}
-test thread-7.32 {cancel: nested catch inside pure bytecode loop -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.32 {cancel: nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
while {1} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
catch {
@@ -1218,24 +1188,25 @@ test thread-7.32 {cancel: nested catch inside pure bytecode loop -unwind} {testt
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel -unwind $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval unwound}}
-test thread-7.33 {cancel: nested catch inside pure inside-command loop -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.33 {cancel: nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
set catch catch
set while while
@@ -1243,8 +1214,7 @@ test thread-7.33 {cancel: nested catch inside pure inside-command loop -unwind}
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
$catch {
@@ -1259,31 +1229,31 @@ test thread-7.33 {cancel: nested catch inside pure inside-command loop -unwind}
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread cancel -unwind $serverthread]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval unwound}}
-test thread-7.34 {cancel: send async cancel nested catch inside pure bytecode loop -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.34 {cancel: send async cancel nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
while {1} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
catch {
@@ -1300,24 +1270,25 @@ test thread-7.34 {cancel: send async cancel nested catch inside pure bytecode lo
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread send -async $serverthread {interp cancel -unwind}]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval unwound}}
-test thread-7.35 {cancel: send async cancel nested catch inside pure inside-command loop -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {interp cancel -unwind}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.35 {cancel: send async cancel nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
set catch catch
set while while
@@ -1325,8 +1296,7 @@ test thread-7.35 {cancel: send async cancel nested catch inside pure inside-comm
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
$catch {
@@ -1343,31 +1313,31 @@ test thread-7.35 {cancel: send async cancel nested catch inside pure inside-comm
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread send -async $serverthread {interp cancel -unwind}]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval unwound}}
-test thread-7.36 {cancel: send async testthread cancel nested catch inside pure bytecode loop -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {interp cancel -unwind}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.36 {cancel: send async thread cancel nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
proc foobar {} {
while {1} {
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
catch {
@@ -1384,24 +1354,25 @@ test thread-7.36 {cancel: send async testthread cancel nested catch inside pure
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread send -async $serverthread {testthread cancel -unwind [testthread id]}]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval unwound}}
-test thread-7.37 {cancel: send async testthread cancel nested catch inside pure inside-command loop -unwind} {testthread} {
- threadReap
- unset -nocomplain ::threadError ::threadId ::threadIdStarted
- set serverthread [testthread create -joinable {
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {thread::cancel -unwind [thread::id]}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.37 {cancel: send async thread cancel nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID [thread::id]] {
proc foobar {} {
set catch catch
set while while
@@ -1409,8 +1380,7 @@ test thread-7.37 {cancel: send async testthread cancel nested catch inside pure
if {![info exists foo]} then {
# signal the primary thread that we are ready
# to be canceled now (we are running).
- testthread send [testthread id -main] \
- [list set ::threadIdStarted [testthread id]]
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
set foo 1
}
$catch {
@@ -1427,20 +1397,20 @@ test thread-7.37 {cancel: send async testthread cancel nested catch inside pure
}
}
foobar
- }]
+ }]]
# wait for other thread to signal "ready to cancel"
- vwait ::threadIdStarted; after 1000
- set res [testthread send -async $serverthread {testthread cancel -unwind [testthread id]}]
- testthread join $serverthread
- while {[testthread event]} {}; # force events to service
- threadReap
- list $res [expr {[info exists ::threadIdStarted] ? \
- $::threadIdStarted == $serverthread : 0}] \
- [expr {[info exists ::threadId] ? \
- $::threadId == $serverthread : 0}] \
- [expr {[info exists ::threadError] ? \
- [lindex [split $::threadError \n] 0] : "" }]
-} {{} 1 1 {eval unwound}}
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {thread::cancel -unwind [thread::id]}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
# cleanup
::tcltest::cleanupTests
diff --git a/tests/tm.test b/tests/tm.test
index 149a65d..1b22f8c 100644
--- a/tests/tm.test
+++ b/tests/tm.test
@@ -200,7 +200,7 @@ test tm-3.11 {tm: module path management, remove ignores unknown path} -setup {
proc genpaths {base} {
# Normalizing picks up drive letters on windows [Bug 1053568]
set base [file normalize $base]
- foreach {major minor} [split [info tclversion] .] break
+ lassign [split [package present Tcl] .] major minor
set results {}
set base [file join $base tcl$major]
lappend results [file join $base site-tcl]
diff --git a/tests/trace.test b/tests/trace.test
index 5767860..d830f3c 100644
--- a/tests/trace.test
+++ b/tests/trace.test
@@ -11,10 +11,11 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest
- namespace import -force ::tcltest::*
-}
+package require tcltest
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
testConstraint testcmdtrace [llength [info commands testcmdtrace]]
testConstraint testevalobjv [llength [info commands testevalobjv]]
@@ -29,15 +30,15 @@ proc getbytes {} {
proc traceScalar {name1 name2 op} {
global info
- set info [list $name1 $name2 $op [catch {uplevel set $name1} msg] $msg]
+ set info [list $name1 $name2 $op [catch {uplevel 1 set $name1} msg] $msg]
}
proc traceScalarAppend {name1 name2 op} {
global info
- lappend info $name1 $name2 $op [catch {uplevel set $name1} msg] $msg
+ lappend info $name1 $name2 $op [catch {uplevel 1 set $name1} msg] $msg
}
proc traceArray {name1 name2 op} {
global info
- set info [list $name1 $name2 $op [catch {uplevel set [set name1]($name2)} msg] $msg]
+ set info [list $name1 $name2 $op [catch {uplevel 1 set [set name1]($name2)} msg] $msg]
}
proc traceArray2 {name1 name2 op} {
global info
@@ -59,7 +60,7 @@ proc traceCheck {cmd args} {
set info [list [catch $cmd msg] $msg]
}
proc traceCrtElement {value name1 name2 op} {
- uplevel set ${name1}($name2) $value
+ uplevel 1 set ${name1}($name2) $value
}
proc traceCommand {oldName newName op} {
global info
@@ -69,10 +70,10 @@ proc traceCommand {oldName newName op} {
test trace-0.0 {memory corruption in trace (Tcl Bug 484339)} {
# You may need Purify or Electric Fence to reliably
# see this one fail.
- catch {unset z}
+ unset -nocomplain z
trace add variable z array {set z(foo) 1 ;#}
set res "names: [array names z]"
- catch {unset ::z}
+ unset -nocomplain ::z
trace variable ::z w {unset ::z; error "memory corruption";#}
list [catch {set ::z 1} msg] $msg
} {1 {can't set "::z": memory corruption}}
@@ -80,40 +81,40 @@ test trace-0.0 {memory corruption in trace (Tcl Bug 484339)} {
# Read-tracing on variables
test trace-1.1 {trace variable reads} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x read traceScalar
list [catch {set x} msg] $msg $info
} {1 {can't read "x": no such variable} {x {} read 1 {can't read "x": no such variable}}}
test trace-1.2 {trace variable reads} {
- catch {unset x}
+ unset -nocomplain x
set x 123
set info {}
trace add variable x read traceScalar
list [catch {set x} msg] $msg $info
} {0 123 {x {} read 0 123}}
test trace-1.3 {trace variable reads} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x read traceScalar
set x 123
set info
} {}
test trace-1.4 {trace array element reads} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x(2) read traceArray
list [catch {set x(2)} msg] $msg $info
} {1 {can't read "x(2)": no such element in array} {x 2 read 1 {can't read "x(2)": no such element in array}}}
test trace-1.5 {trace array element reads} {
- catch {unset x}
+ unset -nocomplain x
set x(2) zzz
set info {}
trace add variable x(2) read traceArray
list [catch {set x(2)} msg] $msg $info
} {0 zzz {x 2 read 0 zzz}}
test trace-1.6 {trace array element reads} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x read traceArray2
proc p {} {
@@ -124,7 +125,7 @@ test trace-1.6 {trace array element reads} {
list [catch {p} msg] $msg $info
} {0 willi {x 2 read}}
test trace-1.7 {trace array element reads, create element undefined if nonexistant} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x read q
proc q {name1 name2 op} {
@@ -141,20 +142,20 @@ test trace-1.7 {trace array element reads, create element undefined if nonexista
list [catch {p} msg] $msg $info
} {0 wolf {x Y read}}
test trace-1.8 {trace reads on whole arrays} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x read traceArray
list [catch {set x(2)} msg] $msg $info
} {1 {can't read "x(2)": no such variable} {}}
test trace-1.9 {trace reads on whole arrays} {
- catch {unset x}
+ unset -nocomplain x
set x(2) zzz
set info {}
trace add variable x read traceArray
list [catch {set x(2)} msg] $msg $info
} {0 zzz {x 2 read 0 zzz}}
test trace-1.10 {trace variable reads} {
- catch {unset x}
+ unset -nocomplain x
set x 444
set info {}
trace add variable x read traceScalar
@@ -162,28 +163,28 @@ test trace-1.10 {trace variable reads} {
set info
} {}
test trace-1.11 {read traces that modify the array structure} {
- catch {unset x}
+ unset -nocomplain x
set x(bar) 0
trace variable x r {set x(foo) 1 ;#}
trace variable x r {unset -nocomplain x(bar) ;#}
array get x
} {}
test trace-1.12 {read traces that modify the array structure} {
- catch {unset x}
+ unset -nocomplain x
set x(bar) 0
trace variable x r {unset -nocomplain x(bar) ;#}
trace variable x r {set x(foo) 1 ;#}
array get x
} {}
test trace-1.13 {read traces that modify the array structure} {
- catch {unset x}
+ unset -nocomplain x
set x(bar) 0
trace variable x r {set x(foo) 1 ;#}
trace variable x r {unset -nocomplain x;#}
list [catch {array get x} res] $res
} {1 {can't read "x(bar)": no such variable}}
test trace-1.14 {read traces that modify the array structure} {
- catch {unset x}
+ unset -nocomplain x
set x(bar) 0
trace variable x r {unset -nocomplain x;#}
trace variable x r {set x(foo) 1 ;#}
@@ -193,28 +194,28 @@ test trace-1.14 {read traces that modify the array structure} {
# Basic write-tracing on variables
test trace-2.1 {trace variable writes} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x write traceScalar
set x 123
set info
} {x {} write 0 123}
test trace-2.2 {trace writes to array elements} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x(33) write traceArray
set x(33) 444
set info
} {x 33 write 0 444}
test trace-2.3 {trace writes on whole arrays} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x write traceArray
set x(abc) qq
set info
} {x abc write 0 qq}
test trace-2.4 {trace variable writes} {
- catch {unset x}
+ unset -nocomplain x
set x 1234
set info {}
trace add variable x write traceScalar
@@ -222,7 +223,7 @@ test trace-2.4 {trace variable writes} {
set info
} {}
test trace-2.5 {trace variable writes} {
- catch {unset x}
+ unset -nocomplain x
set x 1234
set info {}
trace add variable x write traceScalar
@@ -235,7 +236,7 @@ test trace-2.6 {trace variable writes on compiled local} {
# arrays [Bug 1770591]. The corresponding function for read traces is
# already indirectly tested in trace-1.7
#
- catch {unset x}
+ unset -nocomplain x
set info {}
proc p {} {
trace add variable x write traceArray
@@ -264,7 +265,7 @@ test trace-2.7 {trace variable writes on errorInfo} -body {
# trace: after appending all arguments to the list.
test trace-3.1 {trace variable read-modify-writes} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x read traceScalarAppend
append x 123
@@ -273,7 +274,7 @@ test trace-3.1 {trace variable read-modify-writes} {
set info
} {x {} read 0 123456}
test trace-3.2 {trace variable read-modify-writes} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x {read write} traceScalarAppend
append x 123
@@ -284,14 +285,14 @@ test trace-3.2 {trace variable read-modify-writes} {
# Basic unset-tracing on variables
test trace-4.1 {trace variable unsets} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x unset traceScalar
- catch {unset x}
+ unset -nocomplain x
set info
} {x {} unset 1 {can't read "x": no such variable}}
test trace-4.2 {variable mustn't exist during unset trace} {
- catch {unset x}
+ unset -nocomplain x
set x 1234
set info {}
trace add variable x unset traceScalar
@@ -299,7 +300,7 @@ test trace-4.2 {variable mustn't exist during unset trace} {
set info
} {x {} unset 1 {can't read "x": no such variable}}
test trace-4.3 {unset traces mustn't be called during reads and writes} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x unset traceScalar
set x 44
@@ -307,15 +308,15 @@ test trace-4.3 {unset traces mustn't be called during reads and writes} {
set info
} {}
test trace-4.4 {trace unsets on array elements} {
- catch {unset x}
+ unset -nocomplain x
set x(0) 18
set info {}
trace add variable x(1) unset traceArray
- catch {unset x(1)}
+ unset -nocomplain x(1)
set info
} {x 1 unset 1 {can't read "x(1)": no such element in array}}
test trace-4.5 {trace unsets on array elements} {
- catch {unset x}
+ unset -nocomplain x
set x(1) 18
set info {}
trace add variable x(1) unset traceArray
@@ -323,7 +324,7 @@ test trace-4.5 {trace unsets on array elements} {
set info
} {x 1 unset 1 {can't read "x(1)": no such element in array}}
test trace-4.6 {trace unsets on array elements} {
- catch {unset x}
+ unset -nocomplain x
set x(1) 18
set info {}
trace add variable x(1) unset traceArray
@@ -331,15 +332,15 @@ test trace-4.6 {trace unsets on array elements} {
set info
} {x 1 unset 1 {can't read "x(1)": no such variable}}
test trace-4.7 {trace unsets on whole arrays} {
- catch {unset x}
+ unset -nocomplain x
set x(1) 18
set info {}
trace add variable x unset traceProc
- catch {unset x(0)}
+ unset -nocomplain x(0)
set info
} {}
test trace-4.8 {trace unsets on whole arrays} {
- catch {unset x}
+ unset -nocomplain x
set x(1) 18
set x(2) 144
set x(3) 14
@@ -349,7 +350,7 @@ test trace-4.8 {trace unsets on whole arrays} {
set info
} {x 1 unset}
test trace-4.9 {trace unsets on whole arrays} {
- catch {unset x}
+ unset -nocomplain x
set x(1) 18
set x(2) 144
set x(3) 14
@@ -361,7 +362,7 @@ test trace-4.9 {trace unsets on whole arrays} {
# Array tracing on variables
test trace-5.1 {array traces fire on accesses via [array]} {
- catch {unset x}
+ unset -nocomplain x
set x(b) 2
trace add variable x array traceArray2
set ::info {}
@@ -369,7 +370,7 @@ test trace-5.1 {array traces fire on accesses via [array]} {
set ::info
} {x {} array}
test trace-5.2 {array traces do not fire on normal accesses} {
- catch {unset x}
+ unset -nocomplain x
set x(b) 2
trace add variable x array traceArray2
set ::info {}
@@ -378,7 +379,7 @@ test trace-5.2 {array traces do not fire on normal accesses} {
set ::info
} {}
test trace-5.3 {array traces do not outlive variable} {
- catch {unset x}
+ unset -nocomplain x
trace add variable x array traceArray2
set ::info {}
set x(a) 1
@@ -387,19 +388,19 @@ test trace-5.3 {array traces do not outlive variable} {
set ::info
} {}
test trace-5.4 {array traces properly listed in trace information} {
- catch {unset x}
+ unset -nocomplain x
trace add variable x array traceArray2
set result [trace info variable x]
set result
} [list [list array traceArray2]]
test trace-5.5 {array traces properly listed in trace information} {
- catch {unset x}
+ unset -nocomplain x
trace variable x a traceArray2
set result [trace vinfo x]
set result
} [list [list a traceArray2]]
test trace-5.6 {array traces don't fire on scalar variables} {
- catch {unset x}
+ unset -nocomplain x
set x foo
trace add variable x array traceArray2
set ::info {}
@@ -407,14 +408,14 @@ test trace-5.6 {array traces don't fire on scalar variables} {
set ::info
} {}
test trace-5.7 {array traces fire for undefined variables} {
- catch {unset x}
+ unset -nocomplain x
trace add variable x array traceArray2
set ::info {}
array set x {a 1}
set ::info
} {x {} array}
test trace-5.8 {array traces fire for undefined variables} {
- catch {unset x}
+ unset -nocomplain x
trace add variable x array {set x(foo) 1 ;#}
set res "names: [array names x]"
} {names: foo}
@@ -422,7 +423,7 @@ test trace-5.8 {array traces fire for undefined variables} {
# Trace multiple trace types at once.
test trace-6.1 {multiple ops traced at once} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x {read write unset} traceProc
catch {set x}
@@ -433,7 +434,7 @@ test trace-6.1 {multiple ops traced at once} {
set info
} {x {} read x {} write x {} read x {} write x {} unset}
test trace-6.2 {multiple ops traced on array element} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x(0) {read write unset} traceProc
catch {set x(0)}
@@ -445,7 +446,7 @@ test trace-6.2 {multiple ops traced on array element} {
set info
} {x 0 read x 0 write x 0 read x 0 write x 0 unset}
test trace-6.3 {multiple ops traced on whole array} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x {read write unset} traceProc
catch {set x(0)}
@@ -460,7 +461,7 @@ test trace-6.3 {multiple ops traced on whole array} {
# Check order of invocation of traces
test trace-7.1 {order of invocation of traces} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x read "traceTag 1"
trace add variable x read "traceTag 2"
@@ -471,7 +472,7 @@ test trace-7.1 {order of invocation of traces} {
set info
} {3 2 1 3 2 1}
test trace-7.2 {order of invocation of traces} {
- catch {unset x}
+ unset -nocomplain x
set x(0) 44
set info {}
trace add variable x(0) read "traceTag 1"
@@ -481,7 +482,7 @@ test trace-7.2 {order of invocation of traces} {
set info
} {3 2 1}
test trace-7.3 {order of invocation of traces} {
- catch {unset x}
+ unset -nocomplain x
set x(0) 44
set info {}
trace add variable x(0) read "traceTag 1"
@@ -497,7 +498,7 @@ test trace-7.3 {order of invocation of traces} {
# Check effects of errors in trace procedures
test trace-8.1 {error returns from traces} {
- catch {unset x}
+ unset -nocomplain x
set x 123
set info {}
trace add variable x read "traceTag 1"
@@ -505,7 +506,7 @@ test trace-8.1 {error returns from traces} {
list [catch {set x} msg] $msg $info
} {1 {can't read "x": trace returned error} {}}
test trace-8.2 {error returns from traces} {
- catch {unset x}
+ unset -nocomplain x
set x 123
set info {}
trace add variable x write "traceTag 1"
@@ -513,14 +514,14 @@ test trace-8.2 {error returns from traces} {
list [catch {set x 44} msg] $msg $info
} {1 {can't set "x": trace returned error} {}}
test trace-8.3 {error returns from traces} {
- catch {unset x}
+ unset -nocomplain x
set x 123
set info {}
trace add variable x write traceError
list [catch {append x 44} msg] $msg $info
} {1 {can't set "x": trace returned error} {}}
test trace-8.4 {error returns from traces} {
- catch {unset x}
+ unset -nocomplain x
set x 123
set info {}
trace add variable x unset "traceTag 1"
@@ -528,7 +529,7 @@ test trace-8.4 {error returns from traces} {
list [catch {unset x} msg] $msg $info
} {0 {} 1}
test trace-8.5 {error returns from traces} {
- catch {unset x}
+ unset -nocomplain x
set x(0) 123
set info {}
trace add variable x(0) read "traceTag 1"
@@ -538,7 +539,7 @@ test trace-8.5 {error returns from traces} {
list [catch {set x(0)} msg] $msg $info
} {1 {can't read "x(0)": trace returned error} 3}
test trace-8.6 {error returns from traces} {
- catch {unset x}
+ unset -nocomplain x
set x 123
trace add variable x unset traceError
list [catch {unset x} msg] $msg
@@ -547,7 +548,7 @@ test trace-8.7 {error returns from traces} {
# This test just makes sure that the memory for the error message
# gets deallocated correctly when the trace is invoked again or
# when the trace is deleted.
- catch {unset x}
+ unset -nocomplain x
set x 123
trace add variable x read traceError
catch {set x}
@@ -568,7 +569,7 @@ test trace-8.8 {error returns from traces} {
trace add variable ::x write [list foo $::x]
error "foo"
}
- catch {unset ::x ::y}
+ unset -nocomplain ::x ::y
set x junk
trace add variable ::x write [list foo $x]
for {set y 0} {$y<100} {incr y} {
@@ -582,31 +583,31 @@ test trace-8.8 {error returns from traces} {
# a new copy of the variables.
test trace-9.1 {be sure variable is unset before trace is called} {
- catch {unset x}
+ unset -nocomplain x
set x 33
set info {}
- trace add variable x unset {traceCheck {uplevel set x}}
+ trace add variable x unset {traceCheck {uplevel 1 set x}}
unset x
set info
} {1 {can't read "x": no such variable}}
test trace-9.2 {be sure variable is unset before trace is called} {
- catch {unset x}
+ unset -nocomplain x
set x 33
set info {}
- trace add variable x unset {traceCheck {uplevel set x 22}}
+ trace add variable x unset {traceCheck {uplevel 1 set x 22}}
unset x
concat $info [list [catch {set x} msg] $msg]
} {0 22 0 22}
test trace-9.3 {be sure traces are cleared before unset trace called} {
- catch {unset x}
+ unset -nocomplain x
set x 33
set info {}
- trace add variable x unset {traceCheck {uplevel trace info variable x}}
+ trace add variable x unset {traceCheck {uplevel 1 trace info variable x}}
unset x
set info
} {0 {}}
test trace-9.4 {set new trace during unset trace} {
- catch {unset x}
+ unset -nocomplain x
set x 33
set info {}
trace add variable x unset {traceCheck {global x; trace add variable x unset traceProc}}
@@ -615,23 +616,23 @@ test trace-9.4 {set new trace during unset trace} {
} {0 {} {unset traceProc}}
test trace-10.1 {make sure array elements are unset before traces are called} {
- catch {unset x}
+ unset -nocomplain x
set x(0) 33
set info {}
- trace add variable x(0) unset {traceCheck {uplevel set x(0)}}
+ trace add variable x(0) unset {traceCheck {uplevel 1 set x(0)}}
unset x(0)
set info
} {1 {can't read "x(0)": no such element in array}}
test trace-10.2 {make sure array elements are unset before traces are called} {
- catch {unset x}
+ unset -nocomplain x
set x(0) 33
set info {}
- trace add variable x(0) unset {traceCheck {uplevel set x(0) zzz}}
+ trace add variable x(0) unset {traceCheck {uplevel 1 set x(0) zzz}}
unset x(0)
concat $info [list [catch {set x(0)} msg] $msg]
} {0 zzz 0 zzz}
test trace-10.3 {array elements are unset before traces are called} {
- catch {unset x}
+ unset -nocomplain x
set x(0) 33
set info {}
trace add variable x(0) unset {traceCheck {global x; trace info variable x(0)}}
@@ -639,49 +640,49 @@ test trace-10.3 {array elements are unset before traces are called} {
set info
} {0 {}}
test trace-10.4 {set new array element trace during unset trace} {
- catch {unset x}
+ unset -nocomplain x
set x(0) 33
set info {}
- trace add variable x(0) unset {traceCheck {uplevel {trace add variable x(0) read {}}}}
- catch {unset x(0)}
+ trace add variable x(0) unset {traceCheck {uplevel 1 {trace add variable x(0) read {}}}}
+ unset -nocomplain x(0)
concat $info [trace info variable x(0)]
} {0 {} {read {}}}
test trace-11.1 {make sure arrays are unset before traces are called} {
- catch {unset x}
+ unset -nocomplain x
set x(0) 33
set info {}
- trace add variable x unset {traceCheck {uplevel set x(0)}}
+ trace add variable x unset {traceCheck {uplevel 1 set x(0)}}
unset x
set info
} {1 {can't read "x(0)": no such variable}}
test trace-11.2 {make sure arrays are unset before traces are called} {
- catch {unset x}
+ unset -nocomplain x
set x(y) 33
set info {}
- trace add variable x unset {traceCheck {uplevel set x(y) 22}}
+ trace add variable x unset {traceCheck {uplevel 1 set x(y) 22}}
unset x
concat $info [list [catch {set x(y)} msg] $msg]
} {0 22 0 22}
test trace-11.3 {make sure arrays are unset before traces are called} {
- catch {unset x}
+ unset -nocomplain x
set x(y) 33
set info {}
- trace add variable x unset {traceCheck {uplevel array exists x}}
+ trace add variable x unset {traceCheck {uplevel 1 array exists x}}
unset x
set info
} {0 0}
test trace-11.4 {make sure arrays are unset before traces are called} {
- catch {unset x}
+ unset -nocomplain x
set x(y) 33
set info {}
- set cmd {traceCheck {uplevel {trace info variable x}}}
+ set cmd {traceCheck {uplevel 1 {trace info variable x}}}
trace add variable x unset $cmd
unset x
set info
} {0 {}}
test trace-11.5 {set new array trace during unset trace} {
- catch {unset x}
+ unset -nocomplain x
set x(y) 33
set info {}
trace add variable x unset {traceCheck {global x; trace add variable x read {}}}
@@ -689,7 +690,7 @@ test trace-11.5 {set new array trace during unset trace} {
concat $info [trace info variable x]
} {0 {} {read {}}}
test trace-11.6 {create scalar during array unset trace} {
- catch {unset x}
+ unset -nocomplain x
set x(y) 33
set info {}
trace add variable x unset {traceCheck {global x; set x 44}}
@@ -700,52 +701,52 @@ test trace-11.6 {create scalar during array unset trace} {
# Check special conditions (e.g. errors) in Tcl_TraceVar2.
test trace-12.1 {creating array when setting variable traces} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x(0) write traceProc
list [catch {set x 22} msg] $msg
} {1 {can't set "x": variable is array}}
test trace-12.2 {creating array when setting variable traces} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x(0) write traceProc
list [catch {set x(0)} msg] $msg
} {1 {can't read "x(0)": no such element in array}}
test trace-12.3 {creating array when setting variable traces} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x(0) write traceProc
set x(0) 22
set info
} {x 0 write}
test trace-12.4 {creating variable when setting variable traces} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x write traceProc
list [catch {set x} msg] $msg
} {1 {can't read "x": no such variable}}
test trace-12.5 {creating variable when setting variable traces} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x write traceProc
set x 22
set info
} {x {} write}
test trace-12.6 {creating variable when setting variable traces} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x write traceProc
set x(0) 22
set info
} {x 0 write}
test trace-12.7 {create array element during read trace} {
- catch {unset x}
+ unset -nocomplain x
set x(2) zzz
trace add variable x read {traceCrtElement xyzzy}
list [catch {set x(3)} msg] $msg
} {0 xyzzy}
test trace-12.8 {errors when setting variable traces} {
- catch {unset x}
+ unset -nocomplain x
set x 44
list [catch {trace add variable x(0) write traceProc} msg] $msg
} {1 {can't trace "x(0)": variable isn't array}}
@@ -759,7 +760,7 @@ test trace-13.1 {delete one trace from another} {
trace remove variable x read {traceTag 3}
trace remove variable x read {traceTag 4}
}
- catch {unset x}
+ unset -nocomplain x
set x 44
set info {}
trace add variable x read {traceTag 1}
@@ -913,13 +914,13 @@ test trace-14.11 {trace command, "trace variable" errors} {
test trace-14.12 {trace command ("remove variable" option)} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x write traceProc
trace remove variable x write traceProc
} {}
test trace-14.13 {trace command ("remove variable" option)} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x write traceProc
trace remove variable x write traceProc
@@ -927,7 +928,7 @@ test trace-14.13 {trace command ("remove variable" option)} {
set info
} {}
test trace-14.14 {trace command ("remove variable" option)} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x write {traceTag 1}
trace add variable x write traceProc
@@ -942,7 +943,7 @@ test trace-14.14 {trace command ("remove variable" option)} {
set info
} {2 x {} write 1 2 1 2}
test trace-14.15 {trace command ("remove variable" option)} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x write {traceTag 1}
trace remove variable x write non_existent
@@ -950,27 +951,27 @@ test trace-14.15 {trace command ("remove variable" option)} {
set info
} {1}
test trace-14.16 {trace command ("info variable" option)} {
- catch {unset x}
+ unset -nocomplain x
trace add variable x write {traceTag 1}
trace add variable x write traceProc
trace add variable x write {traceTag 2}
trace info variable x
} {{write {traceTag 2}} {write traceProc} {write {traceTag 1}}}
test trace-14.17 {trace command ("info variable" option)} {
- catch {unset x}
+ unset -nocomplain x
trace info variable x
} {}
test trace-14.18 {trace command ("info variable" option)} {
- catch {unset x}
+ unset -nocomplain x
trace info variable x(0)
} {}
test trace-14.19 {trace command ("info variable" option)} {
- catch {unset x}
+ unset -nocomplain x
set x 44
trace info variable x(0)
} {}
test trace-14.20 {trace command ("info variable" option)} {
- catch {unset x}
+ unset -nocomplain x
set x 44
trace add variable x write {traceTag 1}
proc check {} {global x; trace info variable x}
@@ -980,7 +981,7 @@ test trace-14.20 {trace command ("info variable" option)} {
# Check fancy trace commands (long ones, weird arguments, etc.)
test trace-15.1 {long trace command} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x write {traceTag {This is a very very long argument. It's \
designed to test out the facilities of TraceVarProc for dealing \
@@ -998,14 +999,14 @@ test trace-15.2 {long trace command result to ignore} {
proc longResult {args} {return "quite a bit of text, designed to
generate a core leak if this command file is invoked over and over again
and memory isn't being recycled correctly"}
- catch {unset x}
+ unset -nocomplain x
trace add variable x write longResult
set x 44
set x 5
set x abcde
} abcde
test trace-15.3 {special list-handling in trace commands} {
- catch {unset "x y z"}
+ unset -nocomplain "x y z"
set "x y z(a\n\{)" 44
set info {}
trace add variable "x y z(a\n\{)" write traceProc
@@ -1017,18 +1018,18 @@ test trace-15.3 {special list-handling in trace commands} {
proc traceUnset {unsetName args} {
global info
- upvar $unsetName x
+ upvar 1 $unsetName x
lappend info [catch {unset x} msg] $msg [catch {set x} msg] $msg
}
proc traceReset {unsetName resetName args} {
global info
- upvar $unsetName x $resetName y
+ upvar 1 $unsetName x $resetName y
lappend info [catch {unset x} msg] $msg [catch {set y xyzzy} msg] $msg
}
proc traceReset2 {unsetName resetName args} {
global info
- lappend info [catch {uplevel unset $unsetName} msg] $msg \
- [catch {uplevel set $resetName xyzzy} msg] $msg
+ lappend info [catch {uplevel 1 unset $unsetName} msg] $msg \
+ [catch {uplevel 1 set $resetName xyzzy} msg] $msg
}
proc traceAppend {string name1 name2 op} {
global info
@@ -1036,7 +1037,7 @@ proc traceAppend {string name1 name2 op} {
}
test trace-16.1 {unsets during read traces} {
- catch {unset y}
+ unset -nocomplain y
set y 1234
set info {}
trace add variable y read {traceUnset y}
@@ -1044,49 +1045,49 @@ test trace-16.1 {unsets during read traces} {
lappend info [catch {set y} msg] $msg
} {unset 0 {} 1 {can't read "x": no such variable} 1 {can't read "y": no such variable}}
test trace-16.2 {unsets during read traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) read {traceUnset y(0)}
lappend info [catch {set y(0)} msg] $msg
} {0 {} 1 {can't read "x": no such variable} 1 {can't read "y(0)": no such element in array}}
test trace-16.3 {unsets during read traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) read {traceUnset y}
lappend info [catch {set y(0)} msg] $msg
} {0 {} 1 {can't read "x": no such variable} 1 {can't read "y(0)": no such variable}}
test trace-16.4 {unsets during read traces} {
- catch {unset y}
+ unset -nocomplain y
set y 1234
set info {}
trace add variable y read {traceReset y y}
lappend info [catch {set y} msg] $msg
} {0 {} 0 xyzzy 0 xyzzy}
test trace-16.5 {unsets during read traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) read {traceReset y(0) y(0)}
lappend info [catch {set y(0)} msg] $msg
} {0 {} 0 xyzzy 0 xyzzy}
test trace-16.6 {unsets during read traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) read {traceReset y y(0)}
lappend info [catch {set y(0)} msg] $msg [catch {set y(0)} msg] $msg
} {0 {} 1 {can't set "y": upvar refers to element in deleted array} 1 {can't read "y(0)": no such variable} 1 {can't read "y(0)": no such variable}}
test trace-16.7 {unsets during read traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) read {traceReset2 y y(0)}
lappend info [catch {set y(0)} msg] $msg [catch {set y(0)} msg] $msg
} {0 {} 0 xyzzy 1 {can't read "y(0)": no such element in array} 0 xyzzy}
test trace-16.8 {unsets during write traces} {
- catch {unset y}
+ unset -nocomplain y
set y 1234
set info {}
trace add variable y write {traceUnset y}
@@ -1094,91 +1095,91 @@ test trace-16.8 {unsets during write traces} {
lappend info [catch {set y xxx} msg] $msg
} {unset 0 {} 1 {can't read "x": no such variable} 0 {}}
test trace-16.9 {unsets during write traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) write {traceUnset y(0)}
lappend info [catch {set y(0) xxx} msg] $msg
} {0 {} 1 {can't read "x": no such variable} 0 {}}
test trace-16.10 {unsets during write traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) write {traceUnset y}
lappend info [catch {set y(0) xxx} msg] $msg
} {0 {} 1 {can't read "x": no such variable} 0 {}}
test trace-16.11 {unsets during write traces} {
- catch {unset y}
+ unset -nocomplain y
set y 1234
set info {}
trace add variable y write {traceReset y y}
lappend info [catch {set y xxx} msg] $msg
} {0 {} 0 xyzzy 0 xyzzy}
test trace-16.12 {unsets during write traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) write {traceReset y(0) y(0)}
lappend info [catch {set y(0) xxx} msg] $msg
} {0 {} 0 xyzzy 0 xyzzy}
test trace-16.13 {unsets during write traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) write {traceReset y y(0)}
lappend info [catch {set y(0) xxx} msg] $msg [catch {set y(0)} msg] $msg
} {0 {} 1 {can't set "y": upvar refers to element in deleted array} 0 {} 1 {can't read "y(0)": no such variable}}
test trace-16.14 {unsets during write traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) write {traceReset2 y y(0)}
lappend info [catch {set y(0) xxx} msg] $msg [catch {set y(0)} msg] $msg
} {0 {} 0 xyzzy 0 {} 0 xyzzy}
test trace-16.15 {unsets during unset traces} {
- catch {unset y}
+ unset -nocomplain y
set y 1234
set info {}
trace add variable y unset {traceUnset y}
lappend info [catch {unset y} msg] $msg [catch {set y} msg] $msg
} {1 {can't unset "x": no such variable} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y": no such variable}}
test trace-16.16 {unsets during unset traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) unset {traceUnset y(0)}
lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
} {1 {can't unset "x": no such variable} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y(0)": no such element in array}}
test trace-16.17 {unsets during unset traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) unset {traceUnset y}
lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
} {0 {} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y(0)": no such variable}}
test trace-16.18 {unsets during unset traces} {
- catch {unset y}
+ unset -nocomplain y
set y 1234
set info {}
trace add variable y unset {traceReset2 y y}
lappend info [catch {unset y} msg] $msg [catch {set y} msg] $msg
} {1 {can't unset "y": no such variable} 0 xyzzy 0 {} 0 xyzzy}
test trace-16.19 {unsets during unset traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) unset {traceReset2 y(0) y(0)}
lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
} {1 {can't unset "y(0)": no such element in array} 0 xyzzy 0 {} 0 xyzzy}
test trace-16.20 {unsets during unset traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) unset {traceReset2 y y(0)}
lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
} {0 {} 0 xyzzy 0 {} 0 xyzzy}
test trace-16.21 {unsets cancelling traces} {
- catch {unset y}
+ unset -nocomplain y
set y 1234
set info {}
trace add variable y read {traceAppend first}
@@ -1188,7 +1189,7 @@ test trace-16.21 {unsets cancelling traces} {
lappend info [catch {set y} msg] $msg
} {third unset 0 {} 1 {can't read "x": no such variable} 1 {can't read "y": no such variable}}
test trace-16.22 {unsets cancelling traces} {
- catch {unset y}
+ unset -nocomplain y
set y(0) 1234
set info {}
trace add variable y(0) read {traceAppend first}
@@ -1201,19 +1202,19 @@ test trace-16.22 {unsets cancelling traces} {
# Check various non-interference between traces and other things.
test trace-17.1 {trace doesn't prevent unset errors} {
- catch {unset x}
+ unset -nocomplain x
set info {}
trace add variable x unset {traceProc}
list [catch {unset x} msg] $msg $info
} {1 {can't unset "x": no such variable} {x {} unset}}
test trace-17.2 {traced variables must survive procedure exits} {
- catch {unset x}
+ unset -nocomplain x
proc p1 {} {global x; trace add variable x write traceProc}
p1
trace info variable x
} {{write traceProc}}
test trace-17.3 {traced variables must survive procedure exits} {
- catch {unset x}
+ unset -nocomplain x
set info {}
proc p1 {} {global x; trace add variable x write traceProc}
p1
@@ -1226,7 +1227,7 @@ test trace-17.3 {traced variables must survive procedure exits} {
test trace-18.1 {unset traces on procedure returns} {
proc p1 {x y} {set a 44; p2 14}
- proc p2 {z} {trace add variable z unset {traceCheck {lsort [uplevel {info vars}]}}}
+ proc p2 {z} {trace add variable z unset {traceCheck {lsort [uplevel 1 {info vars}]}}}
set info {}
p1 foo bar
set info
@@ -1266,8 +1267,7 @@ test trace-18.4 {namespace delete / trace vdelete combo, Bug \#1338280} {
# Delete arrays when done, so they can be re-used as scalars
# elsewhere.
-catch {unset x}
-catch {unset y}
+unset -nocomplain x y
test trace-19.0.1 {trace add command (command existence)} {
# Just in case!
@@ -1309,6 +1309,7 @@ test trace-19.3 {command rename traces don't fire on command deletion} {
test trace-19.4 {trace add command rename doesn't trace recreated commands} {
proc foo {} {}
catch {rename bar {}}
+ set info {}
trace add command foo rename traceCommand
proc foo {} {}
rename foo bar
@@ -1321,25 +1322,49 @@ test trace-19.5 {trace add command deleted removes traces} {
trace info command foo
} {}
-namespace eval tc {}
-proc tc::tcfoo {} {}
-test trace-19.6 {trace add command rename in namespace} {
+test trace-19.6 {trace add command rename in namespace} -setup {
+ namespace eval tc {}
+ proc tc::tcfoo {} {}
+} -body {
trace add command tc::tcfoo rename traceCommand
rename tc::tcfoo tc::tcbar
set info
-} {::tc::tcfoo ::tc::tcbar rename}
-test trace-19.7 {trace add command rename in namespace back again} {
+} -cleanup {
+ namespace delete tc
+} -result {::tc::tcfoo ::tc::tcbar rename}
+test trace-19.7 {trace add command rename in namespace back again} -setup {
+ namespace eval tc {}
+ proc tc::tcfoo {} {}
+} -body {
+ trace add command tc::tcfoo rename traceCommand
+ rename tc::tcfoo tc::tcbar
rename tc::tcbar tc::tcfoo
set info
-} {::tc::tcbar ::tc::tcfoo rename}
-test trace-19.8 {trace add command rename in namespace to out of namespace} {
+} -cleanup {
+ namespace delete tc
+} -result {::tc::tcbar ::tc::tcfoo rename}
+test trace-19.8 {trace add command rename in namespace to out of namespace} -setup {
+ namespace eval tc {}
+ proc tc::tcfoo {} {}
+} -body {
+ trace add command tc::tcfoo rename traceCommand
rename tc::tcfoo tcbar
set info
-} {::tc::tcfoo ::tcbar rename}
-test trace-19.9 {trace add command rename back into namespace} {
+} -cleanup {
+ catch {rename tcbar {}}
+ namespace delete tc
+} -result {::tc::tcfoo ::tcbar rename}
+test trace-19.9 {trace add command rename back into namespace} -setup {
+ namespace eval tc {}
+ proc tc::tcfoo {} {}
+} -body {
+ trace add command tc::tcfoo rename traceCommand
+ rename tc::tcfoo tcbar
rename tcbar tc::tcfoo
set info
-} {::tcbar ::tc::tcfoo rename}
+} -cleanup {
+ namespace delete tc
+} -result {::tcbar ::tc::tcfoo rename}
test trace-19.10 {trace add command failed rename doesn't trigger trace} {
set info {}
proc foo {} {}
@@ -1350,11 +1375,18 @@ test trace-19.10 {trace add command failed rename doesn't trigger trace} {
} {}
catch {rename foo {}}
catch {rename bar {}}
-test trace-19.11 {trace add command qualifies when renamed in namespace} {
+
+test trace-19.11 {trace add command qualifies when renamed in namespace} -setup {
+ namespace eval tc {}
+ proc tc::tcfoo {} {}
+} -body {
set info {}
+ trace add command tc::tcfoo {rename delete} traceCommand
namespace eval tc {rename tcfoo tcbar}
set info
-} {::tc::tcfoo ::tc::tcbar rename}
+} -cleanup {
+ namespace delete tc
+} -result {::tc::tcfoo ::tc::tcbar rename}
# Make sure it exists again
proc foo {} {}
@@ -1539,8 +1571,7 @@ proc foo {b} { set a $b }
# Delete arrays when done, so they can be re-used as scalars
# elsewhere.
-catch {unset x}
-catch {unset y}
+unset -nocomplain x y
# Delete procedures when done, so we don't clash with other tests
# (e.g. foobar will clash with 'unknown' tests).
@@ -1671,6 +1702,16 @@ test trace-21.11 {trace execution and alias} -setup {
rename ::x {}
} -result {:: ::}
+proc set2 args {
+ set {*}$args
+}
+
+test trace-21.12 {bug 2438181} -setup {
+ trace add execution set2 leave {puts one two three #;}
+} -body {
+ set2 a hello
+} -returnCodes 1 -result {wrong # args: should be "puts ?-nonewline? ?channelId? string"}
+
proc factorial {n} {
if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }
return 1
@@ -2047,7 +2088,7 @@ test trace-28.1 {enterstep and leavestep traces with update idletasks (615043)}
trace remove execution foo {enter enterstep leavestep leave} \
[list traceExecute foo]
rename foo {}
- catch {unset a}
+ unset -nocomplain a
join $info "\n"
} {foo foo enter
foo {set a 1} enterstep
@@ -2558,8 +2599,76 @@ set base {
}
runbase {{- *} {-* *} {- *} {- *}} $base
+test trace-39 {bug #3484621: tracing Bc'ed commands} -setup {
+ set ::traceLog 0
+ set ::traceCalls 0
+ set ::bar [list 0 1 2 3]
+ set res {}
+ proc dotrace args {
+ incr ::traceLog
+ }
+ proc foo {} {
+ incr ::traceCalls
+ # choose a BC'ed command that is 'unlikely' to interfere with tcltest's
+ # internals
+ lset ::bar 1 2
+ }
+} -body {
+ foo
+ lappend res $::traceLog
+
+ trace add execution lset enter dotrace
+ foo
+ lappend res $::traceLog
+
+ trace remove execution lset enter dotrace
+ foo
+ lappend res $::traceLog
+ list $::traceCalls | {*}$res
+} -cleanup {
+ unset ::traceLog ::traceCalls ::bar res
+ rename dotrace {}
+ rename foo {}
+} -result {3 | 0 1 1}
+
+test trace-39.1 {bug #3485022: tracing Bc'ed commands} -setup {
+ set ::traceLog 0
+ set ::traceCalls 0
+ set res {}
+ proc dotrace args {
+ incr ::traceLog
+ }
+ proc foo {} {
+ incr ::traceCalls
+ string equal zip zap
+ }
+} -body {
+ foo
+ lappend res $::traceLog
+
+ trace add execution ::tcl::string::equal enter dotrace
+ foo
+ lappend res $::traceLog
+
+ trace remove execution tcl::string::equal enter dotrace
+ foo
+ lappend res $::traceLog
+ list $::traceCalls | {*}$res
+} -cleanup {
+ unset ::traceLog ::traceCalls res
+ rename dotrace {}
+ rename foo {}
+} -result {3 | 0 1 1}
+
+test trace-40.1 {execution trace errors become command errors} {
+ proc foo args {}
+ trace add execution foo enter {rename foo {}; error bar;#}
+ catch foo m
+ return -level 0 $m[unset m]
+} bar
+
# Delete procedures when done, so we don't clash with other tests
# (e.g. foobar will clash with 'unknown' tests).
catch {rename foobar {}}
@@ -2570,9 +2679,8 @@ catch {rename traceproc {}}
catch {rename runbase {}}
# Unset the variable when done
-catch {unset info}
-catch {unset base}
+unset -nocomplain info base
# cleanup
-::tcltest::cleanupTests
+cleanupTests
return
diff --git a/tests/unixFCmd.test b/tests/unixFCmd.test
index e8148e9..e4613ed 100644
--- a/tests/unixFCmd.test
+++ b/tests/unixFCmd.test
@@ -14,6 +14,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testchmod [llength [info commands testchmod]]
# These tests really need to be run from a writable directory, which
@@ -362,20 +365,21 @@ test unixFCmd-17.4 {SetPermissionsAttribute} -setup {
close [open foo.test w]
set ::i 4
-proc permcheck {testnum permstr expected} {
+proc permcheck {testnum permList expected} {
test $testnum {SetPermissionsAttribute} {unix notRoot} {
+ set result {}
+ foreach permstr $permList {
file attributes foo.test -permissions $permstr
- file attributes foo.test -permissions
+ lappend result [file attributes foo.test -permissions]
+ }
+ set result
} $expected
}
permcheck unixFCmd-17.5 rwxrwxrwx 00777
permcheck unixFCmd-17.6 r--r---w- 00442
-permcheck unixFCmd-17.7 0 00000
-permcheck unixFCmd-17.8 u+rwx,g+r 00740
-permcheck unixFCmd-17.9 u-w 00540
-permcheck unixFCmd-17.10 o+rwx 00547
+permcheck unixFCmd-17.7 {0 u+rwx,g+r u-w o+rwx} {00000 00740 00540 00547}
permcheck unixFCmd-17.11 --x--x--x 00111
-permcheck unixFCmd-17.12 a+rwx 00777
+permcheck unixFCmd-17.12 {0 a+rwx} {00000 00777}
file delete -force -- foo.test
test unixFCmd-18.1 {Unix pwd} -constraints {unix notRoot nonPortable} -setup {
diff --git a/tests/unixFile.test b/tests/unixFile.test
index 0ea0ec1..8147f48 100644
--- a/tests/unixFile.test
+++ b/tests/unixFile.test
@@ -14,6 +14,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testfindexecutable [llength [info commands testfindexecutable]]
set oldpwd [pwd]
diff --git a/tests/unixForkEvent.test b/tests/unixForkEvent.test
new file mode 100644
index 0000000..120f362
--- /dev/null
+++ b/tests/unixForkEvent.test
@@ -0,0 +1,45 @@
+# This file contains a collection of tests for the procedures in the file
+# tclUnixNotify.c. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+testConstraint testfork [llength [info commands testfork]]
+
+# Test if the notifier thread is well initialized in a forked interpreter
+# by Tcl_InitNotifier
+test unixforkevent-1.1 {fork and test writeable event} \
+ -constraints {testfork nonPortable} \
+ -body {
+ set myFolder [makeDirectory unixtestfork]
+ set pid [testfork]
+ if {$pid == 0} {
+ # we are the forked process
+ set result initialized
+ set h [open [file join $myFolder test.txt] w]
+ fileevent $h writable\
+ "set result writable;\
+ after cancel [after 1000 {set result timeout}]"
+ vwait result
+ close $h
+ makeFile $result result.txt $myFolder
+ exit
+ }
+ # we are the original process
+ while {![file readable [file join $myFolder result.txt]]} {}
+ viewFile result.txt $myFolder
+ } \
+ -result {writable} \
+ -cleanup {
+ catch { removeFolder $myFolder }
+ }
+
+::tcltest::cleanupTests
+return
diff --git a/tests/unixInit.test b/tests/unixInit.test
index 9ba9c11..05338ed 100644
--- a/tests/unixInit.test
+++ b/tests/unixInit.test
@@ -11,7 +11,7 @@
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
package require tcltest 2.2
-namespace import -force ::tcltest::*
+namespace import ::tcltest::*
unset -nocomplain path
catch {set oldlang $env(LANG)}
set env(LANG) C
@@ -44,11 +44,11 @@ test unixInit-1.2 {initialisation: standard channel type deduction} {unix stdio}
set pipe1 [open "|[list [interpreter]]" r+]
puts $pipe1 {
proc accept {channel host port} {
- puts $channel {puts [fconfigure stdin -peername]; exit}
+ puts $channel {puts [chan configure stdin -peername]; exit}
close $channel
exit
}
- puts [fconfigure [socket -server accept -myaddr 127.0.0.1 0] -sockname]
+ puts [chan configure [socket -server accept -myaddr 127.0.0.1 0] -sockname]
vwait forever \
}
# Note the backslash above; this is important to make sure that the whole
@@ -64,8 +64,8 @@ test unixInit-1.2 {initialisation: standard channel type deduction} {unix stdio}
set pipe2 [open "|[list [interpreter] <@$sock]" r]
set result [gets $pipe2]
# Clear any pending data; stops certain kinds of (non-important) errors
- fconfigure $pipe1 -blocking 0; gets $pipe1
- fconfigure $pipe2 -blocking 0; gets $pipe2
+ chan configure $pipe1 -blocking 0; gets $pipe1
+ chan configure $pipe2 -blocking 0; gets $pipe2
# Close the pipes and the socket.
close $pipe2
close $pipe1
@@ -329,7 +329,7 @@ test unixInit-3.1 {TclpSetInitialEncodings} -constraints {
} -body {
set env(LANG) C
set f [open "|[list [interpreter]]" w+]
- fconfigure $f -buffering none
+ chan configure $f -buffering none
puts $f {puts [encoding system]; exit}
set enc [gets $f]
close $f
@@ -344,7 +344,7 @@ test unixInit-3.2 {TclpSetInitialEncodings} -setup {
set env(LANG) japanese
set env(LC_ALL) japanese
set f [open "|[list [interpreter]]" w+]
- fconfigure $f -buffering none
+ chan configure $f -buffering none
puts $f {puts [encoding system]; exit}
set enc [gets $f]
close $f
@@ -390,7 +390,7 @@ test unixInit-7.1 {closed standard channel: Bug 772288} -constraints {
} -returnCodes 0
# cleanup
-catch {unset env(LANG)}
+unset -nocomplain env(LANG)
catch {set env(LANG) $oldlang}
unset -nocomplain path
::tcltest::cleanupTests
diff --git a/tests/unixNotfy.test b/tests/unixNotfy.test
index 8af8a21..2f03529 100644
--- a/tests/unixNotfy.test
+++ b/tests/unixNotfy.test
@@ -10,21 +10,17 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-# The tests should not be run if you have a notifier which is unable to
-# detect infinite vwaits, as the tests below will hang. The presence of
-# the "testthread" command indicates that this is the case.
-
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest 2
namespace import -force ::tcltest::*
}
# When run in a Tk shell, these tests hang.
-testConstraint noTk [expr {![info exists tk_version]}]
-testConstraint testthread [expr {[info commands testthread] != {}}]
+testConstraint noTk [expr {0 != [catch {package present Tk}]}]
+testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
# Darwin always uses a threaded notifier
testConstraint unthreaded [expr {
- (![info exist tcl_platform(threaded)] || !$tcl_platform(threaded))
+ ![::tcl::pkgconfig get threaded]
&& $tcl_platform(os) ne "Darwin"
}]
@@ -61,16 +57,15 @@ test unixNotfy-1.2 {Tcl_DeleteFileHandler} -constraints {noTk unix unthreaded} -
}
test unixNotfy-2.1 {Tcl_DeleteFileHandler} \
- -constraints {noTk unix testthread} \
+ -constraints {noTk unix thread} \
-body {
update
set f [open [makeFile "" foo] w]
fileevent $f writable {set x 1}
vwait x
close $f
- testthread create "testthread send [testthread id] {set x ok}"
+ thread::create "thread::send [thread::id] {set x ok}"
vwait x
- threadReap
set x
} \
-result {ok} \
@@ -79,7 +74,7 @@ test unixNotfy-2.1 {Tcl_DeleteFileHandler} \
catch { removeFile foo }
}
test unixNotfy-2.2 {Tcl_DeleteFileHandler} \
- -constraints {noTk unix testthread} \
+ -constraints {noTk unix thread} \
-body {
update
set f1 [open [makeFile "" foo] w]
@@ -90,9 +85,8 @@ test unixNotfy-2.2 {Tcl_DeleteFileHandler} \
close $f1
vwait y
close $f2
- testthread create "testthread send [testthread id] {set x ok}"
+ thread::create "thread::send [thread::id] {set x ok}"
vwait x
- threadReap
set x
} \
-result {ok} \
diff --git a/tests/unknown.test b/tests/unknown.test
index 40be6602..e80d3a6 100644
--- a/tests/unknown.test
+++ b/tests/unknown.test
@@ -11,12 +11,10 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest
- namespace import -force ::tcltest::*
-}
+package require tcltest 2
+namespace import ::tcltest::*
-catch {unset x}
+unset -nocomplain x
catch {rename unknown unknown.old}
test unknown-1.1 {non-existent "unknown" command} {
@@ -59,7 +57,7 @@ test unknown-4.1 {errors in "unknown" procedure} {
# cleanup
catch {rename unknown {}}
catch {rename unknown.old unknown}
-::tcltest::cleanupTests
+cleanupTests
return
# Local Variables:
diff --git a/tests/unload.test b/tests/unload.test
index a103cc5..5a374c4 100644
--- a/tests/unload.test
+++ b/tests/unload.test
@@ -16,6 +16,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
# Figure out what extension is used for shared libraries on this
# platform.
if {![info exists ext]} {
diff --git a/tests/upvar.test b/tests/upvar.test
index cd78c31..e93f58a 100644
--- a/tests/upvar.test
+++ b/tests/upvar.test
@@ -16,6 +16,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testupvar [llength [info commands testupvar]]
test upvar-1.1 {reading variables with upvar} {
@@ -411,6 +414,17 @@ test upvar-9.7 {Tcl_UpVar procedure} testupvar {
} {1234}
catch {unset a}
+test upvar-10.1 {CompileWord OBOE} -setup {
+ proc linenumber {} {dict get [info frame -1] line}
+} -body {
+ apply {n {
+ upvar 1 {*}{
+ } [return [incr n -[linenumber]]] x
+ }} [linenumber]
+} -cleanup {
+ rename linenumber {}
+} -result 1
+
#
# Tests for 'namespace upvar'. As the implementation is essentially the same as
# for 'upvar', we only test that the variables are linked correctly, i.e., we
@@ -533,6 +547,38 @@ test upvar-NS-2.2 {TIP 323} -setup {
} -cleanup {
namespace delete test_ns_1
} -result {}
+
+test upvar-NS-3.1 {CompileWord OBOE} -setup {
+ proc linenumber {} {dict get [info frame -1] line}
+} -body {
+ apply {n {
+ namespace upvar {*}{
+ } [return [incr n -[linenumber]]] x y
+ }} [linenumber]
+} -cleanup {
+ rename linenumber {}
+} -result 1
+test upvar-NS-3.2 {CompileWord OBOE} -setup {
+ proc linenumber {} {dict get [info frame -1] line}
+} -body {
+ apply {n {
+ namespace upvar :: {*}{
+ } [return [incr n -[linenumber]]] x
+ }} [linenumber]
+} -cleanup {
+ rename linenumber {}
+} -result 1
+test upvar-NS-3.3 {CompileWord OBOE} -setup {
+ proc linenumber {} {dict get [info frame -1] line}
+} -body {
+ apply {n {
+ variable x {*}{
+ } [return [incr n -[linenumber]]]
+ }} [linenumber]
+} -cleanup {
+ rename linenumber {}
+} -result 1
+
# cleanup
::tcltest::cleanupTests
diff --git a/tests/utf.test b/tests/utf.test
index d319f6e..ebab967 100644
--- a/tests/utf.test
+++ b/tests/utf.test
@@ -13,6 +13,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
catch {unset x}
test utf-1.1 {Tcl_UniCharToUtf: 1 byte sequences} {
@@ -27,9 +30,12 @@ test utf-1.3 {Tcl_UniCharToUtf: 2 byte sequences} {
test utf-1.4 {Tcl_UniCharToUtf: 3 byte sequences} {
set x "\u4e4e"
} [bytestring "\xe4\xb9\x8e"]
-test utf-1.5 {Tcl_UniCharToUtf: negative Tcl_UniChar} {
- string length [format %c -1]
-} 1
+test utf-1.5 {Tcl_UniCharToUtf: overflowed Tcl_UniChar} {
+ format %c 0x110000
+} [bytestring "\xef\xbf\xbd"]
+test utf-1.6 {Tcl_UniCharToUtf: negative Tcl_UniChar} {
+ format %c -1
+} [bytestring "\xef\xbf\xbd"]
test utf-2.1 {Tcl_UtfToUniChar: low ascii} {
string length "abc"
@@ -168,7 +174,7 @@ bsCheck \x 120
bsCheck \xa 10
bsCheck \xA 10
bsCheck \x41 65
-bsCheck \x541 65
+bsCheck \x541 84
bsCheck \u 117
bsCheck \uk 117
bsCheck \u41 65
@@ -177,6 +183,18 @@ bsCheck \uA 10
bsCheck \340 224
bsCheck \ua1 161
bsCheck \u4e21 20001
+bsCheck \741 60
+bsCheck \U 85
+bsCheck \Uk 85
+bsCheck \U41 65
+bsCheck \Ua 10
+bsCheck \UA 10
+bsCheck \Ua1 161
+bsCheck \U4e21 20001
+bsCheck \U004e21 20001
+bsCheck \U00004e21 20001
+bsCheck \U00110000 65533
+bsCheck \Uffffffff 65533
test utf-11.1 {Tcl_UtfToUpper} {
string toupper {}
@@ -244,8 +262,9 @@ test utf-16.1 {Tcl_UniCharToLower, negative delta} {
string tolower aA
} aa
test utf-16.2 {Tcl_UniCharToLower, positive delta} {
- string tolower \u0178\u00ff
-} \u00ff\u00ff
+ string tolower \u0178\u00ff\uA78D\u01c5
+} \u00ff\u00ff\u0265\u01c6
+
test utf-17.1 {Tcl_UniCharToLower, no delta} {
string tolower !
} !
@@ -281,6 +300,46 @@ test utf-21.2 {unicode alnum char in regc_locale.c} {
# this returns 1 with Unicode 6 compliance
list [regexp {^[[:alnum:]]+$} \u1040\u021f\u0220] [regexp {^\w+$} \u1040\u021f\u0220]
} {1 1}
+test utf-21.3 {unicode print char in regc_locale.c} {
+ # this returns 1 with Unicode 6 compliance
+ regexp {^[[:print:]]+$} \ufbc1
+} 1
+test utf-21.4 {TclUniCharIsGraph} {
+ # [Bug 3464428]
+ string is graph \u0120
+} {1}
+test utf-21.5 {unicode graph char in regc_locale.c} {
+ # [Bug 3464428]
+ regexp {^[[:graph:]]+$} \u0120
+} {1}
+test utf-21.6 {TclUniCharIsGraph} {
+ # [Bug 3464428]
+ string is graph \u00a0
+} {0}
+test utf-21.7 {unicode graph char in regc_locale.c} {
+ # [Bug 3464428]
+ regexp {[[:graph:]]} \u0020\u00a0\u2028\u2029
+} {0}
+test utf-21.8 {TclUniCharIsPrint} {
+ # [Bug 3464428]
+ string is print \u0009
+} {0}
+test utf-21.9 {unicode print char in regc_locale.c} {
+ # [Bug 3464428]
+ regexp {[[:print:]]} \u0009
+} {0}
+test utf-21.10 {unicode print char in regc_locale.c} {
+ # [Bug 3464428]
+ regexp {[[:print:]]} \u0009
+} {0}
+test utf-21.11 {TclUniCharIsControl} {
+ # [Bug 3464428]
+ string is control \u00ad
+} {1}
+test utf-21.12 {unicode control char in regc_locale.c} {
+ # [Bug 3464428], [Bug a876646efe]
+ regexp {^[[:cntrl:]]*$} \u0000\u001f\u00ad
+} {1}
test utf-22.1 {TclUniCharIsWordChar} {
string wordend "xyz123_bar fg" 0
diff --git a/tests/util.test b/tests/util.test
index 15457da..0e50483 100644
--- a/tests/util.test
+++ b/tests/util.test
@@ -12,9 +12,13 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint controversialNaN 1
testConstraint testdstring [llength [info commands testdstring]]
testConstraint testconcatobj [llength [info commands testconcatobj]]
+testConstraint testdoubledigits [llength [info commands testdoubledigits]]
# Big test for correct ordering of data in [expr]
@@ -1143,542 +1147,628 @@ test util-11.23 {Tcl_PrintDouble - scaling} {
expr 1.1e17
} {1.1e+17}
-test util-12.1 {TclDoubleDigits - Inf} ieeeFloatingPoint {
+test util-12.1 {TclDoubleDigits - Inf} {testdoubledigits ieeeFloatingPoint} {
testdoubledigits Inf -1 shortest
} {Infinity 9999 +}
-test util-12.2 {TclDoubleDigits - -Inf} ieeeFloatingPoint {
+test util-12.2 {TclDoubleDigits - -Inf} {testdoubledigits ieeeFloatingPoint} {
testdoubledigits -Inf -1 shortest
} {Infinity 9999 -}
-test util-12.3 {TclDoubleDigits - NaN} ieeeFloatingPoint {
+test util-12.3 {TclDoubleDigits - NaN} {testdoubledigits ieeeFloatingPoint} {
testdoubledigits $ieeeValues(NaN) -1 shortest
} {NaN 9999 +}
test util-12.4 {TclDoubleDigits - NaN} {*}{
- -constraints {ieeeFloatingPoint && controversialNaN}
+ -constraints {testdoubledigits ieeeFloatingPoint controversialNaN}
-body {
testdoubledigits -NaN -1 shortest
}
-result {NaN 9999 -}
}
-test util-12.5 {TclDoubleDigits - 0} {
+test util-12.5 {TclDoubleDigits - 0} testdoubledigits {
testdoubledigits 0.0 -1 shortest
} {0 0 +}
-test util-12.6 {TclDoubleDigits - -0} {
+test util-12.6 {TclDoubleDigits - -0} testdoubledigits {
testdoubledigits -0.0 -1 shortest
} {0 0 -}
# Verdonk test vectors
test util-13.1 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1754e31cd072da E+1008 +4_000000000000000000& E+303
}
-result {}
}
test util-13.2 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1afcef51f0fb5f E+265 -1_000000000000000000& E+80
}
-result {}
}
test util-13.3 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1754e31cd072da E+1006 +1_000000000000000000& E+303
}
-result {}
}
test util-13.4 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1754e31cd072da E+1007 -2_000000000000000000& E+303
}
-result {}
}
test util-13.5 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1e07b27dd78b14 E-848 +1_00000000000000000& E-255
}
-result {}
}
test util-13.6 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1e29e9c56687fe E-709 -7_00000000000000000& E-214
}
-result {}
}
test util-13.7 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1be03d0bf225c7 E-137 +1_00000000000000000& E-41
}
-result {}
}
test util-13.8 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1a2fe76a3f9475 E-499 -1_00000000000000000& E-150
}
-result {}
}
test util-13.9 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 19a2028368022e E+1019 +8_999999999999999999& E+306
}
-result {}
}
test util-13.10 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1317e5ef3ab327 E+509 -1_999999999999999999& E+153
}
-result {}
}
test util-13.11 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1317e5ef3ab327 E+510 +3_99999999999999999& E+153
}
-result {}
}
test util-13.12 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1317e5ef3ab327 E+511 -7_99999999999999999& E+153
}
-result {}
}
test util-13.13 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1eb8e84fa0b278 E-1008 +6_999999999999999999& E-304
}
-result {}
}
test util-13.14 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -13339131c46f8b E-1004 -6_999999999999999999& E-303
}
-result {}
}
test util-13.15 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1c0f92a6276c9d E-162 +2_999999999999999999& E-49
}
-result {}
}
test util-13.16 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -15ce1f143d7ad2 E-443 -5_99999999999999999& E-134
}
-result {}
}
test util-13.17 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1c0794d9d40e96 E-301 +43_000000000000000000& E-92
}
-result {}
}
test util-13.18 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1c0794d9d40e96 E-300 -86_000000000000000000& E-92
}
-result {}
}
test util-13.19 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1cd5bee57763e6 E-241 +51_000000000000000000& E-74
}
-result {}
}
test util-13.20 {just under exact - 2 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1d1c26db7d0dae E+651 +16_999999999999999999& E+195
}
-result {}
}
test util-13.21 {just under exact - 2 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -13f7ced916872b E-5 -38_999999999999999999& E-3
}
-result {}
}
test util-13.22 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 17d93193f78fc6 E+588 +151_0000000000000000000& E+175
}
-result {}
}
test util-13.23 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1a82a1631eeb30 E-625 -119_000000000000000000& E-190
}
-result {}
}
test util-13.24 {just under exact - 3 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -16c309024bab4b E+290 -282_999999999999999999& E+85
}
-result {}
}
test util-13.25 {just over exact - 8 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1dbbac6f83a821 E-800 +27869147_0000000000000000000& E-248
}
-result {}
}
test util-13.26 {just under exact - 9 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1c569e968e0944 E+430 -491080653_9999999999999999999& E+121
}
-result {}
}
test util-13.27 {just under exact - 9 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1c569e968e0944 E+429 +245540326_9999999999999999999& E+121
}
-result {}
}
test util-13.28 {just over exact - 10 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1fc575867314ee E-330 -9078555839_0000000000000000000& E-109
}
-result {}
}
test util-13.29 {just under exact - 10 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1c569e968e0944 E+428 -1227701634_9999999999999999999& E+120
}
-result {}
}
test util-13.30 {just over exact - 11 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1fc575867314ee E-329 +18157111678_0000000000000000000& E-109
}
-result {}
}
test util-13.31 {just over exact - 14 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -18bf7e7fa6f02a E-196 -15400733123779_0000000000000000000& E-72
}
-result {}
}
test util-13.32 {just over exact - 17 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -13de005bd620df E+217 -26153245263757307_0000000000000000000& E+49
}
-result {}
}
test util-13.33 {just over exact - 18 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1f92bacb3cb40c E+718 +272104041512242479_0000000000000000000& E+199
}
-result {}
}
test util-13.34 {just over exact - 18 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1f92bacb3cb40c E+719 -544208083024484958_0000000000000000000& E+199
}
-result {}
}
test util-13.35 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 142dbf25096cf5 E+148 +4_500000000000000000& E+44
}
-result {}
}
test util-13.36 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1afcef51f0fb5f E+263 -2_500000000000000000& E+79
}
-result {}
}
test util-13.37 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 102498ea6df0c4 E+145 +4_500000000000000000& E+43
}
-result {}
}
test util-13.38 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1754e31cd072da E+1004 -2_500000000000000000& E+302
}
-result {}
}
test util-13.39 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 12deac01e2b4f7 E-557 +2_50000000000000000& E-168
}
-result {}
}
test util-13.40 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1b1df536c13eee E-307 -6_50000000000000000& E-93
}
-result {}
}
test util-13.41 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 10711fed5b19a4 E-154 +4_50000000000000000& E-47
}
-result {}
}
test util-13.42 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -148d67e8b1e00d E-151 -4_50000000000000000& E-46
}
-result {}
}
test util-13.43 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1c8c574c0c6be7 E+187 +3_49999999999999999& E+56
}
-result {}
}
test util-13.44 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1756183c147514 E+206 -1_49999999999999999& E+62
}
-result {}
}
test util-13.45 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 12ab469676c410 E+203 +1_49999999999999999& E+61
}
-result {}
}
test util-13.46 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1539684e774b48 E+246 -1_49999999999999999& E+74
}
-result {}
}
test util-13.47 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 12e5f5dfa4fe9d E-286 +9_499999999999999999& E-87
}
-result {}
}
test util-13.48 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1bdc2417bf7787 E-838 -9_499999999999999999& E-253
}
-result {}
}
test util-13.49 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1eb8e84fa0b278 E-1009 +3_499999999999999999& E-304
}
-result {}
}
test util-13.50 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1e3cbc9907fdc8 E-290 -9_499999999999999999& E-88
}
-result {}
}
test util-13.51 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 10ad836f269a17 E-324 +30_500000000000000000& E-99
}
-result {}
}
test util-13.52 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1b39ae1909c31b E-687 -26_500000000000000000& E-208
}
-result {}
}
test util-13.53 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1b2ab18615fcc6 E-576 +686_500000000000000000& E-176
}
-result {}
}
test util-13.54 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -13e1f90a573064 E-624 -178_500000000000000000& E-190
}
-result {}
}
test util-13.55 {just under half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 16c309024bab4b E+289 +141_499999999999999999& E+85
}
-result {}
}
test util-13.56 {just under half ulp - 4 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -159bd3ad46e346 E+193 -1695_499999999999999999& E+55
}
-result {}
}
test util-13.57 {just under half ulp - 4 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1df4170f0fdecc E+124 +3981_499999999999999999& E+34
}
-result {}
}
test util-13.58 {just over half ulp - 6 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 17e1e0f1c7a4ac E+415 +126300_5000000000000000000& E+120
}
-result {}
}
test util-13.59 {just over half ulp - 6 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1dda592e398dd7 E+418 -126300_5000000000000000000& E+121
}
-result {}
}
test util-13.60 {just under half ulp - 7 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1e597c0b94b7ae E+453 -4411845_499999999999999999& E+130
}
-result {}
}
test util-13.61 {just under half ulp - 9 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1c569e968e0944 E+427 +613850817_4999999999999999999& E+120
}
-result {}
}
test util-13.62 {just under half ulp - 9 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1c569e968e0944 E+428 -122770163_49999999999999999999& E+121
}
-result {}
}
test util-13.63 {just over half ulp - 18 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 17ae0c186d8709 E+719 +408156062268363718_5000000000000000000& E+199
}
-result {}
}
test util-13.64 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 152d02c7e14af7 E+76 +1_0000000000000000& E+23
}
-result {}
}
test util-13.65 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -19d971e4fe8402 E+89 -1_0000000000000000& E+27
}
-result {}
}
test util-13.66 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 19d971e4fe8402 E+90 +2_0000000000000000& E+27
}
-result {}
}
test util-13.67 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -19d971e4fe8402 E+91 -4_0000000000000000& E+27
}
-result {}
}
test util-13.68 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 15798ee2308c3a E-27 +1_0000000000000000& E-8
}
-result {}
}
test util-13.69 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -15798ee2308c3a E-26 -2_0000000000000000& E-8
}
-result {}
}
test util-13.70 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 15798ee2308c3a E-25 +4_0000000000000000& E-8
}
-result {}
}
test util-13.71 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1ef2d0f5da7dd9 E-84 -1_0000000000000000& E-25
}
-result {}
}
test util-13.72 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1a784379d99db4 E+78 +4_9999999999999999& E+23
}
-result {}
}
test util-13.73 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1a784379d99db4 E+80 -1_9999999999999999& E+24
}
-result {}
}
test util-13.74 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 13da329b633647 E+81 +2_9999999999999999& E+24
}
-result {}
}
test util-13.75 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1cf389cd46047d E+85 -6_9999999999999999& E+25
}
-result {}
}
test util-13.76 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 19999999999999 E-3 +1_99999999999999999& E-1
}
-result {}
}
test util-13.77 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -13333333333333 E-2 -2_99999999999999999& E-1
}
-result {}
}
test util-13.78 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 16849b86a12b9b E-48 +4_99999999999999999& E-15
}
-result {}
}
test util-13.79 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -16849b86a12b9b E-46 -1_99999999999999999& E-14
}
-result {}
}
test util-13.80 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 17ccfc73126788 E-71 +63_00000000000000000& E-23
}
-result {}
}
test util-13.81 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1dc03b8fd7016a E-68 -63_00000000000000000& E-22
}
-result {}
}
test util-13.82 {just under exact - 2 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 13f7ced916872b E-5 +38_999999999999999999& E-3
}
-result {}
}
test util-13.83 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1b297cad9f70b6 E+97 +269_000000000000000000& E+27
}
-result {}
}
test util-13.84 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1b297cad9f70b6 E+98 -538_00000000000000000& E+27
}
-result {}
}
test util-13.85 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1cdc06b20ef183 E-82 +373_00000000000000000& E-27
}
-result {}
}
test util-13.86 {just over exact - 4 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1b297cad9f70b6 E+96 +1345_00000000000000000& E+26
}
@@ -1686,205 +1776,238 @@ test util-13.86 {just over exact - 4 digits} {*}{
}
# this one is not 4 digits, it is 3, and it is covered above.
test util-13.87 {just over exact - 4 digits} {*}{
- -constraints knownBadTest
+ -constraints {testdoubledigits knownBadTest}
-body {
verdonk_test -1b297cad9f70b6 E+97 -2690_00000000000000000& E+26
}
-result {}
}
test util-13.88 {just over exact - 5 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -150a246ecd44f3 E-63 -14257_00000000000000000& E-23
}
-result {}
}
test util-13.89 {just under exact - 6 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -119b96f36ec68b E-19 -209900_999999999999999999& E-11
}
-result {}
}
test util-13.90 {just over exact - 11 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1c06d366394441 E-35 +50980203373_000000000000000000& E-21
}
-result {}
}
test util-13.91 {just under exact - 12 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1f58ac4db68c90 E+122 -104166211810_99999999999999999& E+26
}
-result {}
}
test util-13.92 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 19d971e4fe8402 E+87 +2_5000000000000000& E+26
}
-result {}
}
test util-13.93 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1dc74be914d16b E+81 -4_500000000000000& E+24
}
-result {}
}
test util-13.94 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 14adf4b7320335 E+84 +2_500000000000000& E+25
}
-result {}
}
test util-13.95 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1ae22487c1042b E+85 -6_5000000000000000& E+25
}
-result {}
}
test util-13.96 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 187fe49aab41e0 E-54 +8_5000000000000000& E-17
}
-result {}
}
test util-13.97 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1f5c05e4b23fd7 E-61 -8_5000000000000000& E-19
}
-result {}
}
test util-13.98 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1faa7ab552a552 E-42 +4_5000000000000000& E-13
}
-result {}
}
test util-13.99 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1b7cdfd9d7bdbb E-36 -2_5000000000000000& E-11
}
-result {}
}
test util-13.100 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 13da329b633647 E+80 +1_4999999999999999& E+24
}
-result {}
}
test util-13.101 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1cf389cd46047d E+84 -3_49999999999999999& E+25
}
-result {}
}
test util-13.102 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1f04ef12cb04cf E+85 +7_4999999999999999& E+25
}
-result {}
}
test util-13.103 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1f04ef12cb04cf E+86 -1_4999999999999999& E+26
}
-result {}
}
test util-13.104 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 13333333333333 E-3 +1_49999999999999999& E-1
}
-result {}
}
test util-13.105 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -107e1fe91b0b70 E-36 -1_49999999999999999& E-11
}
-result {}
}
test util-13.106 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 149da7e361ce4c E-33 +1_49999999999999999& E-10
}
-result {}
}
test util-13.107 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -19c511dc3a41df E-30 -1_49999999999999999& E-9
}
-result {}
}
test util-13.108 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1aa83d74267822 E+93 -16_5000000000000000& E+27
}
-result {}
}
test util-13.109 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 18f1d5969453de E+89 +96_5000000000000000& E+25
}
-result {}
}
test util-13.110 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 11d9bd564dcda6 E-70 +94_50000000000000000& E-23
}
-result {}
}
test util-13.111 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1a58973ecbede6 E-48 -58_50000000000000000& E-16
}
-result {}
}
test util-13.112 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1b297cad9f70b6 E+95 +672_50000000000000000& E+26
}
-result {}
}
test util-13.113 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -1b297cad9f70b6 E+96 -134_500000000000000000& E+27
}
-result {}
}
test util-13.114 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1cdc06b20ef183 E-83 +186_50000000000000000& E-27
}
-result {}
}
test util-13.115 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -136071dcae4565 E-47 -860_50000000000000000& E-17
}
-result {}
}
test util-13.116 {just over half ulp - 6 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1cb968d297dde8 E+99 +113788_50000000000000000& E+25
}
-result {}
}
test util-13.117 {just over half ulp - 6 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test -11f3e1839eeab1 E+103 -113788_50000000000000000& E+26
}
-result {}
}
test util-13.118 {just under half ulp - 9 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1e9cec176c96f8 E+117 +317903333_49999999999999999& E+27
}
-result {}
}
test util-13.119 {just over half ulp - 11 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1c06d366394441 E-36 +25490101686_500000000000000000& E-21
}
-result {}
}
test util-13.120 {just under half ulp - 11 digits} {*}{
+ -constraints testdoubledigits
-body {
verdonk_test 1f58ac4db68c90 E+121 +52083105905_49999999999999999& E+26
}
@@ -1892,7 +2015,7 @@ test util-13.120 {just under half ulp - 11 digits} {*}{
}
test util-14.1 {funky NaN} {*}{
- -constraints {ieeeFloatingPoint && controversialNaN}
+ -constraints {ieeeFloatingPoint controversialNaN}
-body {
set ieeeValues(-NaN)
}
@@ -1900,7 +2023,7 @@ test util-14.1 {funky NaN} {*}{
}
test util-14.2 {funky NaN} {*}{
- -constraints {ieeeFloatingPoint && controversialNaN}
+ -constraints {ieeeFloatingPoint controversialNaN}
-body {
set ieeeValues(-NaN(3456789abcdef))
}
@@ -3901,4 +4024,4 @@ return
# Local Variables:
# mode: tcl
-# End: \ No newline at end of file
+# End:
diff --git a/tests/var.test b/tests/var.test
index f2923de..208b361 100644
--- a/tests/var.test
+++ b/tests/var.test
@@ -19,6 +19,9 @@ if {"::tcltest" ni [namespace children]} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testupvar [llength [info commands testupvar]]
testConstraint testgetvarfullname [llength [info commands testgetvarfullname]]
testConstraint testsetnoerr [llength [info commands testsetnoerr]]
@@ -745,6 +748,9 @@ test var-15.1 {segfault in [unset], [Bug 735335]} {
namespace eval test A useSomeUnlikelyNameHere
namespace eval test unset useSomeUnlikelyNameHere
} {}
+test var-15.2 {compiled unset evaluation order, Bug 3970f54c4e} {
+ apply {{} {unset foo [return ok]}}
+} ok
test var-16.1 {CallVarTraces: save/restore interp error state} {
trace add variable ::errorCode write " ;#"
@@ -790,6 +796,88 @@ test var-19.1 {crash when freeing locals hashtable: Bug 3037525} {
foo ; # This crashes without the fix for the bug
rename foo {}
} {}
+
+test var-20.1 {array set compilation correctness: Bug 3603163} -setup {
+ unset -nocomplain x
+} -body {
+ apply {{} {
+ global x
+ array set x {a 1}
+ }}
+ array size x
+} -result 1
+test var-20.2 {array set compilation correctness: Bug 3603163} -setup {
+ unset -nocomplain x
+} -body {
+ apply {{} {
+ global x
+ array set x {}
+ }}
+ array size x
+} -result 0
+test var-20.3 {array set compilation correctness: Bug 3603163} -setup {
+ unset -nocomplain x
+} -body {
+ apply {{} {
+ array set ::x {a 1}
+ }}
+ array size x
+} -result 1
+test var-20.4 {array set compilation correctness: Bug 3603163} -setup {
+ unset -nocomplain x
+} -body {
+ apply {{} {
+ array set ::x {}
+ }}
+ array size x
+} -result 0
+test var-20.5 {array set compilation correctness: Bug 3603163} -setup {
+ unset -nocomplain x
+} -body {
+ apply {{} {
+ global x
+ eval {array set x {a 1}}
+ }}
+ array size x
+} -result 1
+test var-20.6 {array set compilation correctness: Bug 3603163} -setup {
+ unset -nocomplain x
+} -body {
+ apply {{} {
+ global x
+ eval {array set x {}}
+ }}
+ array size x
+} -result 0
+test var-20.7 {array set compilation correctness: Bug 3603163} -setup {
+ unset -nocomplain x
+} -body {
+ apply {{} {
+ eval {array set ::x {a 1}}
+ }}
+ array size x
+} -result 1
+test var-20.8 {array set compilation correctness: Bug 3603163} -setup {
+ unset -nocomplain x
+} -body {
+ apply {{} {
+ eval {array set ::x {}}
+ }}
+ array size x
+} -result 0
+
+test var-21.0 {PushVarNameWord OBOE in compiled unset} -setup {
+ proc linenumber {} {dict get [info frame -1] line}
+} -body {
+ apply {n {
+ set foo bar
+ unset foo {*}{
+ } [return [incr n -[linenumber]]]
+ }} [linenumber]
+} -cleanup {
+ rename linenumber {}
+} -result 1
+
catch {namespace delete ns}
catch {unset arr}
diff --git a/tests/winDde.test b/tests/winDde.test
index ca50a96..f04fb45 100644
--- a/tests/winDde.test
+++ b/tests/winDde.test
@@ -15,17 +15,14 @@ if {"::tcltest" ni [namespace children]} {
namespace import -force ::tcltest::*
}
+testConstraint debug [::tcl::pkgconfig get debug]
+testConstraint dde 0
if {[testConstraint win]} {
- if [catch {
- # Is the dde extension already static to this shell?
- if [catch {load {} Dde; set ::ddelib {}}] {
- # try the location given to use on the commandline to tcltest
+ if {![catch {
::tcltest::loadTestedCommands
- load $::ddelib Dde
- }
+ set ::ddever [package require dde 1.4.0]
+ set ::ddelib [lindex [package ifneeded dde $::ddever] 1]}]} {
testConstraint dde 1
- }] {
- testConstraint dde 0
}
}
@@ -36,14 +33,12 @@ if {[testConstraint win]} {
set scriptName [makeFile {} script1.tcl]
-proc createChildProcess { ddeServerName {handler {}}} {
+proc createChildProcess {ddeServerName args} {
file delete -force $::scriptName
set f [open $::scriptName w+]
puts $f [list set ddeServerName $ddeServerName]
- if {$::ddelib != ""} {
- puts $f [list load $::ddelib Dde]
- }
+ puts $f [list load $::ddelib dde]
puts $f {
# DDE child server -
#
@@ -51,7 +46,7 @@ proc createChildProcess { ddeServerName {handler {}}} {
package require tcltest
namespace import -force ::tcltest::*
}
-
+
# If an error occurs during the tests, this process may end up not
# being closed down. To deal with this we create a 30s timeout.
proc ::DoTimeout {} {
@@ -61,16 +56,19 @@ proc createChildProcess { ddeServerName {handler {}}} {
flush stdout
}
set timeout [after 30000 ::DoTimeout]
-
+
# Define a restricted handler.
proc Handler1 {cmd} {
if {$cmd eq "stop"} {set ::done 1}
- puts $cmd ; flush stdout
+ if {$cmd == ""} {
+ set cmd "null data"
+ }
+ puts $cmd ; flush stdout
return
}
proc Handler2 {cmd} {
if {$cmd eq "stop"} {set ::done 1}
- puts [uplevel \#0 $cmd] ; flush stdout
+ puts [uplevel \#0 $cmd] ; flush stdout
return
}
proc Handler3 {prefix cmd} {
@@ -80,11 +78,7 @@ proc createChildProcess { ddeServerName {handler {}}} {
}
}
# set the dde server name to the supplied argument.
- if {$handler == {}} {
- puts $f [list dde servername $ddeServerName]
- } else {
- puts $f [list dde servername -handler $handler -- $ddeServerName]
- }
+ puts $f [list dde servername {*}$args -- $ddeServerName]
puts $f {
# run the server and handle final cleanup.
after 200;# give dde a chance to get going.
@@ -94,12 +88,12 @@ proc createChildProcess { ddeServerName {handler {}}} {
# allow enough time for the calling process to
# claim all results, to avoid spurious "server did
# not respond"
- after 200 { set reallyDone 1 }
+ after 200 {set reallyDone 1}
vwait reallyDone
exit
}
close $f
-
+
# run the child server script.
set f [open |[list [interpreter] $::scriptName] r]
fconfigure $f -buffering line
@@ -108,147 +102,184 @@ proc createChildProcess { ddeServerName {handler {}}} {
}
# -------------------------------------------------------------------------
+test winDde-1.0 {check if we are testing the right dll} {win dde} {
+ set ::ddever
+} {1.4.0}
-test winDde-1.1 {Settings the server's topic name} {win dde} {
+test winDde-1.1 {Settings the server's topic name} -constraints dde -body {
list [dde servername foobar] [dde servername] [dde servername self]
-} {foobar foobar self}
+} -result {foobar foobar self}
-test winDde-2.1 {Checking for other services} {win dde} {
+test winDde-2.1 {Checking for other services} -constraints dde -body {
expr [llength [dde services {} {}]] >= 0
-} 1
+} -result 1
test winDde-2.2 {Checking for existence, with service and topic specified} \
- {win dde} {
+ -constraints dde -body {
llength [dde services TclEval self]
-} 1
+} -result 1
test winDde-2.3 {Checking for existence, with only the service specified} \
- {win dde} {
+ -constraints dde -body {
expr [llength [dde services TclEval {}]] >= 1
-} 1
+} -result 1
test winDde-2.4 {Checking for existence, with only the topic specified} \
- {win dde} {
+ -constraints dde -body {
expr [llength [dde services {} self]] >= 1
-} 1
+} -result 1
# -------------------------------------------------------------------------
-test winDde-3.1 {DDE execute locally} {win dde} {
- set a ""
- dde execute TclEval self {set a "foo"}
- set a
-} foo
-test winDde-3.2 {DDE execute -async locally} {win dde} {
- set a ""
- dde execute -async TclEval self {set a "foo"}
+test winDde-3.1 {DDE execute locally} -constraints dde -body {
+ set \xe1 ""
+ dde execute TclEval self [list set \xe1 foo]
+ set \xe1
+} -result foo
+test winDde-3.2 {DDE execute -async locally} -constraints dde -body {
+ set \xe1 ""
+ dde execute -async TclEval self [list set \xe1 foo]
update
- set a
-} foo
-test winDde-3.3 {DDE request locally} {win dde} {
- set a ""
- dde execute TclEval self {set a "foo"}
- dde request TclEval self a
-} foo
-test winDde-3.4 {DDE eval locally} {win dde} {
- set a ""
- dde eval self set a "foo"
-} foo
-test winDde-3.5 {DDE request locally} {win dde} {
- set a ""
- dde execute TclEval self {set a "foo"}
- dde request -binary TclEval self a
-} "foo\x00"
+ set \xe1
+} -result foo
+test winDde-3.3 {DDE request locally} -constraints dde -body {
+ set \xe1 ""
+ dde execute TclEval self [list set \xe1 foo]
+ dde request TclEval self \xe1
+} -result foo
+test winDde-3.4 {DDE eval locally} -constraints dde -body {
+ set \xe1 ""
+ dde eval self set \xe1 foo
+} -result foo
+test winDde-3.5 {DDE request locally} -constraints dde -body {
+ set \xe1 ""
+ dde execute TclEval self [list set \xe1 foo]
+ dde request -binary TclEval self \xe1
+} -result "foo\x00"
+# Set variable a to A with diaeresis (unicode C4) by relying on the fact
+# that utf8 is sent (e.g. "c3 84" on the wire)
+test winDde-3.6 {DDE request utf8} -constraints dde -body {
+ set \xe1 "not set"
+ dde execute TclEval self "set \xe1 \xc4"
+ scan [set \xe1] %c
+} -result 196
+# Set variable a to A with diaeresis (unicode C4) using binary execute
+# and compose utf-8 (e.g. "c3 84" ) manualy
+test winDde-3.7 {DDE request binary} -constraints dde -body {
+ set \xe1 "not set"
+ dde execute -binary TclEval self [list set \xc3\xa1 \xc3\x84\x00]
+ scan [set \xe1] %c
+} -result 196
+test winDde-3.8 {DDE poke locally} -constraints {dde debug} -body {
+ set \xe1 ""
+ dde poke TclEval self \xe1 \xc4
+ dde request TclEval self \xe1
+} -result \xc4
+test winDde-3.9 {DDE poke -binary locally} -constraints {dde debug} -body {
+ set \xe1 ""
+ dde poke -binary TclEval self \xe1 \xc3\x84\x00
+ dde request TclEval self \xe1
+} -result \xc4
# -------------------------------------------------------------------------
-test winDde-4.1 {DDE execute remotely} {stdio win dde} {
- set a ""
- set name child-4.1
+test winDde-4.1 {DDE execute remotely} -constraints {dde stdio} -body {
+ set \xe1 ""
+ set name ch\xEDld-4.1
set child [createChildProcess $name]
- dde execute TclEval $name {set a "foo"}
+ dde execute TclEval $name [list set \xe1 foo]
dde execute TclEval $name {set done 1}
update
- set a
-} ""
-test winDde-4.2 {DDE execute async remotely} {stdio win dde} {
- set a ""
- set name child-4.2
+ set \xe1
+} -result ""
+test winDde-4.2 {DDE execute async remotely} -constraints {dde stdio} -body {
+ set \xe1 ""
+ set name ch\xEDld-4.2
set child [createChildProcess $name]
- dde execute -async TclEval $name {set a "foo"}
+ dde execute -async TclEval $name [list set \xe1 foo]
+ update
+ dde execute TclEval $name {set done 1}
update
+ set \xe1
+} -result ""
+test winDde-4.3 {DDE request remotely} -constraints {dde stdio} -body {
+ set \xe1 ""
+ set name ch\xEDld-4.3
+ set child [createChildProcess $name]
+ dde execute TclEval $name [list set \xe1 foo]
+ set \xe1 [dde request TclEval $name \xe1]
dde execute TclEval $name {set done 1}
update
- set a
-} ""
-test winDde-4.3 {DDE request remotely} {stdio win dde} {
- set a ""
- set name chile-4.3
+ set \xe1
+} -result foo
+test winDde-4.4 {DDE eval remotely} -constraints {dde stdio} -body {
+ set \xe1 ""
+ set name ch\xEDld-4.4
set child [createChildProcess $name]
- dde execute TclEval $name {set a "foo"}
- set a [dde request TclEval $name a]
+ set \xe1 [dde eval $name set \xe1 foo]
dde execute TclEval $name {set done 1}
update
- set a
-} foo
-test winDde-4.4 {DDE eval remotely} {stdio win dde} {
- set a ""
- set name child-4.4
+ set \xe1
+} -result foo
+test winDde-4.5 {DDE poke remotely} -constraints {dde debug stdio} -body {
+ set \xe1 ""
+ set name ch\xEDld-4.5
set child [createChildProcess $name]
- set a [dde eval $name set a "foo"]
+ dde poke TclEval $name \xe1 foo
+ set \xe1 [dde request TclEval $name \xe1]
dde execute TclEval $name {set done 1}
update
- set a
-} foo
+ set \xe1
+} -result foo
# -------------------------------------------------------------------------
-test winDde-5.1 {check for bad arguments} -constraints {win dde} -body {
+test winDde-5.1 {check for bad arguments} -constraints dde -body {
dde execute "" "" "" ""
-} -returnCodes error -result {wrong # args: should be "dde execute ?-async? serviceName topicName value"}
-test winDde-5.2 {check for bad arguments} -constraints {win dde} -body {
- dde execute "" "" ""
+} -returnCodes error -result {wrong # args: should be "dde execute ?-async? ?-binary? serviceName topicName value"}
+test winDde-5.2 {check for bad arguments} -constraints dde -body {
+ dde execute -binary "" "" ""
} -returnCodes error -result {cannot execute null data}
-test winDde-5.3 {check for bad arguments} -constraints {win dde} -body {
+test winDde-5.3 {check for bad arguments} -constraints dde -body {
dde execute -foo "" "" ""
-} -returnCodes error -result {wrong # args: should be "dde execute ?-async? serviceName topicName value"}
-test winDde-5.4 {DDE eval bad arguments} -constraints {win dde} -body {
+} -returnCodes error -result {wrong # args: should be "dde execute ?-async? ?-binary? serviceName topicName value"}
+test winDde-5.4 {DDE eval bad arguments} -constraints dde -body {
dde eval "" "foo"
} -returnCodes error -result {invalid service name ""}
# -------------------------------------------------------------------------
-test winDde-6.1 {DDE servername bad arguments} -constraints {win dde} -body {
+test winDde-6.1 {DDE servername bad arguments} -constraints dde -body {
dde servername -z -z -z
} -returnCodes error -result {bad option "-z": must be -force, -handler, or --}
-test winDde-6.2 {DDE servername set name} -constraints {win dde} -body {
+test winDde-6.2 {DDE servername set name} -constraints dde -body {
dde servername -- winDde-6.2
} -result {winDde-6.2}
-test winDde-6.3 {DDE servername set exact name} -constraints {win dde} -body {
+test winDde-6.3 {DDE servername set exact name} -constraints dde -body {
dde servername -force winDde-6.3
} -result {winDde-6.3}
-test winDde-6.4 {DDE servername set exact name} -constraints {win dde} -body {
+test winDde-6.4 {DDE servername set exact name} -constraints dde -body {
dde servername -force -- winDde-6.4
} -result {winDde-6.4}
-test winDde-6.5 {DDE remote servername collision} -constraints {stdio win dde} -setup {
- set name child-6.5
+test winDde-6.5 {DDE remote servername collision} -constraints {dde stdio} -setup {
+ set name ch\xEDld-6.5
set child [createChildProcess $name]
} -body {
dde servername -- $name
} -cleanup {
dde execute TclEval $name {set done 1}
update
-} -result "child-6.5 #2"
-test winDde-6.6 {DDE remote servername collision force} -constraints {stdio win dde} -setup {
- set name child-6.6
+} -result "ch\xEDld-6.5 #2"
+test winDde-6.6 {DDE remote servername collision force} -constraints {dde stdio} -setup {
+ set name ch\xEDld-6.6
set child [createChildProcess $name]
} -body {
dde servername -force -- $name
} -cleanup {
dde execute TclEval $name {set done 1}
update
-} -result {child-6.6}
+} -result "ch\xEDld-6.6"
# -------------------------------------------------------------------------
-test winDde-7.1 {Load DDE in slave interpreter } -constraints {win dde} -setup {
+test winDde-7.1 {Load DDE in slave interpreter} -constraints dde -setup {
interp create slave
} -body {
slave eval [list load $::ddelib Dde]
@@ -256,7 +287,7 @@ test winDde-7.1 {Load DDE in slave interpreter } -constraints {win dde} -setup {
} -cleanup {
interp delete slave
} -result {dde-interp-7.1}
-test winDde-7.2 {DDE slave cleanup} -constraints {win dde} -setup {
+test winDde-7.2 {DDE slave cleanup} -constraints dde -setup {
interp create slave
slave eval [list load $::ddelib Dde]
slave eval [list dde servername -- dde-interp-7.5]
@@ -269,7 +300,7 @@ test winDde-7.2 {DDE slave cleanup} -constraints {win dde} -setup {
set s
}
} -result {}
-test winDde-7.3 {DDE present in slave interp} -constraints {win dde} -setup {
+test winDde-7.3 {DDE present in slave interp} -constraints dde -setup {
interp create slave
slave eval [list load $::ddelib Dde]
slave eval [list dde servername -- dde-interp-7.3]
@@ -278,7 +309,7 @@ test winDde-7.3 {DDE present in slave interp} -constraints {win dde} -setup {
} -cleanup {
interp delete slave
} -result {{TclEval dde-interp-7.3}}
-test winDde-7.4 {interp name collision with -force} -constraints {win dde} -setup {
+test winDde-7.4 {interp name collision with -force} -constraints dde -setup {
interp create slave
slave eval [list load $::ddelib Dde]
slave eval [list dde servername -- dde-interp-7.4]
@@ -287,7 +318,7 @@ test winDde-7.4 {interp name collision with -force} -constraints {win dde} -setu
} -cleanup {
interp delete slave
} -result {dde-interp-7.4}
-test winDde-7.5 {interp name collision without -force} -constraints {win dde} -setup {
+test winDde-7.5 {interp name collision without -force} -constraints dde -setup {
interp create slave
slave eval [list load $::ddelib Dde]
slave eval [list dde servername -- dde-interp-7.5]
@@ -299,7 +330,7 @@ test winDde-7.5 {interp name collision without -force} -constraints {win dde} -s
# -------------------------------------------------------------------------
-test winDde-8.1 {Safe DDE load} -constraints {win dde} -setup {
+test winDde-8.1 {Safe DDE load} -constraints dde -setup {
interp create -safe slave
slave invokehidden load $::ddelib Dde
} -body {
@@ -307,20 +338,20 @@ test winDde-8.1 {Safe DDE load} -constraints {win dde} -setup {
} -cleanup {
interp delete slave
} -returnCodes error -result {invalid command name "dde"}
-test winDde-8.2 {Safe DDE set servername} -constraints {win dde} -setup {
+test winDde-8.2 {Safe DDE set servername} -constraints dde -setup {
interp create -safe slave
slave invokehidden load $::ddelib Dde
} -body {
slave invokehidden dde servername slave
} -cleanup {interp delete slave} -result {slave}
-test winDde-8.3 {Safe DDE check handler required for eval} -constraints {win dde} -setup {
+test winDde-8.3 {Safe DDE check handler required for eval} -constraints dde -setup {
interp create -safe slave
slave invokehidden load $::ddelib Dde
slave invokehidden dde servername slave
} -body {
catch {dde eval slave set a 1} msg
} -cleanup {interp delete slave} -result {1}
-test winDde-8.4 {Safe DDE check that execute is denied} -constraints {win dde} -setup {
+test winDde-8.4 {Safe DDE check that execute is denied} -constraints dde -setup {
interp create -safe slave
slave invokehidden load $::ddelib Dde
slave invokehidden dde servername slave
@@ -329,7 +360,7 @@ test winDde-8.4 {Safe DDE check that execute is denied} -constraints {win dde} -
dde execute TclEval slave {set a 2}
slave eval set a
} -cleanup {interp delete slave} -result 1
-test winDde-8.5 {Safe DDE check that request is denied} -constraints {win dde} -setup {
+test winDde-8.5 {Safe DDE check that request is denied} -constraints dde -setup {
interp create -safe slave
slave invokehidden load $::ddelib Dde
slave invokehidden dde servername slave
@@ -339,14 +370,14 @@ test winDde-8.5 {Safe DDE check that request is denied} -constraints {win dde} -
} -cleanup {
interp delete slave
} -returnCodes error -result {remote server cannot handle this command}
-test winDde-8.6 {Safe DDE assign handler procedure} -constraints {win dde} -setup {
+test winDde-8.6 {Safe DDE assign handler procedure} -constraints dde -setup {
interp create -safe slave
slave invokehidden load $::ddelib Dde
slave eval {proc DDEACCEPT {cmd} {set ::DDECMD $cmd}}
} -body {
slave invokehidden dde servername -handler DDEACCEPT slave
} -cleanup {interp delete slave} -result slave
-test winDde-8.7 {Safe DDE check simple command} -constraints {win dde} -setup {
+test winDde-8.7 {Safe DDE check simple command} -constraints dde -setup {
interp create -safe slave
slave invokehidden load $::ddelib Dde
slave eval {proc DDEACCEPT {cmd} {set ::DDECMD $cmd}}
@@ -354,7 +385,7 @@ test winDde-8.7 {Safe DDE check simple command} -constraints {win dde} -setup {
} -body {
dde eval slave set x 1
} -cleanup {interp delete slave} -result {set x 1}
-test winDde-8.8 {Safe DDE check non-list command} -constraints {win dde} -setup {
+test winDde-8.8 {Safe DDE check non-list command} -constraints dde -setup {
interp create -safe slave
slave invokehidden load $::ddelib Dde
slave eval {proc DDEACCEPT {cmd} {set ::DDECMD $cmd}}
@@ -364,16 +395,16 @@ test winDde-8.8 {Safe DDE check non-list command} -constraints {win dde} -setup
dde eval slave $s
string equal [slave eval set DDECMD] $s
} -cleanup {interp delete slave} -result 1
-test winDde-8.9 {Safe DDE check command evaluation} -constraints {win dde} -setup {
+test winDde-8.9 {Safe DDE check command evaluation} -constraints dde -setup {
interp create -safe slave
slave invokehidden load $::ddelib Dde
slave eval {proc DDEACCEPT {cmd} {set ::DDECMD [uplevel \#0 $cmd]}}
slave invokehidden dde servername -handler DDEACCEPT slave
} -body {
- dde eval slave set x 1
- slave eval set x
+ dde eval slave set \xe1 1
+ slave eval set \xe1
} -cleanup {interp delete slave} -result 1
-test winDde-8.10 {Safe DDE check command evaluation (2)} -constraints {win dde} -setup {
+test winDde-8.10 {Safe DDE check command evaluation (2)} -constraints dde -setup {
interp create -safe slave
slave invokehidden load $::ddelib Dde
slave eval {proc DDEACCEPT {cmd} {set ::DDECMD [uplevel \#0 $cmd]}}
@@ -382,7 +413,7 @@ test winDde-8.10 {Safe DDE check command evaluation (2)} -constraints {win dde}
dde eval slave [list set x 1]
slave eval set x
} -cleanup {interp delete slave} -result 1
-test winDde-8.11 {Safe DDE check command evaluation (3)} -constraints {win dde} -setup {
+test winDde-8.11 {Safe DDE check command evaluation (3)} -constraints dde -setup {
interp create -safe slave
slave invokehidden load $::ddelib Dde
slave eval {proc DDEACCEPT {cmd} {set ::DDECMD [uplevel \#0 $cmd]}}
@@ -394,9 +425,9 @@ test winDde-8.11 {Safe DDE check command evaluation (3)} -constraints {win dde}
# -------------------------------------------------------------------------
-test winDde-9.1 {External safe DDE check string passing} -constraints {win dde stdio} -setup {
- set name child-9.1
- set child [createChildProcess $name Handler1]
+test winDde-9.1 {External safe DDE check string passing} -constraints {dde stdio} -setup {
+ set name ch\xEDld-9.1
+ set child [createChildProcess $name -handler Handler1]
file copy -force script1.tcl dde-script.tcl
} -body {
dde eval $name set x 1
@@ -407,9 +438,9 @@ test winDde-9.1 {External safe DDE check string passing} -constraints {win dde s
update
file delete -force -- dde-script.tcl
} -result {set x 1}
-test winDde-9.2 {External safe DDE check command evaluation} -constraints {win dde stdio} -setup {
- set name child-9.2
- set child [createChildProcess $name Handler2]
+test winDde-9.2 {External safe DDE check command evaluation} -constraints {dde stdio} -setup {
+ set name ch\xEDld-9.2
+ set child [createChildProcess $name -handler Handler2]
file copy -force script1.tcl dde-script.tcl
} -body {
dde eval $name set x 1
@@ -420,9 +451,9 @@ test winDde-9.2 {External safe DDE check command evaluation} -constraints {win d
update
file delete -force -- dde-script.tcl
} -result 1
-test winDde-9.3 {External safe DDE check prefixed arguments} -constraints {win dde stdio} -setup {
- set name child-9.3
- set child [createChildProcess $name [list Handler3 ARG]]
+test winDde-9.3 {External safe DDE check prefixed arguments} -constraints {dde stdio} -setup {
+ set name ch\xEDld-9.3
+ set child [createChildProcess $name -handler [list Handler3 ARG]]
file copy -force script1.tcl dde-script.tcl
} -body {
dde eval $name set x 1
@@ -433,6 +464,19 @@ test winDde-9.3 {External safe DDE check prefixed arguments} -constraints {win d
update
file delete -force -- dde-script.tcl
} -result {ARG {set x 1}}
+test winDde-9.4 {External safe DDE check null data passing} -constraints {dde stdio} -setup {
+ set name ch\xEDld-9.4
+ set child [createChildProcess $name -handler Handler1]
+ file copy -force script1.tcl dde-script.tcl
+} -body {
+ dde execute TclEval $name ""
+ gets $child line
+ set line
+} -cleanup {
+ dde execute TclEval $name stop
+ update
+ file delete -force -- dde-script.tcl
+} -result {null data}
# -------------------------------------------------------------------------
diff --git a/tests/winFCmd.test b/tests/winFCmd.test
index b49356d..28257c6 100644
--- a/tests/winFCmd.test
+++ b/tests/winFCmd.test
@@ -15,6 +15,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
# Initialise the test constraints
testConstraint winVista 0
@@ -205,22 +208,11 @@ test winFCmd-1.13 {TclpRenameFile: errno: EACCES} -setup {
} -constraints {win win2000orXP testfile} -body {
testfile mv nul tf1
} -returnCodes error -result EINVAL
-test winFCmd-1.13.1 {TclpRenameFile: errno: EACCES} -setup {
+test winFCmd-1.14 {TclpRenameFile: errno: EACCES} -setup {
cleanup
} -constraints {win nt winOlderThan2000 testfile} -body {
testfile mv nul tf1
} -returnCodes error -result EACCES
-test winFCmd-1.13.2 {TclpRenameFile: errno: ENOENT} -setup {
- cleanup
-} -constraints {win 95 testfile} -body {
- testfile mv nul tf1
-} -returnCodes error -result ENOENT
-test winFCmd-1.14 {TclpRenameFile: errno: EACCES} -setup {
- cleanup
-} -constraints {win 95 testfile} -body {
- createfile tf1
- testfile mv tf1 nul
-} -returnCodes error -result EACCES
test winFCmd-1.15 {TclpRenameFile: errno: EEXIST} -setup {
cleanup
} -constraints {win nt testfile} -body {
@@ -254,11 +246,6 @@ test winFCmd-1.19.1 {TclpRenameFile: errno == EACCES} -setup {
} -constraints {win nt winOlderThan2000 testfile} -body {
testfile mv nul tf1
} -returnCodes error -result EACCES
-test winFCmd-1.19.2 {TclpRenameFile: errno == ENOENT} -setup {
- cleanup
-} -constraints {win 95 testfile} -body {
- testfile mv nul tf1
-} -returnCodes error -result ENOENT
test winFCmd-1.20 {TclpRenameFile: src is dir} -setup {
cleanup
} -constraints {win nt testfile} -body {
@@ -471,29 +458,14 @@ test winFCmd-2.6 {TclpCopyFile: errno: ENOENT} -setup {
} -returnCodes error -result ENOENT
test winFCmd-2.7 {TclpCopyFile: errno: EACCES} -setup {
cleanup
-} -constraints {win 95 testfile} -body {
- createfile tf1
- set fd [open tf2 w]
- testfile cp tf1 tf2
-} -cleanup {
- close $fd
- cleanup
-} -returnCodes error -result EACCES
-test winFCmd-2.8 {TclpCopyFile: errno: EACCES} -setup {
- cleanup
} -constraints {win win2000orXP testfile} -body {
testfile cp nul tf1
} -returnCodes error -result EINVAL
-test winFCmd-2.8.1 {TclpCopyFile: errno: EACCES} -setup {
+test winFCmd-2.8 {TclpCopyFile: errno: EACCES} -setup {
cleanup
} -constraints {win nt winOlderThan2000 testfile} -body {
testfile cp nul tf1
} -returnCodes error -result EACCES
-test winFCmd-2.9 {TclpCopyFile: errno: ENOENT} -setup {
- cleanup
-} -constraints {win 95 testfile} -body {
- testfile cp nul tf1
-} -returnCodes error -result ENOENT
test winFCmd-2.10 {TclpCopyFile: CopyFile succeeds} -setup {
cleanup
} -constraints {win testfile} -body {
@@ -570,17 +542,6 @@ test winFCmd-2.17 {TclpCopyFile: dst is readonly} -setup {
catch {testchmod 666 tf2}
cleanup
} -result {1 tf1}
-test winFCmd-2.18 {TclpCopyFile: still can't copy onto dst} -setup {
- cleanup
-} -constraints {win 95 testfile testchmod} -body {
- createfile tf1
- createfile tf2
- testchmod 000 tf2
- set fd [open tf2]
- set msg [list [catch {testfile cp tf1 tf2} msg] $msg]
- close $fd
- lappend msg [file writable tf2]
-} -result {1 EACCES 0}
test winFCmd-3.1 {TclpDeleteFile: errno: EACCES} -body {
testfile rm $cdfile $cdrom/dummy~~.fil
@@ -663,9 +624,6 @@ test winFCmd-3.11 {TclpDeleteFile: still can't remove path} -setup {
test winFCmd-4.1 {TclpCreateDirectory: errno: EACCES} -body {
testfile mkdir $cdrom/dummy~~.dir
} -constraints {win nt cdrom testfile} -returnCodes error -result EACCES
-test winFCmd-4.2 {TclpCreateDirectory: errno: EACCES} -body {
- testfile mkdir $cdrom/dummy~~.dir
-} -constraints {win 95 cdrom testfile} -returnCodes error -result ENOSPC
test winFCmd-4.3 {TclpCreateDirectory: errno: EEXIST} -setup {
cleanup
} -constraints {win testfile} -body {
@@ -761,11 +719,6 @@ test winFCmd-6.9 {TclpRemoveDirectory: errno == EACCES} -setup {
catch {testchmod 666 td1}
cleanup
} -result {td1 EACCES}
-test winFCmd-6.10 {TclpRemoveDirectory: attr == -1} -setup {
- cleanup
-} -constraints {win 95 testfile} -body {
- testfile rmdir nul
-} -returnCodes error -result {nul EACCES}
test winFCmd-6.11 {TclpRemoveDirectory: attr == -1} -setup {
cleanup
} -constraints {win nt testfile} -body {
@@ -773,16 +726,6 @@ test winFCmd-6.11 {TclpRemoveDirectory: attr == -1} -setup {
# WinXP returns EEXIST, WinNT seems to return EACCES. No policy
# decision has been made as to which is correct.
} -returnCodes error -match regexp -result {^/ E(ACCES|EXIST)$}
-# This next test has a very hokey way of matching...
-test winFCmd-6.12 {TclpRemoveDirectory: errno == EACCES} -setup {
- cleanup
-} -constraints {win 95 testfile} -body {
- createfile tf1
- set res [catch {testfile rmdir tf1} msg]
- # get rid of path
- set msg [list [file tail [lindex $msg 0]] [lindex $msg 1]]
- list $res $msg
-} -result {1 {tf1 ENOTDIR}}
test winFCmd-6.13 {TclpRemoveDirectory: write-protected} -setup {
cleanup
} -constraints {winVista testfile testchmod} -body {
@@ -795,16 +738,6 @@ test winFCmd-6.13 {TclpRemoveDirectory: write-protected} -setup {
cleanup
} -returnCodes error -result {td1 EACCES}
# This next test has a very hokey way of matching...
-test winFCmd-6.14 {TclpRemoveDirectory: check if empty dir} -setup {
- cleanup
-} -constraints {win 95 testfile} -body {
- file mkdir td1/td2
- set res [catch {testfile rmdir td1} msg]
- # get rid of path
- set msg [list [file tail [lindex $msg 0]] [lindex $msg 1]]
- list $res $msg
-} -result {1 {td1 EEXIST}}
-# This next test has a very hokey way of matching...
test winFCmd-6.15 {TclpRemoveDirectory: !recursive} -setup {
cleanup
} -constraints {win testfile} -body {
@@ -884,11 +817,6 @@ test winFCmd-7.7 {TraverseWinTree: append \ to source if necessary} -setup {
} -cleanup {
cleanup
} -result {tf1}
-test winFCmd-7.8 {TraverseWinTree: append \ to source if necessary} -body {
- # cdrom can return either d:\ or D:/, but we only care about the errcode
- testfile rmdir $cdrom/
-} -constraints {win 95 cdrom testfile} -returnCodes error -match glob \
- -result {* EACCES} ; # was EEXIST, but changed for win98.
test winFCmd-7.9 {TraverseWinTree: append \ to source if necessary} -body {
testfile rmdir $cdrom/
} -constraints {win nt cdrom testfile} -returnCodes error -match glob \
@@ -927,14 +855,6 @@ test winFCmd-7.13 {TraverseWinTree: append \ to target if necessary} -setup {
} -cleanup {
cleanup
} -result {tf1}
-test winFCmd-7.14 {TraverseWinTree: append \ to target if necessary} -setup {
- cleanup
-} -constraints {win 95 testfile} -body {
- file mkdir td1
- testfile cpdir td1 /
-} -cleanup {
- cleanup
-} -returnCodes error -result {/ EEXIST}
test winFCmd-7.15 {TraverseWinTree: append \ to target if necessary} -setup {
cleanup
} -constraints {win nt testfile} -body {
@@ -1035,15 +955,6 @@ test winFCmd-9.1 {TraversalDelete: DOTREE_F} -setup {
createfile td1/tf1
testfile rmdir -force td1
} -result {}
-test winFCmd-9.2 {TraversalDelete: DOTREE_F} -setup {
- cleanup
-} -constraints {win 95 testfile} -body {
- file mkdir td1
- set fd [open td1/tf1 w]
- testfile rmdir -force td1
-} -cleanup {
- close $fd
-} -returnCodes error -result {td1\tf1 EACCES}
test winFCmd-9.3 {TraversalDelete: DOTREE_PRED} -setup {
cleanup
} -constraints {winVista testfile testchmod} -body {
@@ -1474,10 +1385,10 @@ test winFCmd-19.5 {Windows extended path names} -constraints nt -setup {
list [catch {
set f [open $tmpfile [list WRONLY CREAT]]
close $f
- } res] errormsg ;#$res
+ } res] $res
} -cleanup {
catch {file delete $tmpfile}
-} -result [list 1 errormsg]
+} -result [list 0 {}]
test winFCmd-19.6 {Windows extended path names} -constraints nt -setup {
set tmpfile [file join $::env(TEMP) tcl[string repeat x 248].tmp]
set tmpfile //?/[file normalize $tmpfile]
diff --git a/tests/winFile.test b/tests/winFile.test
index ad34624..2c47f5f 100644
--- a/tests/winFile.test
+++ b/tests/winFile.test
@@ -16,6 +16,9 @@ if {[catch {package require tcltest 2.0.2}]} {
}
namespace import -force ::tcltest::*
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testvolumetype [llength [info commands testvolumetype]]
testConstraint notNTFS 0
testConstraint win2000 0
@@ -34,24 +37,6 @@ test winFile-1.2 {TclpGetUserHome} -constraints {win nt nonPortable} -body {
# The administrator account should always exist.
glob ~administrator
} -match glob -result *
-test winFile-1.3 {TclpGetUserHome} -constraints {win 95} -body {
- # Find some user in system.ini and then see if they have a home.
-
- set f [open $::env(windir)/system.ini]
- while {[gets $f line] >= 0} {
- if {$line ne {[Password Lists]}} {
- continue
- }
- gets $f
- set name [lindex [split [gets $f] =] 0]
- if {$name ne ""} {
- return [catch {glob ~$name}]
- }
- }
- return 0 ;# didn't find anything...
-} -cleanup {
- catch {close $f}
-} -result {0}
test winFile-1.4 {TclpGetUserHome} {win nt nonPortable} {
catch {glob ~stanton@workgroup}
} {0}
diff --git a/tests/winNotify.test b/tests/winNotify.test
index f9c75a3..3e9aa29 100644
--- a/tests/winNotify.test
+++ b/tests/winNotify.test
@@ -15,6 +15,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testeventloop [expr {[info commands testeventloop] != {}}]
# There is no explicit test for InitNotifier or NotifierExitHandler
diff --git a/tests/winPipe.test b/tests/winPipe.test
index 62d7d0d..9c6f94d 100644
--- a/tests/winPipe.test
+++ b/tests/winPipe.test
@@ -16,6 +16,12 @@ package require tcltest
namespace import -force ::tcltest::*
unset -nocomplain path
+catch {
+ ::tcltest::loadTestedCommands
+ package require -exact Tcltest [info patchlevel]
+ set ::tcltestlib [lindex [package ifneeded Tcltest [info patchlevel]] 1]
+}
+
set bindir [file join [pwd] [file dirname [info nameofexecutable]]]
set cat32 [file join $bindir cat32.exe]
@@ -23,6 +29,8 @@ testConstraint exec [llength [info commands exec]]
testConstraint cat32 [file exists $cat32]
testConstraint AllocConsole [catch {puts console1 ""}]
testConstraint RealConsole [expr {![testConstraint AllocConsole]}]
+testConstraint testexcept [llength [info commands testexcept]]
+
set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
append big $big
@@ -74,10 +82,6 @@ test winpipe-1.4 {32 bit comprehensive tests: a lot from pipe} {win nt exec cat3
exec [interpreter] $path(more) < $path(big) | $cat32 > $path(stdout) 2> $path(stderr)
list [contents $path(stdout)] [contents $path(stderr)]
} "{$big} stderr32"
-test winpipe-1.5 {32 bit comprehensive tests: a lot from pipe} {win 95 exec cat32} {
- exec command /c type $path(big) |& $cat32 > $path(stdout) 2> $path(stderr)
- list [contents $path(stdout)] [contents $path(stderr)]
-} "{$big} stderr32"
test winpipe-1.6 {32 bit comprehensive tests: from console} \
{win cat32 AllocConsole} {
# would block waiting for human input
@@ -166,10 +170,6 @@ test winpipe-1.21 {32 bit comprehensive tests: read/write application} \
catch {close $f}
set r
} "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
-test winpipe-1.22 {Checking command.com for Win95/98 hanging} {win 95 exec} {
- exec command.com /c dir /b
- set result 1
-} 1
test winpipe-4.1 {Tcl_WaitPid} {win nt exec cat32} {
proc readResults {f} {
@@ -190,30 +190,34 @@ test winpipe-4.1 {Tcl_WaitPid} {win nt exec cat32} {
vwait x
list $result $x [contents $path(stderr)]
} "{$big} 1 stderr32"
-test winpipe-4.2 {Tcl_WaitPid: return of exception codes, SIGFPE} {win exec} {
+test winpipe-4.2 {Tcl_WaitPid: return of exception codes, SIGFPE} {win exec testexcept} {
set f [open "|[list [interpreter]]" w+]
set pid [pid $f]
+ puts $f "load $::tcltestlib Tcltest"
puts $f "testexcept float_underflow"
set status [catch {close $f}]
list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
} {1 1 SIGFPE}
-test winpipe-4.3 {Tcl_WaitPid: return of exception codes, SIGSEGV} {win exec} {
+test winpipe-4.3 {Tcl_WaitPid: return of exception codes, SIGSEGV} {win exec testexcept} {
set f [open "|[list [interpreter]]" w+]
set pid [pid $f]
+ puts $f "load $::tcltestlib Tcltest"
puts $f "testexcept access_violation"
set status [catch {close $f}]
list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
} {1 1 SIGSEGV}
-test winpipe-4.4 {Tcl_WaitPid: return of exception codes, SIGILL} {win exec} {
+test winpipe-4.4 {Tcl_WaitPid: return of exception codes, SIGILL} {win exec testexcept} {
set f [open "|[list [interpreter]]" w+]
set pid [pid $f]
+ puts $f "load $::tcltestlib Tcltest"
puts $f "testexcept illegal_instruction"
set status [catch {close $f}]
list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
} {1 1 SIGILL}
-test winpipe-4.5 {Tcl_WaitPid: return of exception codes, SIGINT} {win exec} {
+test winpipe-4.5 {Tcl_WaitPid: return of exception codes, SIGINT} {win exec testexcept} {
set f [open "|[list [interpreter]]" w+]
set pid [pid $f]
+ puts $f "load $::tcltestlib Tcltest"
puts $f "testexcept ctrl+c"
set status [catch {close $f}]
list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
diff --git a/tests/winTime.test b/tests/winTime.test
index 278db32..add8f98 100644
--- a/tests/winTime.test
+++ b/tests/winTime.test
@@ -15,6 +15,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
testConstraint testwinclock [llength [info commands testwinclock]]
# The next two tests will crash on Windows if the check for negative
diff --git a/tests/zlib.test b/tests/zlib.test
index dac11e4..4e51ebb 100644
--- a/tests/zlib.test
+++ b/tests/zlib.test
@@ -10,12 +10,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} {
+if {"::tcltest" ni [namespace children]} {
package require tcltest 2.1
namespace import -force ::tcltest::*
}
testConstraint zlib [llength [info commands zlib]]
+testConstraint recentZlib 0
+catch {
+ # Work around a bug in some versions of zlib; known to manifest on at
+ # least Mac OS X Mountain Lion...
+ testConstraint recentZlib \
+ [package vsatisfies [zlib::pkgconfig get zlibVersion] 1.2.6]
+}
test zlib-1.1 {zlib basics} -constraints zlib -returnCodes error -body {
zlib
@@ -23,6 +30,12 @@ test zlib-1.1 {zlib basics} -constraints zlib -returnCodes error -body {
test zlib-1.2 {zlib basics} -constraints zlib -returnCodes error -body {
zlib ? {}
} -result {bad command "?": must be adler32, compress, crc32, decompress, deflate, gunzip, gzip, inflate, push, or stream}
+test zlib-1.3 {zlib basics} -constraints zlib -body {
+ zlib::pkgconfig list
+} -result zlibVersion
+test zlib-1.4 {zlib basics} -constraints zlib -body {
+ package present zlib
+} -result 2.0
test zlib-2.1 {zlib compress/decompress} zlib {
zlib decompress [zlib compress abcdefghijklm]
@@ -70,7 +83,7 @@ test zlib-7.0 {zlib stream} -constraints zlib -returnCodes error -setup {
$s ?
} -cleanup {
$s close
-} -result {bad option "?": must be add, checksum, close, eof, finalize, flush, fullflush, get, put, or reset}
+} -result {bad option "?": must be add, checksum, close, eof, finalize, flush, fullflush, get, header, put, or reset}
test zlib-7.1 {zlib stream} zlib {
set s [zlib stream compress]
$s put -finalize abcdeEDCBA
@@ -103,6 +116,22 @@ test zlib-7.4 {zlib stream} zlib {
$s close
lappend result $data
} {{} 1 abcdeEDCBA}
+test zlib-7.5 {zlib stream} zlib {
+ set s [zlib stream gzip]
+ $s put -finalize abcdeEDCBA..
+ set data [$s get]
+ set result [list [$s get] [format %x [$s checksum]]]
+ $s close
+ lappend result [zlib gunzip $data]
+} {{} 69f34b6a abcdeEDCBA..}
+test zlib-7.6 {zlib stream} zlib {
+ set s [zlib stream gunzip]
+ $s put -finalize [zlib gzip abcdeEDCBA..]
+ set data [$s get]
+ set result [list [$s get] [format %x [$s checksum]]]
+ $s close
+ lappend result $data
+} {{} 69f34b6a abcdeEDCBA..}
test zlib-8.1 {zlib transformation} -constraints zlib -setup {
set file [makeFile {} test.gz]
@@ -130,7 +159,7 @@ test zlib-8.2 {zlib transformation} -constraints zlib -setup {
} -result ok
test zlib-8.3 {zlib transformation and fileevent} -constraints zlib -setup {
set srv [socket -myaddr localhost -server {apply {{c a p} {
- fconfigure $c -translation binary
+ fconfigure $c -translation binary -buffering none -blocking 0
puts -nonewline $c [zlib gzip [string repeat a 81920]]
close $c
}}} 0]
@@ -147,6 +176,7 @@ test zlib-8.3 {zlib transformation and fileevent} -constraints zlib -setup {
set ::total [expr {$e eq {} ? $c : $e}]
}}}
vwait total
+ after cancel {set total timeout}
} finally {
close $sin
}
@@ -156,6 +186,215 @@ test zlib-8.3 {zlib transformation and fileevent} -constraints zlib -setup {
close $srv
removeFile $file
} -result 81920-->81920
+test zlib-8.4 {transformation and flushing: Bug 3517696} -setup {
+ set file [makeFile {} test.z]
+ set fd [open $file w]
+} -constraints zlib -body {
+ zlib push compress $fd
+ puts $fd "qwertyuiop"
+ fconfigure $fd -flush sync
+ puts $fd "qwertyuiop"
+} -cleanup {
+ catch {close $fd}
+ removeFile $file
+} -result {}
+test zlib-8.5 {transformation and flushing and fileevents: Bug 3525907} -setup {
+ foreach {r w} [chan pipe] break
+} -constraints zlib -body {
+ set ::res {}
+ fconfigure $w -buffering none
+ zlib push compress $w
+ puts -nonewline $w qwertyuiop
+ chan configure $w -flush sync
+ after 500 {puts -nonewline $w asdfghjkl;close $w}
+ fconfigure $r -blocking 0 -buffering none
+ zlib push decompress $r
+ fileevent $r readable {set msg [read $r];lappend ::res $msg;if {[eof $r]} {set ::done 1}}
+ after 250 {lappend ::res MIDDLE}
+ vwait ::done
+ set ::res
+} -cleanup {
+ catch {close $r}
+} -result {qwertyuiop MIDDLE asdfghjkl}
+test zlib-8.6 {transformation and fconfigure} -setup {
+ set file [makeFile {} test.z]
+ set fd [open $file wb]
+} -constraints zlib -body {
+ list [fconfigure $fd] [zlib push compress $fd; fconfigure $fd] \
+ [chan pop $fd; fconfigure $fd]
+} -cleanup {
+ catch {close $fd}
+ removeFile $file
+} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf -checksum 1 -dictionary {}} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf}}
+test zlib-8.7 {transformation and fconfigure} -setup {
+ set file [makeFile {} test.gz]
+ set fd [open $file wb]
+} -constraints zlib -body {
+ list [fconfigure $fd] [zlib push gzip $fd; fconfigure $fd] \
+ [chan pop $fd; fconfigure $fd]
+} -cleanup {
+ catch {close $fd}
+ removeFile $file
+} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf -checksum 0} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf}}
+# Input is headers from fetching SPDY draft
+# Dictionary is that which is proposed _in_ SPDY draft
+set spdyHeaders "HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nX-Robots-Tag: noarchive\r\nLast-Modified: Tue, 05 Jun 2012 02:43:25 GMT\r\nETag: \"1338864205129|#public|0|en|||0\"\r\nExpires: Tue, 05 Jun 2012 16:17:11 GMT\r\nDate: Tue, 05 Jun 2012 16:17:06 GMT\r\nCache-Control: public, max-age=5\r\nX-Content-Type-Options: nosniff\r\nX-XSS-Protection: 1; mode=block\r\nServer: GSE\r\n"
+set spdyDict "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchif-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser-agent100101200201202203204205206300301302303304305306307400401402403404405406407408409410411412413414415416417500501502503504505accept-rangesageetaglocationproxy-authenticatepublicretry-afterservervarywarningwww-authenticateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertransfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locationcontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMondayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSepOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplication/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1.1statusversionurl"
+test zlib-8.8 {transformation and fconfigure} -setup {
+ lassign [chan pipe] inSide outSide
+} -constraints zlib -body {
+ zlib push compress $outSide -dictionary $spdyDict
+ fconfigure $outSide -blocking 0 -translation binary -buffering none
+ fconfigure $inSide -blocking 0 -translation binary
+ puts -nonewline $outSide $spdyHeaders
+ chan pop $outSide
+ set compressed [read $inSide]
+ catch {zlib decompress $compressed} err opt
+ list [string length [zlib compress $spdyHeaders]] \
+ [string length $compressed] \
+ $err [dict get $opt -errorcode] [zlib adler32 $spdyDict]
+} -cleanup {
+ catch {close $outSide}
+ catch {close $inSide}
+} -result {260 222 {need dictionary} {TCL ZLIB NEED_DICT 2381337010} 2381337010}
+test zlib-8.9 {transformation and fconfigure} -setup {
+ lassign [chan pipe] inSide outSide
+ set strm [zlib stream decompress]
+} -constraints zlib -body {
+ zlib push compress $outSide -dictionary $spdyDict
+ fconfigure $outSide -blocking 0 -translation binary -buffering none
+ fconfigure $inSide -blocking 0 -translation binary
+ puts -nonewline $outSide $spdyHeaders
+ set result [fconfigure $outSide -checksum]
+ chan pop $outSide
+ $strm put -dictionary $spdyDict [read $inSide]
+ lappend result [string length $spdyHeaders] [string length [$strm get]]
+} -cleanup {
+ catch {close $outSide}
+ catch {close $inSide}
+ catch {$strm close}
+} -result {3064818174 358 358}
+test zlib-8.10 {transformation and fconfigure} -setup {
+ lassign [chan pipe] inSide outSide
+} -constraints {zlib recentZlib} -body {
+ zlib push deflate $outSide -dictionary $spdyDict
+ fconfigure $outSide -blocking 0 -translation binary -buffering none
+ fconfigure $inSide -blocking 0 -translation binary
+ puts -nonewline $outSide $spdyHeaders
+ chan pop $outSide
+ set compressed [read $inSide]
+ catch {
+ zlib inflate $compressed
+ throw UNREACHABLE "should be unreachable"
+ } err opt
+ list [string length [zlib deflate $spdyHeaders]] \
+ [string length $compressed] \
+ $err [dict get $opt -errorcode]
+} -cleanup {
+ catch {close $outSide}
+ catch {close $inSide}
+} -result {254 212 {data error} {TCL ZLIB DATA}}
+test zlib-8.11 {transformation and fconfigure} -setup {
+ lassign [chan pipe] inSide outSide
+ set strm [zlib stream inflate]
+} -constraints zlib -body {
+ zlib push deflate $outSide -dictionary $spdyDict
+ fconfigure $outSide -blocking 0 -translation binary -buffering none
+ fconfigure $inSide -blocking 0 -translation binary
+ puts -nonewline $outSide $spdyHeaders
+ chan pop $outSide
+ $strm put -dictionary $spdyDict [read $inSide]
+ list [string length $spdyHeaders] [string length [$strm get]]
+} -cleanup {
+ catch {close $outSide}
+ catch {close $inSide}
+ catch {$strm close}
+} -result {358 358}
+test zlib-8.12 {transformation and fconfigure} -setup {
+ lassign [chan pipe] inSide outSide
+ set strm [zlib stream compress]
+} -constraints zlib -body {
+ $strm put -dictionary $spdyDict -finalize $spdyHeaders
+ zlib push decompress $inSide
+ fconfigure $outSide -blocking 0 -translation binary
+ fconfigure $inSide -translation binary -dictionary $spdyDict
+ puts -nonewline $outSide [$strm get]
+ close $outSide
+ list [string length $spdyHeaders] [string length [read $inSide]] \
+ [fconfigure $inSide -checksum]
+} -cleanup {
+ catch {close $outSide}
+ catch {close $inSide}
+ catch {$strm close}
+} -result {358 358 3064818174}
+test zlib-8.13 {transformation and fconfigure} -setup {
+ lassign [chan pipe] inSide outSide
+ set strm [zlib stream compress]
+} -constraints zlib -body {
+ $strm put -dictionary $spdyDict -finalize $spdyHeaders
+ zlib push decompress $inSide -dictionary $spdyDict
+ fconfigure $outSide -blocking 0 -translation binary
+ fconfigure $inSide -translation binary
+ puts -nonewline $outSide [$strm get]
+ close $outSide
+ list [string length $spdyHeaders] [string length [read $inSide]] \
+ [fconfigure $inSide -checksum]
+} -cleanup {
+ catch {close $outSide}
+ catch {close $inSide}
+ catch {$strm close}
+} -result {358 358 3064818174}
+test zlib-8.14 {transformation and fconfigure} -setup {
+ lassign [chan pipe] inSide outSide
+ set strm [zlib stream deflate]
+} -constraints zlib -body {
+ $strm put -finalize -dictionary $spdyDict $spdyHeaders
+ zlib push inflate $inSide
+ fconfigure $outSide -blocking 0 -buffering none -translation binary
+ fconfigure $inSide -translation binary -dictionary $spdyDict
+ puts -nonewline $outSide [$strm get]
+ close $outSide
+ list [string length $spdyHeaders] [string length [read $inSide]]
+} -cleanup {
+ catch {close $outSide}
+ catch {close $inSide}
+ catch {$strm close}
+} -result {358 358}
+test zlib-8.15 {transformation and fconfigure} -setup {
+ lassign [chan pipe] inSide outSide
+ set strm [zlib stream deflate]
+} -constraints zlib -body {
+ $strm put -finalize -dictionary $spdyDict $spdyHeaders
+ zlib push inflate $inSide -dictionary $spdyDict
+ fconfigure $outSide -blocking 0 -buffering none -translation binary
+ fconfigure $inSide -translation binary
+ puts -nonewline $outSide [$strm get]
+ close $outSide
+ list [string length $spdyHeaders] [string length [read $inSide]]
+} -cleanup {
+ catch {close $outSide}
+ catch {close $inSide}
+ catch {$strm close}
+} -result {358 358}
+test zlib-8.16 {Bug 3603553: buffer transfer with large writes} -setup {
+ # Actual data isn't very important; needs to be substantially larger than
+ # the internal buffer (32kB) and incompressible.
+ set largeData {}
+ for {set i 0;expr srand(1)} {$i < 100000} {incr i} {
+ append largeData [lindex "a b c d e f g h i j k l m n o p" \
+ [expr {int(16*rand())}]]
+ }
+ set file [makeFile {} test.gz]
+} -constraints zlib -body {
+ set f [open $file wb]
+ fconfigure $f -buffering none
+ zlib push gzip $f
+ puts -nonewline $f $largeData
+ close $f
+ file size $file
+} -cleanup {
+ removeFile $file
+} -result 57647
test zlib-9.1 "check fcopy with push" -constraints zlib -setup {
set sfile [makeFile {} testsrc.gz]
@@ -175,7 +414,7 @@ test zlib-9.1 "check fcopy with push" -constraints zlib -setup {
} -result {copied 81920 size 81920}
test zlib-9.2 "socket fcopy with push" -constraints zlib -setup {
set srv [socket -myaddr localhost -server {apply {{c a p} {
- chan configure $c -encoding binary -translation binary
+ chan configure $c -translation binary -buffering none -blocking 0
puts -nonewline $c [zlib gzip [string repeat a 81920]]
close $c
}}} 0]
@@ -197,7 +436,7 @@ test zlib-9.2 "socket fcopy with push" -constraints zlib -setup {
test zlib-9.3 "socket fcopy bg (identity)" -constraints {tempNotWin zlib} -setup {
set srv [socket -myaddr localhost -server {apply {{c a p} {
#puts "connection from $a:$p on $c"
- chan configure $c -encoding binary -translation binary
+ chan configure $c -translation binary -buffering none -blocking 0
puts -nonewline $c [string repeat a 81920]
close $c
}}} 0]
@@ -214,6 +453,7 @@ test zlib-9.3 "socket fcopy bg (identity)" -constraints {tempNotWin zlib} -setup
set ::total [expr {$e eq {} ? $c : $e}]
}}}
vwait ::total
+ after cancel {set ::total timeout}
close $sin; close $fout
list read $::total size [file size $file]
} -cleanup {
@@ -222,7 +462,7 @@ test zlib-9.3 "socket fcopy bg (identity)" -constraints {tempNotWin zlib} -setup
} -returnCodes {ok error} -result {read 81920 size 81920}
test zlib-9.4 "socket fcopy bg (gzip)" -constraints zlib -setup {
set srv [socket -myaddr localhost -server {apply {{c a p} {
- chan configure $c -encoding binary -translation binary
+ chan configure $c -translation binary -buffering none -blocking 0
puts -nonewline $c [zlib gzip [string repeat a 81920]]
close $c
}}} 0]
@@ -239,6 +479,7 @@ test zlib-9.4 "socket fcopy bg (gzip)" -constraints zlib -setup {
set ::total [expr {$e eq {} ? $c : $e}]
}}}
vwait ::total
+ after cancel {set ::total timeout}
close $sin; close $fout
list read $::total size [file size $file]
} -cleanup {
@@ -247,7 +488,7 @@ test zlib-9.4 "socket fcopy bg (gzip)" -constraints zlib -setup {
} -result {read 81920 size 81920}
test zlib-9.5 "socket fcopy incremental (gzip)" -constraints zlib -setup {
set srv [socket -myaddr localhost -server {apply {{c a p} {
- chan configure $c -encoding binary -translation binary
+ chan configure $c -translation binary -buffering none -blocking 0
puts -nonewline $c [zlib gzip [string repeat a 81920]]
close $c
}}} 0]
@@ -272,6 +513,7 @@ test zlib-9.5 "socket fcopy incremental (gzip)" -constraints zlib -setup {
after 1000 {set ::total timeout}
fcopy $sin $fout -size 8192 -command [list zlib95copy $sin $fout 0]
vwait ::total
+ after cancel {set ::total timeout}
close $sin; close $fout
list $::total size [file size $file]
} -cleanup {
@@ -281,7 +523,7 @@ test zlib-9.5 "socket fcopy incremental (gzip)" -constraints zlib -setup {
} -result {{eof 81920} size 81920}
test zlib-9.6 "bug #2818131 (gzip)" -constraints zlib -setup {
set srv [socket -myaddr localhost -server {apply {{c a p} {
- chan configure $c -translation binary -buffering none
+ chan configure $c -translation binary -buffering none -blocking 0
zlib push gzip $c
puts -nonewline $c [string repeat hello 100]
close $c
@@ -290,7 +532,7 @@ test zlib-9.6 "bug #2818131 (gzip)" -constraints zlib -setup {
lassign [chan configure $srv -sockname] addr name port
after 1000 {set ::total timeout}
set s [socket $addr $port]
- chan configure $s -translation binary -buffering none
+ chan configure $s -translation binary
zlib push gunzip $s
chan event $s readable [list apply {{s} {
set d [read $s]
@@ -300,6 +542,7 @@ test zlib-9.6 "bug #2818131 (gzip)" -constraints zlib -setup {
}
}} $s]
vwait ::total
+ after cancel {set ::total timeout}
close $s
set ::total
} -cleanup {
@@ -308,7 +551,7 @@ test zlib-9.6 "bug #2818131 (gzip)" -constraints zlib -setup {
} -result {eof 500}
test zlib-9.7 "bug #2818131 (compress)" -constraints zlib -setup {
set srv [socket -myaddr localhost -server {apply {{c a p} {
- chan configure $c -translation binary -buffering none
+ chan configure $c -translation binary -buffering none -blocking 0
zlib push compress $c
puts -nonewline $c [string repeat hello 100]
close $c
@@ -317,7 +560,7 @@ test zlib-9.7 "bug #2818131 (compress)" -constraints zlib -setup {
lassign [chan configure $srv -sockname] addr name port
after 1000 {set ::total timeout}
set s [socket $addr $port]
- chan configure $s -translation binary -buffering none
+ chan configure $s -translation binary
zlib push decompress $s
chan event $s readable [list apply {{s} {
set d [read $s]
@@ -327,6 +570,7 @@ test zlib-9.7 "bug #2818131 (compress)" -constraints zlib -setup {
}
}} $s]
vwait ::total
+ after cancel {set ::total timeout}
close $s
set ::total
} -cleanup {
@@ -335,7 +579,7 @@ test zlib-9.7 "bug #2818131 (compress)" -constraints zlib -setup {
} -result {eof 500}
test zlib-9.8 "bug #2818131 (deflate)" -constraints zlib -setup {
set srv [socket -myaddr localhost -server {apply {{c a p} {
- chan configure $c -translation binary -buffering none
+ chan configure $c -translation binary -buffering none -blocking 0
zlib push deflate $c
puts -nonewline $c [string repeat hello 100]
close $c
@@ -344,7 +588,7 @@ test zlib-9.8 "bug #2818131 (deflate)" -constraints zlib -setup {
lassign [chan configure $srv -sockname] addr name port
after 1000 {set ::total timeout}
set s [socket $addr $port]
- chan configure $s -translation binary -buffering none
+ chan configure $s -translation binary
zlib push inflate $s
chan event $s readable [list apply {{s} {
set d [read $s]
@@ -354,6 +598,7 @@ test zlib-9.8 "bug #2818131 (deflate)" -constraints zlib -setup {
}
}} $s]
vwait ::total
+ after cancel {set ::total timeout}
close $s
set ::total
} -cleanup {
@@ -363,7 +608,7 @@ test zlib-9.8 "bug #2818131 (deflate)" -constraints zlib -setup {
test zlib-9.9 "bug #2818131 (gzip mismatch)" -constraints zlib -setup {
proc bgerror {s} {set ::total [list error $s]}
set srv [socket -myaddr localhost -server {apply {{c a p} {
- chan configure $c -translation binary -buffering none
+ chan configure $c -translation binary -buffering none -blocking 0
zlib push gzip $c
puts -nonewline $c [string repeat hello 100]
close $c
@@ -373,7 +618,7 @@ test zlib-9.9 "bug #2818131 (gzip mismatch)" -constraints zlib -setup {
after 1000 {set ::total timeout}
set s [socket $addr $port]
try {
- chan configure $s -translation binary -buffering none
+ chan configure $s -translation binary
zlib push inflate $s
chan event $s readable [list apply {{s} {
set d [read $s]
@@ -384,6 +629,7 @@ test zlib-9.9 "bug #2818131 (gzip mismatch)" -constraints zlib -setup {
}} $s]
vwait ::total
} finally {
+ after cancel {set ::total timeout}
close $s
}
set ::total
@@ -395,7 +641,7 @@ test zlib-9.9 "bug #2818131 (gzip mismatch)" -constraints zlib -setup {
test zlib-9.10 "bug #2818131 (compress mismatch)" -constraints zlib -setup {
proc bgerror {s} {set ::total [list error $s]}
set srv [socket -myaddr localhost -server {apply {{c a p} {
- chan configure $c -translation binary -buffering none
+ chan configure $c -translation binary -buffering none -blocking 0
zlib push compress $c
puts -nonewline $c [string repeat hello 100]
close $c
@@ -405,7 +651,7 @@ test zlib-9.10 "bug #2818131 (compress mismatch)" -constraints zlib -setup {
after 1000 {set ::total timeout}
set s [socket $addr $port]
try {
- chan configure $s -translation binary -buffering none
+ chan configure $s -translation binary
zlib push inflate $s
chan event $s readable [list apply {{s} {
set d [read $s]
@@ -416,6 +662,7 @@ test zlib-9.10 "bug #2818131 (compress mismatch)" -constraints zlib -setup {
}} $s]
vwait ::total
} finally {
+ after cancel {set ::total timeout}
close $s
}
set ::total
@@ -427,7 +674,7 @@ test zlib-9.10 "bug #2818131 (compress mismatch)" -constraints zlib -setup {
test zlib-9.11 "bug #2818131 (deflate mismatch)" -constraints zlib -setup {
proc bgerror {s} {set ::total [list error $s]}
set srv [socket -myaddr localhost -server {apply {{c a p} {
- chan configure $c -translation binary -buffering none
+ chan configure $c -translation binary -buffering none -blocking 0
zlib push deflate $c
puts -nonewline $c [string repeat hello 100]
close $c
@@ -437,7 +684,7 @@ test zlib-9.11 "bug #2818131 (deflate mismatch)" -constraints zlib -setup {
after 1000 {set ::total timeout}
set s [socket $addr $port]
try {
- chan configure $s -translation binary -buffering none
+ chan configure $s -translation binary
zlib push gunzip $s
chan event $s readable [list apply {{s} {
set d [read $s]
@@ -448,6 +695,7 @@ test zlib-9.11 "bug #2818131 (deflate mismatch)" -constraints zlib -setup {
}} $s]
vwait ::total
} finally {
+ after cancel {set ::total timeout}
close $s
}
set ::total
@@ -462,7 +710,7 @@ test zlib-10.0 "bug #2818131 (close with null interp)" -constraints {
} -setup {
proc bgerror {s} {set ::total [list error $s]}
set srv [socket -myaddr localhost -server {apply {{c a p} {
- chan configure $c -translation binary -buffering none
+ chan configure $c -translation binary
zlib push inflate $c
chan event $c readable [list apply {{c} {
set d [read $c]
@@ -477,7 +725,7 @@ test zlib-10.0 "bug #2818131 (close with null interp)" -constraints {
lassign [chan configure $srv -sockname] addr name port
after 1000 {set ::total timeout}
set s [socket $addr $port]
- chan configure $s -translation binary -buffering none
+ chan configure $s -translation binary -buffering none -blocking 0
zlib push gzip $s
chan event $s xyzzy [list apply {{s} {
if {[gets $s line] < 0} {
@@ -490,6 +738,8 @@ test zlib-10.0 "bug #2818131 (close with null interp)" -constraints {
after 100 {set ::total done}
}} $s]
vwait ::total
+ after cancel {set ::total timeout}
+ after cancel {set ::total done}
set ::total
} -cleanup {
close $srv
@@ -509,7 +759,7 @@ test zlib-10.1 "bug #2818131 (mismatch read)" -constraints {
}
}
set srv [socket -myaddr localhost -server {apply {{c a p} {
- chan configure $c -translation binary -buffering none
+ chan configure $c -translation binary
zlib push inflate $c
chan event $c readable [list zlibRead $c]
}}} 0]
@@ -517,7 +767,7 @@ test zlib-10.1 "bug #2818131 (mismatch read)" -constraints {
lassign [chan configure $srv -sockname] addr name port
after 1000 {set ::total timeout}
set s [socket $addr $port]
- chan configure $s -translation binary -buffering none
+ chan configure $s -translation binary -buffering none -blocking 0
zlib push gzip $s
chan event $s readable [list zlibRead $s]
after idle [list apply {{s} {
@@ -526,6 +776,8 @@ test zlib-10.1 "bug #2818131 (mismatch read)" -constraints {
after 100 {set ::total done}
}} $s]
vwait ::total
+ after cancel {set ::total timeout}
+ after cancel {set ::total done}
set ::total
} -cleanup {
close $srv
@@ -547,7 +799,7 @@ test zlib-10.2 "bug #2818131 (mismatch gets)" -constraints {
}
}
set srv [socket -myaddr localhost -server {apply {{c a p} {
- chan configure $c -translation binary -buffering none
+ chan configure $c -translation binary
zlib push inflate $c
chan event $c readable [list zlibRead $c]
}}} 0]
@@ -555,7 +807,7 @@ test zlib-10.2 "bug #2818131 (mismatch gets)" -constraints {
lassign [chan configure $srv -sockname] addr name port
after 1000 {set ::total timeout}
set s [socket $addr $port]
- chan configure $s -translation binary -buffering none
+ chan configure $s -translation binary -buffering none -blocking 0
zlib push gzip $s
chan event $s readable [list zlibRead $s]
after idle [list apply {{s} {
@@ -564,6 +816,8 @@ test zlib-10.2 "bug #2818131 (mismatch gets)" -constraints {
after 100 {set ::total done}
}} $s]
vwait ::total
+ after cancel {set ::total timeout}
+ after cancel {set ::total done}
set ::total
} -cleanup {
close $srv
@@ -601,6 +855,20 @@ test zlib-11.2 "Bug #3390073: mis-appled gzip filtering" -setup {
} -cleanup {
removeFile $file
} -result {1000 /foo/bar 0}
+test zlib-11.3 {Bug 3595576 variant} -setup {
+ set file [makeFile {} test.input]
+} -constraints zlib -body {
+ set f [open $file wb]
+ puts -nonewline [zlib push gzip $f -header {filename /foo/bar}] \
+ [string repeat "hello" 1000]
+ close $f
+ set f [open $file rb]
+ set d [read $f]
+ close $f
+ zlib gunzip $d -header noSuchNs::foo
+} -cleanup {
+ removeFile $file
+} -returnCodes error -result {can't set "noSuchNs::foo": parent namespace doesn't exist}
::tcltest::cleanupTests
return
diff --git a/tools/README b/tools/README
index 821b2b3..f4bf627 100644
--- a/tools/README
+++ b/tools/README
@@ -23,6 +23,3 @@ Generating Windows Help Files:
this converts the Nroff to RTF files.
2) On Windows, convert the RTF to a Help doc, do
nmake helpfile
-
-Generating Windows binary distribution.
-Update and compile the WYSE tcl.wse configuration.
diff --git a/tools/encoding/ebcdic.txt b/tools/encoding/ebcdic.txt
index d9fa42e..d9fa42e 100755..100644
--- a/tools/encoding/ebcdic.txt
+++ b/tools/encoding/ebcdic.txt
diff --git a/tools/encoding/tis-620.txt b/tools/encoding/tis-620.txt
index d3656c5..d3656c5 100755..100644
--- a/tools/encoding/tis-620.txt
+++ b/tools/encoding/tis-620.txt
diff --git a/tools/genStubs.tcl b/tools/genStubs.tcl
index 163a354..7a75dc6 100644
--- a/tools/genStubs.tcl
+++ b/tools/genStubs.tcl
@@ -279,18 +279,26 @@ proc genStubs::rewriteFile {file text} {
# Results:
# Returns the original text inside an appropriate #ifdef.
-proc genStubs::addPlatformGuard {plat iftxt {eltxt {}}} {
+proc genStubs::addPlatformGuard {plat iftxt {eltxt {}} {withCygwin 0}} {
set text ""
switch $plat {
win {
- append text "#ifdef __WIN32__ /* WIN */\n${iftxt}"
+ append text "#if defined(_WIN32)"
+ if {$withCygwin} {
+ append text " || defined(__CYGWIN__)"
+ }
+ append text " /* WIN */\n${iftxt}"
if {$eltxt ne ""} {
append text "#else /* WIN */\n${eltxt}"
}
append text "#endif /* WIN */\n"
}
unix {
- append text "#if !defined(__WIN32__) && !defined(MAC_OSX_TCL)\
+ append text "#if !defined(_WIN32)"
+ if {$withCygwin} {
+ append text " && !defined(__CYGWIN__)"
+ }
+ append text " && !defined(MAC_OSX_TCL)\
/* UNIX */\n${iftxt}"
if {$eltxt ne ""} {
append text "#else /* UNIX */\n${eltxt}"
@@ -312,7 +320,11 @@ proc genStubs::addPlatformGuard {plat iftxt {eltxt {}}} {
append text "#endif /* AQUA */\n"
}
x11 {
- append text "#if !(defined(__WIN32__) || defined(MAC_OSX_TK))\
+ append text "#if !(defined(_WIN32)"
+ if {$withCygwin} {
+ append text " || defined(__CYGWIN__)"
+ }
+ append text " || defined(MAC_OSX_TK))\
/* X11 */\n${iftxt}"
if {$eltxt ne ""} {
append text "#else /* X11 */\n${eltxt}"
@@ -568,8 +580,8 @@ proc genStubs::makeSlot {name decl index} {
append text $rtype " *" $lfname "; /* $index */\n"
return $text
}
- if {[string range $rtype end-7 end] eq "CALLBACK"} {
- append text [string trim [string range $rtype 0 end-8]] " (CALLBACK *" $lfname ") "
+ if {[string range $rtype end-8 end] eq "__stdcall"} {
+ append text [string trim [string range $rtype 0 end-9]] " (__stdcall *" $lfname ") "
} else {
append text $rtype " (*" $lfname ") "
}
@@ -799,7 +811,7 @@ proc genStubs::forAllStubs {name slotProc onAll textVar
eval {append temp} $skipString
}
}
- append text [addPlatformGuard $plat $temp]
+ append text [addPlatformGuard $plat $temp {} true]
}
## win ##
if {$block(win)} {
@@ -813,10 +825,10 @@ proc genStubs::forAllStubs {name slotProc onAll textVar
eval {append temp} $skipString
}
}
- append text [addPlatformGuard $plat $temp]
+ append text [addPlatformGuard $plat $temp {} true]
}
## macosx ##
- if {$block(macosx) && !$block(aqua) && !$block(x11)} {
+ if {($block(unix) || $block(macosx)) && !$block(aqua) && !$block(x11)} {
set temp {}
set lastNum -1
foreach plat {unix macosx} {
@@ -885,7 +897,7 @@ proc genStubs::forAllStubs {name slotProc onAll textVar
} else {
eval {set etxt} $skipString
append temp [addPlatformGuard $plat [$slotProc \
- $name $stubs($name,$plat,$i) $i] $etxt]
+ $name $stubs($name,$plat,$i) $i] $etxt true]
}
set emit 1
break
@@ -895,7 +907,7 @@ proc genStubs::forAllStubs {name slotProc onAll textVar
eval {append temp} $skipString
}
}
- append text [addPlatformGuard x11 $temp]
+ append text [addPlatformGuard x11 $temp {} true]
}
}
}
@@ -971,10 +983,12 @@ proc genStubs::emitHeader {name} {
append text "#define ${CAPName}_STUBS_REVISION $revision\n"
}
+ append text "\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n"
+
emitDeclarations $name text
if {[info exists hooks($name)]} {
- append text "\ntypedef struct ${capName}StubHooks {\n"
+ append text "\ntypedef struct {\n"
foreach hook $hooks($name) {
set capHook [string toupper [string index $hook 0]]
append capHook [string range $hook 1 end]
@@ -988,14 +1002,17 @@ proc genStubs::emitHeader {name} {
append text " int epoch;\n"
append text " int revision;\n"
}
- append text " const struct ${capName}StubHooks *hooks;\n\n"
+ if {[info exists hooks($name)]} {
+ append text " const ${capName}StubHooks *hooks;\n\n"
+ } else {
+ append text " void *hooks;\n\n"
+ }
emitSlots $name text
append text "} ${capName}Stubs;\n\n"
- append text "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"
- append text "extern const ${capName}Stubs *${name}StubsPtr;\n"
+ append text "extern const ${capName}Stubs *${name}StubsPtr;\n\n"
append text "#ifdef __cplusplus\n}\n#endif\n"
emitMacros $name text
diff --git a/tools/man2help2.tcl b/tools/man2help2.tcl
index fe4e7ad..9c8f503 100644
--- a/tools/man2help2.tcl
+++ b/tools/man2help2.tcl
@@ -717,7 +717,7 @@ proc char {name} {
textSetup
puts -nonewline $file "\\'d7 "
}
- {\(em} {
+ {\(em} - {\(en} {
textSetup
puts -nonewline $file "-"
}
diff --git a/tools/str2c b/tools/str2c
index 971e552..cff7ba2 100644
--- a/tools/str2c
+++ b/tools/str2c
@@ -36,7 +36,7 @@ static char data\[\]=\"[translate $r]\";"
puts "/*
* Multi parts read only string generated by str2c
*/
-static CONST char * CONST data\[\]= {"
+static const char * const data\[\]= {"
set n 1
for {set i 0} {$i<$lg} {incr i $MAX} {
set part [string range $r $i [expr $i+$MAX-1]]
@@ -48,7 +48,7 @@ static CONST char * CONST data\[\]= {"
}
puts "\tNULL\t/* End of data marker */\n};"
puts "\n/* use for instance with:
- CONST char * CONST *chunk;
+ const char * const *chunk;
for (chunk=data; *chunk; chunk++) {
Tcl_AppendResult(interp, *chunk, (char *) NULL);
}
diff --git a/tools/tcl.wse.in b/tools/tcl.wse.in
deleted file mode 100644
index 653b1e1..0000000
--- a/tools/tcl.wse.in
+++ /dev/null
@@ -1,2376 +0,0 @@
-Document Type: WSE
-item: Global
- Version=6.01
- Title=Tcl 8.6 for Windows Installation
- Flags=00010100
- Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- Japanese Font Name=MS Gothic
- Japanese Font Size=10
- Start Gradient=0 0 255
- End Gradient=0 0 0
- Windows Flags=00000000000000010010110000001000
- Log Pathname=%MAINDIR%\INSTALL.LOG
- Message Font=MS Sans Serif
- Font Size=8
- Disk Label=tcl8.6b2
- Disk Filename=setup
- Patch Flags=0000000000000001
- Patch Threshold=85
- Patch Memory=4000
- Variable Name1=_SYS_
- Variable Default1=C:\WINDOWS\SYSTEM
- Variable Flags1=00001000
- Variable Name2=_ODBC16_
- Variable Default2=C:\WINDOWS\SYSTEM
- Variable Flags2=00001000
- Variable Name3=_WISE_
- Variable Default3=${__WISE__}
- Variable Flags3=00001000
-end
-item: Open/Close INSTALL.LOG
- Flags=00000001
-end
-item: Check if File/Dir Exists
- Pathname=%SYS%
- Flags=10000100
-end
-item: Set Variable
- Variable=SYS
- Value=%WIN%
-end
-item: End Block
-end
-item: Set Variable
- Variable=VER
- Value=8.6
-end
-item: Set Variable
- Variable=PATCHLEVEL
- Value=${__TCL_PATCH_LEVEL__}
-end
-item: Set Variable
- Variable=APPTITLE
- Value=Tcl/Tk %PATCHLEVEL% for Windows
-end
-item: Set Variable
- Variable=URL
- Value=http://www.tcl.tk/
-end
-item: Set Variable
- Variable=GROUP
- Value=Tcl
-end
-item: Set Variable
- Variable=DISABLED
- Value=!
-end
-item: Set Variable
- Variable=MAINDIR
- Value=Tcl
-end
-item: Check Configuration
- Flags=10111011
-end
-item: Get Registry Key Value
- Variable=PROGRAM_FILES
- Key=SOFTWARE\Microsoft\Windows\CurrentVersion
- Default=C:\Program Files
- Value Name=ProgramFilesDir
- Flags=00000100
-end
-item: Set Variable
- Variable=MAINDIR
- Value=%PROGRAM_FILES%\%MAINDIR%
-end
-item: Set Variable
- Variable=EXPLORER
- Value=1
-end
-item: Else Statement
-end
-item: Set Variable
- Variable=MAINDIR
- Value=C:\%MAINDIR%
-end
-item: End Block
-end
-item: Set Variable
- Variable=BACKUP
- Value=%MAINDIR%\BACKUP
-end
-item: Set Variable
- Variable=DOBACKUP
- Value=B
-end
-item: Set Variable
- Variable=BRANDING
- Value=0
-end
-remarked item: If/While Statement
- Variable=BRANDING
- Value=1
-end
-remarked item: Read INI Value
- Variable=NAME
- Pathname=%INST%\CUSTDATA.INI
- Section=Registration
- Item=Name
-end
-remarked item: Read INI Value
- Variable=COMPANY
- Pathname=%INST%\CUSTDATA.INI
- Section=Registration
- Item=Company
-end
-remarked item: If/While Statement
- Variable=NAME
-end
-remarked item: Set Variable
- Variable=DOBRAND
- Value=1
-end
-remarked item: End Block
-end
-remarked item: End Block
-end
-item: Set Variable
- Variable=TYPE
- Value=C
-end
-item: Set Variable
- Variable=COMPONENTS
- Value=ABC
-end
-item: Wizard Block
- Direction Variable=DIRECTION
- Display Variable=DISPLAY
- X Position=0
- Y Position=0
- Filler Color=8421440
- Flags=00000001
-end
-item: Custom Dialog Set
- Name=Splash
- Display Variable=DISPLAY
- item: Dialog
- Title=%APPTITLE% Installation
- Title French=Bienvenue
- Title German=Willkommen
- Title Portuguese=Bem-vindo
- Title Spanish=Bienvenido
- Title Italian=Benvenuto
- Title Danish=Velkommen
- Title Dutch=Welkom
- Title Norwegian=Velkommen
- Title Swedish=Välkommen
- Width=273
- Height=250
- Font Name=Helv
- Font Size=8
- item: Push Button
- Rectangle=166 214 208 228
- Variable=DIRECTION
- Value=N
- Create Flags=01010000000000010000000000000001
- Text=&Next >
- end
- item: Push Button
- Rectangle=212 214 254 228
- Action=3
- Create Flags=01010000000000010000000000000000
- Text=Cancel
- end
- item: Static
- Rectangle=0 0 268 233
- Action=2
- Enabled Color=00000000000000001111111111111111
- Create Flags=01010000000000000000000000001011
- Pathname=${__TCLBASEDIR__}\tools\white.bmp
- end
- item: Static
- Rectangle=5 5 268 215
- Destination Dialog=1
- Action=2
- Enabled Color=00000000000000001111111111111111
- Create Flags=01010000000000000000000000001011
- Pathname=${__TCLBASEDIR__}\tools\tclSplash.bmp
- end
- end
-end
-item: End Block
-end
-item: Wizard Block
- Direction Variable=DIRECTION
- Display Variable=DISPLAY
- Bitmap Pathname=%_WISE_%\DIALOGS\TEMPLATE\WIZARD.BMP
- X Position=9
- Y Position=10
- Filler Color=8421440
- Dialog=Welcome
- Dialog=Select Destination Directory
- Dialog=Select Installation Type
- Dialog=Select Components
- Dialog=Select Program Manager Group
- Variable=
- Variable=
- Variable=
- Variable=TYPE
- Variable=EXPLORER
- Value=
- Value=
- Value=
- Value=C
- Value=1
- Compare=0
- Compare=0
- Compare=0
- Compare=1
- Compare=0
- Flags=00000011
-end
-item: Custom Dialog Set
- Name=Welcome
- Display Variable=DISPLAY
- item: Dialog
- Title=%APPTITLE% Installation
- Title French=Installation de %APPTITLE%
- Title German=Installation von %APPTITLE%
- Title Spanish=Instalación de %APPTITLE%
- Title Italian=Installazione di %APPTITLE%
- Width=271
- Height=224
- Font Name=Helv
- Font Size=8
- item: Static
- Rectangle=86 8 258 42
- Create Flags=01010000000000000000000000000000
- Flags=0000000000000001
- Name=Times New Roman
- Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
- Text=Welcome!
- Text French=Bienvenue !
- Text German=Willkommen!
- Text Spanish=¡Bienvenido!
- Text Italian=Benvenuti!
- end
- item: Push Button
- Rectangle=150 187 195 202
- Variable=DIRECTION
- Value=N
- Create Flags=01010000000000010000000000000001
- Text=&Next >
- Text French=&Suite >
- Text German=&Weiter >
- Text Spanish=&Siguiente >
- Text Italian=&Avanti >
- end
- item: Push Button
- Rectangle=105 187 150 202
- Variable=DISABLED
- Value=!
- Create Flags=01010000000000010000000000000000
- Text=< &Back
- Text French=< &Retour
- Text German=< &Zurück
- Text Spanish=< &Atrás
- Text Italian=< &Indietro
- end
- item: Push Button
- Rectangle=211 187 256 202
- Action=3
- Create Flags=01010000000000010000000000000000
- Text=&Cancel
- Text French=&Annuler
- Text German=&Abbrechen
- Text Spanish=&Cancelar
- Text Italian=&Annulla
- end
- item: Static
- Rectangle=85 41 255 130
- Create Flags=01010000000000000000000000000000
- Text=This installation program will install %APPTITLE%.
- Text=
- Text=Press the Next button to start the installation. You can press the Exit Setup button now if you do not want to install %APPTITLE% at this time.
- Text=
- Text=It is strongly recommended that you exit all Windows programs before running this installation program.
- Text French=Ce programme d'installation va installer %APPTITLE%.
- Text French=
- Text French=Cliquez sur le bouton Suite pour démarrer l'installation. Vous pouvez cliquer sur le bouton Quitter l'installation si vous ne voulez pas installer %APPTITLE% tout de suite.
- Text German=Mit diesem Installationsprogramm wird %APPTITLE% installiert.
- Text German=
- Text German=Klicken Sie auf "Weiter", um mit der Installation zu beginnen. Klicken Sie auf "Abbrechen", um die Installation von %APPTITLE% abzubrechen.
- Text Spanish=Este programa de instalación instalará %APPTITLE%.
- Text Spanish=
- Text Spanish=Presione el botón Siguiente para iniciar la instalación. Puede presionar el botón Salir de instalación si no desea instalar %APPTITLE% en este momento.
- Text Italian=Questo programma installerà %APPTITLE%.
- Text Italian=
- Text Italian=Per avvviare l'installazione premere il pulsante Avanti. Se non si desidera installare %APPTITLE% ora, premere il pulsante Esci dall'installazione.
- end
- item: Static
- Rectangle=8 180 256 181
- Action=3
- Create Flags=01010000000000000000000000000111
- end
- end
-end
-item: Custom Dialog Set
- Name=Select Destination Directory
- Display Variable=DISPLAY
- item: Dialog
- Title=%APPTITLE% Installation
- Title French=Installation de %APPTITLE%
- Title German=Installation von %APPTITLE%
- Title Spanish=Instalación de %APPTITLE%
- Title Italian=Installazione di %APPTITLE%
- Width=271
- Height=224
- Font Name=Helv
- Font Size=8
- item: Push Button
- Rectangle=150 187 195 202
- Variable=DIRECTION
- Value=N
- Create Flags=01010000000000010000000000000001
- Text=&Next >
- Text French=&Suite >
- Text German=&Weiter >
- Text Spanish=&Siguiente >
- Text Italian=&Avanti >
- end
- item: Push Button
- Rectangle=105 187 150 202
- Variable=DIRECTION
- Value=B
- Create Flags=01010000000000010000000000000000
- Flags=0000000000000001
- Text=< &Back
- Text French=< &Retour
- Text German=< &Zurück
- Text Spanish=< &Atrás
- Text Italian=< &Indietro
- end
- item: Push Button
- Rectangle=211 187 256 202
- Action=3
- Create Flags=01010000000000010000000000000000
- Text=&Cancel
- Text French=&Annuler
- Text German=&Abbrechen
- Text Spanish=&Cancelar
- Text Italian=&Annulla
- end
- item: Static
- Rectangle=8 180 256 181
- Action=3
- Create Flags=01010000000000000000000000000111
- end
- item: Static
- Rectangle=86 8 258 42
- Create Flags=01010000000000000000000000000000
- Flags=0000000000000001
- Name=Times New Roman
- Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
- Text=Select Destination Directory
- Text French=Sélectionner le répertoire de destination
- Text German=Zielverzeichnis wählen
- Text Spanish=Seleccione el directorio de destino
- Text Italian=Selezionare Directory di destinazione
- end
- item: Static
- Rectangle=86 39 256 114
- Create Flags=01010000000000000000000000000000
- Text=Please select the directory where the %APPTITLE% files are to be installed.
- Text=
- Text=To install in the default directory below, click Next.
- Text=
- Text=To install in a different directory, click Browse and select another directory.
- Text French=Veuillez sélectionner le répertoire dans lequel les fichiers %APPTITLE% doivent être installés.
- Text German=Geben Sie an, in welchem Verzeichnis die %APPTITLE%-Dateien installiert werden sollen.
- Text Spanish=Por favor seleccione el directorio donde desee instalar los archivos de %APPTITLE%.
- Text Italian=Selezionare la directory dove verranno installati i file %APPTITLE%.
- end
- item: Static
- Rectangle=86 130 256 157
- Action=1
- Create Flags=01010000000000000000000000000111
- end
- item: Push Button
- Rectangle=205 138 250 153
- Variable=MAINDIR_SAVE
- Value=%MAINDIR%
- Destination Dialog=1
- Action=2
- Create Flags=01010000000000010000000000000000
- Text=Browse
- Text French=Parcourir
- Text German=Durchsuchen
- Text Spanish=Buscar
- Text Italian=Sfoglie
- end
- item: Static
- Rectangle=91 140 198 151
- Create Flags=01010000000000000000000000000000
- Text=%MAINDIR%
- Text French=%MAINDIR%
- Text German=%MAINDIR%
- Text Spanish=%MAINDIR%
- Text Italian=%MAINDIR%
- end
- end
- item: Dialog
- Title=Select Destination Directory
- Title French=Sélectionner le répertoire de destination
- Title German=Zielverzeichnis wählen
- Title Spanish=Seleccione el directorio de destino
- Title Italian=Selezionare Directory di destinazione
- Width=221
- Height=173
- Font Name=Helv
- Font Size=8
- item: Listbox
- Rectangle=5 5 163 149
- Variable=MAINDIR
- Create Flags=01010000100000010000000101000000
- Flags=0000110000100010
- Text=%MAINDIR%
- Text French=%MAINDIR%
- Text German=%MAINDIR%
- Text Spanish=%MAINDIR%
- Text Italian=%MAINDIR%
- end
- item: Push Button
- Rectangle=167 6 212 21
- Create Flags=01010000000000010000000000000001
- Text=OK
- Text French=OK
- Text German=OK
- Text Spanish=Aceptar
- Text Italian=OK
- end
- item: Push Button
- Rectangle=167 25 212 40
- Variable=MAINDIR
- Value=%MAINDIR_SAVE%
- Create Flags=01010000000000010000000000000000
- Flags=0000000000000001
- Text=Cancel
- Text French=Annuler
- Text German=Abbrechen
- Text Spanish=Cancelar
- Text Italian=Annulla
- end
- end
-end
-remarked item: Custom Dialog Set
- Name=Select Installation Type
- Display Variable=DISPLAY
- item: Dialog
- Title=%APPTITLE% Installation
- Title French=Installation de %APPTITLE%
- Title German=Installation von %APPTITLE%
- Title Spanish=Instalación de %APPTITLE%
- Title Italian=Installazione di %APPTITLE%
- Width=271
- Height=224
- Font Name=Helv
- Font Size=8
- item: Push Button
- Rectangle=150 187 195 202
- Variable=DIRECTION
- Value=N
- Create Flags=01010000000000010000000000000001
- Text=&Next >
- Text French=&Suite >
- Text German=&Weiter >
- Text Spanish=&Siguiente >
- Text Italian=&Avanti >
- end
- item: Push Button
- Rectangle=105 187 150 202
- Variable=DIRECTION
- Value=B
- Create Flags=01010000000000010000000000000000
- Text=< &Back
- Text French=< &Retour
- Text German=< &Zurück
- Text Spanish=< &Atrás
- Text Italian=< &Indietro
- end
- item: Push Button
- Rectangle=211 187 256 202
- Action=3
- Create Flags=01010000000000010000000000000000
- Text=&Cancel
- Text French=&Annuler
- Text German=&Abbrechen
- Text Spanish=&Cancelar
- Text Italian=&Annulla
- end
- item: Static
- Rectangle=8 180 256 181
- Action=3
- Create Flags=01010000000000000000000000000111
- end
- item: Static
- Rectangle=86 8 258 42
- Create Flags=01010000000000000000000000000000
- Flags=0000000000000001
- Name=Times New Roman
- Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
- Text=Select Installation Type
- Text French=Sélectionner les composants
- Text German=Komponenten auswählen
- Text Spanish=Seleccione componentes
- Text Italian=Selezionare i componenti
- end
- item: Static
- Rectangle=194 162 242 172
- Variable=COMPONENTS
- Value=MAINDIR
- Create Flags=01010000000000000000000000000010
- end
- item: Static
- Rectangle=194 153 242 162
- Variable=COMPONENTS
- Create Flags=01010000000000000000000000000010
- end
- item: Static
- Rectangle=107 153 196 164
- Create Flags=01010000000000000000000000000000
- Text=Disk Space Required:
- Text French=Espace disque requis :
- Text German=Notwendiger Speicherplatz:
- Text Spanish=Espacio requerido en el disco:
- Text Italian=Spazio su disco necessario:
- end
- item: Static
- Rectangle=107 162 196 172
- Create Flags=01010000000000000000000000000000
- Text=Disk Space Remaining:
- Text French=Espace disque disponible :
- Text German=Verbleibender Speicherplatz:
- Text Spanish=Espacio en disco disponible:
- Text Italian=Spazio su disco disponibile:
- end
- item: Static
- Rectangle=86 145 256 175
- Action=1
- Create Flags=01010000000000000000000000000111
- end
- item: Static
- Rectangle=86 42 256 61
- Create Flags=01010000000000000000000000000000
- Text=Choose which type of installation to perform by selecting one of the buttons below.
- Text French=Choisissez les composants que vous voulez installer en cochant les cases ci-dessous.
- Text German=Wählen Sie die zu installierenden Komponenten, indem Sie in die entsprechenden Kästchen klicken.
- Text Spanish=Elija los componentes que desee instalar marcando los cuadros de abajo.
- Text Italian=Scegliere quali componenti installare selezionando le caselle sottostanti.
- end
- item: Radio Button
- Rectangle=86 74 256 128
- Variable=TYPE
- Create Flags=01010000000000010000000000001001
- Text=&Full Installation (Recommended)
- Text=&Minimal Installation
- Text=C&ustom Installation
- Text=
- end
- end
-end
-item: Custom Dialog Set
- Name=Select Components
- Display Variable=DISPLAY
- item: Dialog
- Title=%APPTITLE% Installation
- Title French=Installation de %APPTITLE%
- Title German=Installation von %APPTITLE%
- Title Spanish=Instalación de %APPTITLE%
- Title Italian=Installazione di %APPTITLE%
- Width=271
- Height=224
- Font Name=Helv
- Font Size=8
- item: Push Button
- Rectangle=150 187 195 202
- Variable=DIRECTION
- Value=N
- Create Flags=01010000000000010000000000000001
- Text=&Next >
- Text French=&Suite >
- Text German=&Weiter >
- Text Spanish=&Siguiente >
- Text Italian=&Avanti >
- end
- item: Push Button
- Rectangle=105 187 150 202
- Variable=DIRECTION
- Value=B
- Create Flags=01010000000000010000000000000000
- Text=< &Back
- Text French=< &Retour
- Text German=< &Zurück
- Text Spanish=< &Atrás
- Text Italian=< &Indietro
- end
- item: Push Button
- Rectangle=211 187 256 202
- Action=3
- Create Flags=01010000000000010000000000000000
- Text=&Cancel
- Text French=&Annuler
- Text German=&Abbrechen
- Text Spanish=&Cancelar
- Text Italian=&Annulla
- end
- item: Static
- Rectangle=8 180 256 181
- Action=3
- Create Flags=01010000000000000000000000000111
- end
- item: Static
- Rectangle=86 8 258 42
- Create Flags=01010000000000000000000000000000
- Flags=0000000000000001
- Name=Times New Roman
- Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
- Text=Select Components
- Text French=Sélectionner les composants
- Text German=Komponenten auswählen
- Text Spanish=Seleccione componentes
- Text Italian=Selezionare i componenti
- end
- item: Checkbox
- Rectangle=86 75 256 129
- Variable=COMPONENTS
- Create Flags=01010000000000010000000000000011
- Flags=0000000000000110
- Text=Tcl Run-Time Files
- Text=Example Scripts
- Text=Help Files
- Text=Header and Library Files
- Text=
- Text French=Tcl Run-Time Files
- Text French=Example Scripts
- Text French=Help Files
- Text French=Header and Library Files
- Text French=
- Text German=Tcl Run-Time Files
- Text German=Example Scripts
- Text German=Help Files
- Text German=Header and Library Files
- Text German=
- Text Spanish=Tcl Run-Time Files
- Text Spanish=Example Scripts
- Text Spanish=Help Files
- Text Spanish=Header and Library Files
- Text Spanish=
- Text Italian=Tcl Run-Time Files
- Text Italian=Example Scripts
- Text Italian=Help Files
- Text Italian=Header and Library Files
- Text Italian=
- end
- item: Static
- Rectangle=194 162 242 172
- Variable=COMPONENTS
- Value=MAINDIR
- Create Flags=01010000000000000000000000000010
- end
- item: Static
- Rectangle=194 153 242 162
- Variable=COMPONENTS
- Create Flags=01010000000000000000000000000010
- end
- item: Static
- Rectangle=107 153 196 164
- Create Flags=01010000000000000000000000000000
- Text=Disk Space Required:
- Text French=Espace disque requis :
- Text German=Notwendiger Speicherplatz:
- Text Spanish=Espacio requerido en el disco:
- Text Italian=Spazio su disco necessario:
- end
- item: Static
- Rectangle=107 162 196 172
- Create Flags=01010000000000000000000000000000
- Text=Disk Space Remaining:
- Text French=Espace disque disponible :
- Text German=Verbleibender Speicherplatz:
- Text Spanish=Espacio en disco disponible:
- Text Italian=Spazio su disco disponibile:
- end
- item: Static
- Rectangle=86 145 256 175
- Action=1
- Create Flags=01010000000000000000000000000111
- end
- item: Static
- Rectangle=86 42 256 61
- Create Flags=01010000000000000000000000000000
- Text=Choose which components to install by checking the boxes below.
- Text French=Choisissez les composants que vous voulez installer en cochant les cases ci-dessous.
- Text German=Wählen Sie die zu installierenden Komponenten, indem Sie in die entsprechenden Kästchen klicken.
- Text Spanish=Elija los componentes que desee instalar marcando los cuadros de abajo.
- Text Italian=Scegliere quali componenti installare selezionando le caselle sottostanti.
- end
- end
-end
-item: Custom Dialog Set
- Name=Select Program Manager Group
- Display Variable=DISPLAY
- item: Dialog
- Title=%APPTITLE% Installation
- Title French=Installation de %APPTITLE%
- Title German=Installation von %APPTITLE%
- Title Spanish=Instalación de %APPTITLE%
- Title Italian=Installazione di %APPTITLE%
- Width=271
- Height=224
- Font Name=Helv
- Font Size=8
- item: Push Button
- Rectangle=150 187 195 202
- Variable=DIRECTION
- Value=N
- Create Flags=01010000000000010000000000000001
- Text=&Next >
- Text French=&Suite >
- Text German=&Weiter >
- Text Spanish=&Siguiente >
- Text Italian=&Avanti >
- end
- item: Push Button
- Rectangle=105 187 150 202
- Variable=DIRECTION
- Value=B
- Create Flags=01010000000000010000000000000000
- Flags=0000000000000001
- Text=< &Back
- Text French=< &Retour
- Text German=< &Zurück
- Text Spanish=< &Atrás
- Text Italian=< &Indietro
- end
- item: Push Button
- Rectangle=211 187 256 202
- Action=3
- Create Flags=01010000000000010000000000000000
- Text=&Cancel
- Text French=&Annuler
- Text German=&Abbrechen
- Text Spanish=&Cancelar
- Text Italian=&Annulla
- end
- item: Static
- Rectangle=8 180 256 181
- Action=3
- Create Flags=01010000000000000000000000000111
- end
- item: Static
- Rectangle=86 8 258 42
- Create Flags=01010000000000000000000000000000
- Flags=0000000000000001
- Name=Times New Roman
- Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
- Text=Select ProgMan Group
- Text French=Sélectionner le groupe du Gestionnaire de programme
- Text German=Bestimmung der Programm-Managergruppe
- Text Spanish=Seleccione grupo del Administrador de programas
- Text Italian=Selezionare il gruppo ProgMan
- end
- item: Static
- Rectangle=86 44 256 68
- Create Flags=01010000000000000000000000000000
- Text=Enter the name of the Program Manager group to add the %APPTITLE% icons to:
- Text French=Entrez le nom du groupe du Gestionnaire de programme dans lequel vous souhaitez ajouter les icônes de %APPTITLE% :
- Text German=Geben Sie den Namen der Programmgruppe ein, der das Symbol %APPTITLE% hinzugefügt werden soll:
- Text Spanish=Escriba el nombre del grupo del Administrador de programas en el que desea agregar los iconos de %APPTITLE%:
- Text Italian=Inserire il nome del gruppo Program Manager per aggiungere le icone %APPTITLE% a:
- end
- item: Combobox
- Rectangle=86 69 256 175
- Variable=GROUP
- Create Flags=01010000000000010000001000000001
- Flags=0000000000000001
- Text=%GROUP%
- Text French=%GROUP%
- Text German=%GROUP%
- Text Spanish=%GROUP%
- Text Italian=%GROUP%
- end
- end
-end
-item: Custom Dialog Set
- Name=Start Installation
- Display Variable=DISPLAY
- item: Dialog
- Title=%APPTITLE% Installation
- Title French=Installation de %APPTITLE%
- Title German=Installation von %APPTITLE%
- Title Spanish=Instalación de %APPTITLE%
- Title Italian=Installazione di %APPTITLE%
- Width=271
- Height=224
- Font Name=Helv
- Font Size=8
- item: Push Button
- Rectangle=150 187 195 202
- Variable=DIRECTION
- Value=N
- Create Flags=01010000000000010000000000000001
- Text=&Next >
- Text French=&Suite >
- Text German=&Weiter >
- Text Spanish=&Siguiente >
- Text Italian=&Avanti >
- end
- item: Push Button
- Rectangle=105 187 150 202
- Variable=DIRECTION
- Value=B
- Create Flags=01010000000000010000000000000000
- Text=< &Back
- Text French=< &Retour
- Text German=< &Zurück
- Text Spanish=< &Atrás
- Text Italian=< &Indietro
- end
- item: Push Button
- Rectangle=211 187 256 202
- Action=3
- Create Flags=01010000000000010000000000000000
- Text=&Cancel
- Text French=&Annuler
- Text German=&Abbrechen
- Text Spanish=&Cancelar
- Text Italian=&Annulla
- end
- item: Static
- Rectangle=8 180 256 181
- Action=3
- Create Flags=01010000000000000000000000000111
- end
- item: Static
- Rectangle=86 8 258 42
- Create Flags=01010000000000000000000000000000
- Flags=0000000000000001
- Name=Times New Roman
- Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
- Text=Ready to Install!
- Text French=Prêt à installer !
- Text German=Installationsbereit!
- Text Spanish=¡Preparado para la instalación!
- Text Italian=Pronto per l'installazione!
- end
- item: Static
- Rectangle=86 42 256 102
- Create Flags=01010000000000000000000000000000
- Text=You are now ready to install %APPTITLE%.
- Text=
- Text=Press the Next button to begin the installation or the Back button to reenter the installation information.
- Text French=Vous êtes maintenant prêt à installer les fichiers %APPTITLE%.
- Text French=
- Text French=Cliquez sur le bouton Suite pour commencer l'installation ou sur le bouton Retour pour entrer les informations d'installation à nouveau.
- Text German=Sie können %APPTITLE% nun installieren.
- Text German=
- Text German=Klicken Sie auf "Weiter", um mit der Installation zu beginnen. Klicken Sie auf "Zurück", um die Installationsinformationen neu einzugeben.
- Text Spanish=Ya está listo para instalar %APPTITLE%.
- Text Spanish=
- Text Spanish=Presione el botón Siguiente para comenzar la instalación o presione Atrás para volver a ingresar la información para la instalación.
- Text Italian=Ora è possibile installare %APPTITLE%.
- Text Italian=
- Text Italian=Premere il pulsante Avanti per avviare l'installazione o il pulsante Indietro per reinserire le informazioni di installazione.
- end
- end
-end
-item: If/While Statement
- Variable=DISPLAY
- Value=Select Destination Directory
-end
-item: Set Variable
- Variable=BACKUP
- Value=%MAINDIR%\BACKUP
-end
-item: End Block
-end
-item: End Block
-end
-item: If/While Statement
- Variable=TYPE
- Value=B
-end
-item: Set Variable
- Variable=COMPONENTS
- Value=A
-end
-item: End Block
-end
-item: If/While Statement
- Variable=DOBACKUP
- Value=A
-end
-item: Set Variable
- Variable=BACKUPDIR
- Value=%BACKUP%
-end
-item: End Block
-end
-remarked item: If/While Statement
- Variable=BRANDING
- Value=1
-end
-remarked item: If/While Statement
- Variable=DOBRAND
- Value=1
-end
-remarked item: Edit INI File
- Pathname=%INST%\CUSTDATA.INI
- Settings=[Registration]
- Settings=NAME=%NAME%
- Settings=COMPANY=%COMPANY%
- Settings=
-end
-remarked item: End Block
-end
-remarked item: End Block
-end
-item: Set Variable
- Variable=MAINDIRSHORT
- Value=%MAINDIR%
- Flags=00010100
-end
-item: Open/Close INSTALL.LOG
-end
-item: Check Disk Space
- Component=COMPONENTS
-end
-item: Install File
- Source=${__TCLBASEDIR__}\license.txt
- Destination=%MAINDIR%\license.txt
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\win\Readme.txt
- Destination=%MAINDIR%\Readme.txt
- Flags=0000000000000010
-end
-item: If/While Statement
- Variable=COMPONENTS
- Value=D
- Flags=00001010
-end
-item: Install File
- Source=${__TKBASEDIR__}\win\release\tk85.lib
- Destination=%MAINDIR%\lib\tk85.lib
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\win\release\tkstub85.lib
- Destination=%MAINDIR%\lib\tkstub85.lib
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\win\release\tcl85.lib
- Destination=%MAINDIR%\lib\tcl85.lib
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\win\release\tclstub85.lib
- Destination=%MAINDIR%\lib\tclstub85.lib
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\xlib\X11\Xutil.h
- Destination=%MAINDIR%\include\X11\Xutil.h
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\xlib\X11\Xlib.h
- Destination=%MAINDIR%\include\X11\Xlib.h
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\xlib\X11\Xfuncproto.h
- Destination=%MAINDIR%\include\X11\Xfuncproto.h
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\xlib\X11\Xatom.h
- Destination=%MAINDIR%\include\X11\Xatom.h
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\xlib\X11\X.h
- Destination=%MAINDIR%\include\X11\X.h
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\xlib\X11\keysymdef.h
- Destination=%MAINDIR%\include\X11\keysymdef.h
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\xlib\X11\keysym.h
- Destination=%MAINDIR%\include\X11\keysym.h
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\xlib\X11\cursorfont.h
- Destination=%MAINDIR%\include\X11\cursorfont.h
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\generic\tk.h
- Destination=%MAINDIR%\include\tk.h
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\generic\tkDecls.h
- Destination=%MAINDIR%\include\tkDecls.h
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\generic\tkPlatDecls.h
- Destination=%MAINDIR%\include\tkPlatDecls.h
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\generic\tkIntXlibDecls.h
- Destination=%MAINDIR%\include\tkIntXlibDecls.h
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\generic\tcl.h
- Destination=%MAINDIR%\include\tcl.h
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\generic\tclDecls.h
- Destination=%MAINDIR%\include\tclDecls.h
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\generic\tclPlatDecls.h
- Destination=%MAINDIR%\include\tclPlatDecls.h
- Flags=0000000000000010
-end
-item: End Block
-end
-item: If/While Statement
- Variable=COMPONENTS
- Value=A
- Flags=00001010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\msgcat\pkgIndex.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\msgcat1.4\pkgIndex.tcl
- Flags=0000000010000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\msgcat\msgcat.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\msgcat1.4\msgcat.tcl
- Flags=0000000010000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\tcltest\pkgIndex.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\tcltest2.0\pkgIndex.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\tcltest\tcltest.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\tcltest2.0\tcltest.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\symbol.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\symbol.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\shiftjis.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\shiftjis.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\macUkraine.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\macUkraine.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\macTurkish.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\macTurkish.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\macThai.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\macThai.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\macRomania.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\macRomania.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\macRoman.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\macRoman.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\macJapan.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\macJapan.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\macIceland.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\macIceland.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\macGreek.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\macGreek.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\macDingbats.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\macDingbats.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\macCyrillic.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\macCyrillic.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\macCroatian.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\macCroatian.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\macCentEuro.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\macCentEuro.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\ksc5601.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\ksc5601.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\koi8-r.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\koi8-r.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\jis0212.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\jis0212.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\jis0208.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\jis0208.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\jis0201.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\jis0201.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\iso8859-15.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-15.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\iso8859-9.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-9.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\iso8859-8.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-8.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\iso8859-7.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-7.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\iso8859-6.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-6.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\iso8859-5.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-5.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\iso8859-4.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-4.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\iso8859-3.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-3.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\iso8859-2.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-2.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\iso8859-1.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-1.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\iso2022.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso2022.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\iso2022-kr.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso2022-kr.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\iso2022-jp.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso2022-jp.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\gb2312.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\gb2312.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\gb1988.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\gb1988.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\gb12345.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\gb12345.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\euc-cn.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\euc-cn.enc
- Flags=0000000010000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\euc-jp.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\euc-jp.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\euc-kr.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\euc-kr.enc
- Flags=0000000010000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\dingbats.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\dingbats.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp950.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp950.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp949.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp949.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp936.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp936.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp932.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp932.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp874.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp874.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp869.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp869.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp866.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp866.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp865.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp865.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp864.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp864.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp863.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp863.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp862.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp862.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp861.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp861.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp860.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp860.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp857.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp857.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp855.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp855.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp852.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp852.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp850.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp850.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp775.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp775.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp737.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp737.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp437.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp437.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp1258.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1258.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp1257.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1257.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp1256.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1256.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp1255.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1255.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp1254.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1254.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp1253.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1253.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp1252.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1252.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp1251.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1251.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\cp1250.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1250.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\ascii.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\ascii.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\encoding\big5.enc
- Destination=%MAINDIR%\lib\tcl%VER%\encoding\big5.enc
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\opt\pkgIndex.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\opt0.4\pkgIndex.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\opt\optparse.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\opt0.4\optparse.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\http\pkgIndex.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\http2.4\pkgIndex.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\http\http.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\http2.4\http.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\msgbox.tcl
- Destination=%MAINDIR%\lib\tk%VER%\msgbox.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\optMenu.tcl
- Destination=%MAINDIR%\lib\tk%VER%\optMenu.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\clrpick.tcl
- Destination=%MAINDIR%\lib\tk%VER%\clrpick.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\entry.tcl
- Destination=%MAINDIR%\lib\tk%VER%\entry.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\spinbox.tcl
- Destination=%MAINDIR%\lib\tk%VER%\spinbox.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\comdlg.tcl
- Destination=%MAINDIR%\lib\tk%VER%\comdlg.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\bgerror.tcl
- Destination=%MAINDIR%\lib\tk%VER%\bgerror.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\obsolete.tcl
- Destination=%MAINDIR%\lib\tk%VER%\obsolete.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\button.tcl
- Destination=%MAINDIR%\lib\tk%VER%\button.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\xmfbox.tcl
- Destination=%MAINDIR%\lib\tk%VER%\xmfbox.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\console.tcl
- Destination=%MAINDIR%\lib\tk%VER%\console.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\listbox.tcl
- Destination=%MAINDIR%\lib\tk%VER%\listbox.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\menu.tcl
- Destination=%MAINDIR%\lib\tk%VER%\menu.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\dialog.tcl
- Destination=%MAINDIR%\lib\tk%VER%\dialog.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\focus.tcl
- Destination=%MAINDIR%\lib\tk%VER%\focus.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\palette.tcl
- Destination=%MAINDIR%\lib\tk%VER%\palette.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\tkfbox.tcl
- Destination=%MAINDIR%\lib\tk%VER%\tkfbox.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\tk.tcl
- Destination=%MAINDIR%\lib\tk%VER%\tk.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\text.tcl
- Destination=%MAINDIR%\lib\tk%VER%\text.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\tearoff.tcl
- Destination=%MAINDIR%\lib\tk%VER%\tearoff.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\tclIndex
- Destination=%MAINDIR%\lib\tk%VER%\tclIndex
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\scrlbar.tcl
- Destination=%MAINDIR%\lib\tk%VER%\scrlbar.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\scale.tcl
- Destination=%MAINDIR%\lib\tk%VER%\scale.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\safetk.tcl
- Destination=%MAINDIR%\lib\tk%VER%\safetk.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\http1.0\pkgIndex.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\http1.0\pkgIndex.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\http1.0\http.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\http1.0\http.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\reg\pkgIndex.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\reg1.0\pkgIndex.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\win\release\tclreg10.dll
- Destination=%MAINDIR%\lib\tcl%VER%\reg1.0\tclreg10.dll
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\dde\pkgIndex.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\dde1.2\pkgIndex.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\win\release\tcldde12.dll
- Destination=%MAINDIR%\lib\tcl%VER%\dde1.2\tcldde12.dll
- Flags=0000000000000010
-end
-item: Install File
- Source=C:\WINNT\SYSTEM32\Msvcrt.dll
- Destination=%MAINDIR%\bin\msvcrt.dll
- Flags=0010001000000011
-end
-item: Install File
- Source=${__TKBASEDIR__}\win\release\wish85.exe
- Destination=%MAINDIR%\bin\wish85.exe
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\win\release\tclsh85.exe
- Destination=%MAINDIR%\bin\tclsh85.exe
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\win\release\tclpip85.dll
- Destination=%MAINDIR%\bin\tclpip85.dll
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\win\release\tcl85.dll
- Destination=%MAINDIR%\bin\tcl85.dll
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\win\release\tk85.dll
- Destination=%MAINDIR%\bin\tk85.dll
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\auto.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\auto.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\history.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\history.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\init.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\init.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\package.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\package.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\parray.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\parray.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\safe.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\safe.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\tclIndex
- Destination=%MAINDIR%\lib\tcl%VER%\tclIndex
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\library\word.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\word.tcl
- Flags=0000000000000010
-end
-item: End Block
-end
-item: If/While Statement
- Variable=COMPONENTS
- Value=B
- Flags=00001010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\images\tai-ku.gif
- Destination=%MAINDIR%\lib\tk%VER%\images\tai-ku.gif
- Flags=0000000010000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\images\teapot.ppm
- Destination=%MAINDIR%\lib\tk%VER%\demos\images\teapot.ppm
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\images\tcllogo.gif
- Destination=%MAINDIR%\lib\tk%VER%\demos\images\tcllogo.gif
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\images\pattern.bmp
- Destination=%MAINDIR%\lib\tk%VER%\demos\images\pattern.bmp
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\images\noletter.bmp
- Destination=%MAINDIR%\lib\tk%VER%\demos\images\noletter.bmp
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\images\letters.bmp
- Destination=%MAINDIR%\lib\tk%VER%\demos\images\letters.bmp
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\images\gray25.bmp
- Destination=%MAINDIR%\lib\tk%VER%\demos\images\gray25.bmp
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\images\flagup.bmp
- Destination=%MAINDIR%\lib\tk%VER%\demos\images\flagup.bmp
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\images\flagdown.bmp
- Destination=%MAINDIR%\lib\tk%VER%\demos\images\flagdown.bmp
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\images\face.bmp
- Destination=%MAINDIR%\lib\tk%VER%\demos\images\face.bmp
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\images\earthris.gif
- Destination=%MAINDIR%\lib\tk%VER%\demos\images\earthris.gif
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\images\earth.gif
- Destination=%MAINDIR%\lib\tk%VER%\demos\images\earth.gif
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\vscale.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\vscale.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\twind.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\twind.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\text.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\text.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\style.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\style.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\states.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\states.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\search.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\search.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\sayings.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\sayings.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\ruler.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\ruler.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\radio.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\radio.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\puzzle.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\puzzle.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\plot.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\plot.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\msgbox.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\msgbox.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\menubu.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\menubu.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\menu.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\menu.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\label.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\label.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\items.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\items.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\image2.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\image2.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\image1.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\image1.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\icon.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\icon.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\hscale.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\hscale.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\form.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\form.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\ixset
- Destination=%MAINDIR%\lib\tk%VER%\demos\ixset.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\rolodex
- Destination=%MAINDIR%\lib\tk%VER%\demos\rolodex.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\square
- Destination=%MAINDIR%\lib\tk%VER%\demos\square.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\Readme
- Destination=%MAINDIR%\lib\tk%VER%\demos\Readme
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\hello
- Destination=%MAINDIR%\lib\tk%VER%\demos\hello.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\tclIndex
- Destination=%MAINDIR%\lib\tk%VER%\demos\tclIndex
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\browse
- Destination=%MAINDIR%\lib\tk%VER%\demos\browse.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\timer
- Destination=%MAINDIR%\lib\tk%VER%\demos\timer.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\widget
- Destination=%MAINDIR%\lib\tk%VER%\demos\widget.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\tcolor
- Destination=%MAINDIR%\lib\tk%VER%\demos\tcolor.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\rmt
- Destination=%MAINDIR%\lib\tk%VER%\demos\rmt.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\floor.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\floor.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\filebox.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\filebox.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\images\pwrdLogo75.gif
- Destination=%MAINDIR%\lib\tk%VER%\images\pwrdLogo75.gif
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\images\pwrdLogo200.gif
- Destination=%MAINDIR%\lib\tk%VER%\images\pwrdLogo200.gif
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\images\pwrdLogo175.gif
- Destination=%MAINDIR%\lib\tk%VER%\images\pwrdLogo175.gif
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\images\pwrdLogo150.gif
- Destination=%MAINDIR%\lib\tk%VER%\images\pwrdLogo150.gif
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\images\pwrdLogo100.gif
- Destination=%MAINDIR%\lib\tk%VER%\images\pwrdLogo100.gif
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\images\logoMed.gif
- Destination=%MAINDIR%\lib\tk%VER%\images\logoMed.gif
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\images\logoLarge.gif
- Destination=%MAINDIR%\lib\tk%VER%\images\logoLarge.gif
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\images\logo64.gif
- Destination=%MAINDIR%\lib\tk%VER%\images\logo64.gif
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\images\logo100.gif
- Destination=%MAINDIR%\lib\tk%VER%\images\logo100.gif
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\images\Readme
- Destination=%MAINDIR%\lib\tk%VER%\images\Readme
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\arrow.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\arrow.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\bind.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\bind.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\bitmap.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\bitmap.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\button.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\button.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\check.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\check.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\clrpick.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\clrpick.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\colors.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\colors.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\cscroll.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\cscroll.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\ctext.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\ctext.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\dialog1.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\dialog1.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\dialog2.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\dialog2.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\entry1.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\entry1.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TKBASEDIR__}\library\demos\entry2.tcl
- Destination=%MAINDIR%\lib\tk%VER%\demos\entry2.tcl
- Flags=0000000000000010
-end
-item: End Block
-end
-item: If/While Statement
- Variable=COMPONENTS
- Value=C
- Flags=00001010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\tools\tcl85.cnt
- Destination=%MAINDIR%\doc\tcl85.cnt
- Flags=0000000000000010
-end
-item: Install File
- Source=${__TCLBASEDIR__}\tools\tcl85.hlp
- Destination=%MAINDIR%\doc\tcl85.hlp
- Flags=0000000000000010
-end
-item: End Block
-end
-item: Set Variable
- Variable=MAINDIR
- Value=%MAINDIR%
- Flags=00010100
-end
-item: Include Script
- Pathname=\\pop\tools\1.2\win32-ix86\wise\INCLUDE\uninstal.wse
-end
-item: Check Configuration
- Flags=10111011
-end
-item: Get Registry Key Value
- Variable=GROUPDIR
- Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
- Default=%WIN%\Start Menu\Programs
- Value Name=Programs
- Flags=00000010
-end
-item: Set Variable
- Variable=GROUP
- Value=%GROUPDIR%\%GROUP%
-end
-item: If/While Statement
- Variable=COMPONENTS
- Value=A
- Flags=00001010
-end
-item: Create Shortcut
- Source=%MAINDIR%\bin\wish85.exe
- Destination=%GROUP%\Wish.lnk
- Working Directory=%MAINDIR%
-end
-item: End Block
-end
-item: If/While Statement
- Variable=COMPONENTS
- Value=A
- Flags=00001010
-end
-item: Create Shortcut
- Source=%MAINDIR%\bin\tclsh85.exe
- Destination=%GROUP%\Tclsh.lnk
- Working Directory=%MAINDIR%
- Key Type=1536
- Flags=00000001
-end
-item: End Block
-end
-item: If/While Statement
- Variable=COMPONENTS
- Value=C
- Flags=00001010
-end
-item: Create Shortcut
- Source=%MAINDIR%\doc\tcl85.hlp
- Destination=%GROUP%\Tcl Help.lnk
- Working Directory=%MAINDIR%
-end
-item: End Block
-end
-item: Create Shortcut
- Source=%MAINDIR%\Readme.txt
- Destination=%GROUP%\Readme.lnk
- Working Directory=%MAINDIR%
-end
-item: If/While Statement
- Variable=COMPONENTS
- Value=B
- Flags=00001010
-end
-item: Create Shortcut
- Source=%MAINDIR%\lib\tk%VER%\demos\widget.tcl
- Destination=%GROUP%\Widget Tour.lnk
- Working Directory=%MAINDIR%
- Key Type=1536
- Flags=00000001
-end
-item: End Block
-end
-item: Else Statement
-end
-item: If/While Statement
- Variable=COMPONENTS
- Value=B
- Flags=00001010
-end
-item: Add ProgMan Icon
- Group=%GROUP%
- Icon Name=Widget Tour
- Command Line=%MAINDIR%\lib\tk%VER%\demos\widget.tcl
- Icon Pathname=%MAINDIR%\bin\wish85.exe
- Default Directory=%MAINDIR%
-end
-item: End Block
-end
-item: If/While Statement
- Variable=COMPONENTS
- Value=C
- Flags=00001010
-end
-item: Add ProgMan Icon
- Group=%GROUP%
- Icon Name=Tcl Help
- Command Line=%MAINDIR%\doc\tcl85.hlp
- Default Directory=%MAINDIR%
-end
-item: End Block
-end
-item: Add ProgMan Icon
- Group=%GROUP%
- Icon Name=Readme
- Command Line=%MAINDIR%\Readme.txt
- Default Directory=%MAINDIR%
-end
-item: If/While Statement
- Variable=COMPONENTS
- Value=A
- Flags=00001010
-end
-item: Add ProgMan Icon
- Group=%GROUP%
- Icon Name=Wish
- Command Line=%MAINDIR%\bin\wish85.exe
- Default Directory=%MAINDIR%
-end
-item: End Block
-end
-item: If/While Statement
- Variable=COMPONENTS
- Value=A
- Flags=00001010
-end
-item: Add ProgMan Icon
- Group=%GROUP%
- Icon Name=Tclsh
- Command Line=%MAINDIR%\bin\tclsh85.exe
- Default Directory=%MAINDIR%
-end
-item: End Block
-end
-item: End Block
-end
-item: Self-Register OCXs/DLLs
- Description=Updating System Configuration, Please Wait...
-end
-item: Edit Registry
- Total Keys=1
- Key=SOFTWARE\Scriptics\Tcl\%VER%
- New Value=%MAINDIR%
- Value Name=Root
- Root=2
-end
-item: Edit Registry
- Total Keys=1
- Key=TclScript\DefaultIcon
- New Value=%MAINDIR%\bin\tk85.dll
-end
-item: Edit Registry
- Total Keys=1
- Key=.tcl
- New Value=TclScript
-end
-item: Edit Registry
- Total Keys=1
- Key=TclScript
- New Value=TclScript
-end
-item: Edit Registry
- Total Keys=1
- Key=TclScript\shell\open\command
- New Value=%MAINDIRSHORT%\bin\wish85.exe "%%1" %%*
-end
-item: Edit Registry
- Total Keys=1
- Key=TclScript\shell\edit
- New Value=&Edit
-end
-item: Edit Registry
- Total Keys=1
- Key=TclScript\shell\edit\command
- New Value=notepad "%%1"
-end
-item: Add Directory to Path
- Directory=%MAINDIR%\bin
-end
-item: Check Configuration
- Flags=10111011
-end
-item: Set Variable
- Variable=TO_SCRIPTICS
- Value=A
-end
-item: Else Statement
-end
-item: Set Variable
- Variable=TO_SCRIPTICS
-end
-item: End Block
-end
-item: Wizard Block
- Direction Variable=DIRECTION
- Display Variable=DISPLAY
- Bitmap Pathname=%_WISE_%\DIALOGS\TEMPLATE\WIZARD.BMP
- X Position=9
- Y Position=10
- Filler Color=8421440
- Flags=00000011
-end
-item: Custom Dialog Set
- Name=Finished
- Display Variable=DISPLAY
- item: Dialog
- Title=%APPTITLE% Installation
- Title French=Installation de %APPTITLE%
- Title German=Installation von %APPTITLE%
- Title Spanish=Instalación de %APPTITLE%
- Title Italian=Installazione di %APPTITLE%
- Width=271
- Height=224
- Font Name=Helv
- Font Size=8
- item: Push Button
- Rectangle=150 187 195 202
- Variable=DIRECTION
- Value=N
- Create Flags=01010000000000010000000000000001
- Text=&Finish
- Text French=&Fin
- Text German=&Weiter
- Text Spanish=&Terminar
- Text Italian=&Fine
- end
- item: Push Button
- Rectangle=105 187 150 202
- Variable=DISABLED
- Value=!
- Create Flags=01010000000000010000000000000000
- Text=< &Back
- Text French=< &Retour
- Text German=< &Zurück
- Text Spanish=< &Atrás
- Text Italian=< &Indietro
- end
- item: Push Button
- Rectangle=211 187 256 202
- Variable=DISABLED
- Value=!
- Action=3
- Create Flags=01010000000000010000000000000000
- Text=&Cancel
- Text French=&Annuler
- Text German=&Abbrechen
- Text Spanish=&Cancelar
- Text Italian=&Annulla
- end
- item: Static
- Rectangle=8 180 256 181
- Action=3
- Create Flags=01010000000000000000000000000111
- end
- item: Static
- Rectangle=86 8 258 42
- Create Flags=01010000000000000000000000000000
- Flags=0000000000000001
- Name=Times New Roman
- Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
- Text=Installation Completed!
- Text French=Installation terminée !
- Text German=Die Installation ist abgeschlossen!
- Text Spanish=¡Instalación terminada!
- Text Italian=Installazione completata!
- end
- item: Static
- Rectangle=86 42 256 153
- Create Flags=01010000000000000000000000000000
- Text=%APPTITLE% has been successfully installed.
- Text=
- Text=Click the Finish button to exit this installation.
- Text=
- Text=You can learn more about Tcl/Tk %VER%, including release notes, updates, tutorials, and more at %URL%. Check the box below to start your web browser and go there now.
- Text=
- Text=The installer may ask you to reboot your computer, this is to update your PATH and is not necessary to do immediately.
- Text French=%APPTITLE% est maintenant installé.
- Text French=
- Text French=Cliquez sur le bouton Fin pour quitter l'installation.
- Text German=%APPTITLE% wurde erfolgreich installiert.
- Text German=
- Text German=Klicken Sie auf "Weiter", um die Installation zu beenden.
- Text Spanish=%APPTITLE% se ha instalado con éxito.
- Text Spanish=
- Text Spanish=Presione el botón Terminar para salir de esta instalación.
- Text Italian=L'installazione %APPTITLE% è stata portata a termine con successo.
- Text Italian=
- Text Italian=Premere il pulsante Fine per uscire dall'installazione.
- end
- item: Checkbox
- Rectangle=88 143 245 157
- Variable=TO_SCRIPTICS
- Enabled Color=00000000000000001111111111111111
- Create Flags=01010000000000010000000000000011
- Text=Show me important information about
- Text=
- end
- item: Static
- Rectangle=99 156 245 170
- Enabled Color=00000000000000001111111111111111
- Create Flags=01010000000000000000000000000000
- Text=Tcl/Tk %VER% and TclPro
- end
- end
-end
-item: End Block
-end
-item: Check Configuration
- Flags=10111011
-end
-item: If/While Statement
- Variable=TO_SCRIPTICS
- Value=A
- Flags=00000010
-end
-item: Execute Program
- Command Line=%URL%
-end
-item: End Block
-end
-item: Execute Program
- Pathname=explorer
- Command Line=%GROUP%
-end
-item: End Block
-end
diff --git a/tools/tclSplash.bmp b/tools/tclSplash.bmp
deleted file mode 100644
index db8a17e..0000000
--- a/tools/tclSplash.bmp
+++ /dev/null
Binary files differ
diff --git a/tools/tclmin.wse b/tools/tclmin.wse
deleted file mode 100644
index 2fd8185..0000000
--- a/tools/tclmin.wse
+++ /dev/null
@@ -1,247 +0,0 @@
-Document Type: WSE
-item: Global
- Version=5.0
- Flags=00000100
- Split=1420
- Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- Japanese Font Name=MS Gothic
- Japanese Font Size=10
- Start Gradient=0 0 255
- End Gradient=0 0 0
- Windows Flags=00000000000000010010110000001000
- Message Font=MS Sans Serif
- Font Size=8
- Disk Filename=SETUP
- Patch Flags=0000000000000001
- Patch Threshold=85
- Patch Memory=4000
-end
-item: Remark
- Text=-------
-end
-item: Remark
- Text=Tcl 8.0 Minimal Installation
-end
-item: Remark
- Text=-------
-end
-item: Install File
- Source=n:\dist\tcl8.0\library\opt0.4\pkgIndex.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\opt0.4\pkgIndex.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\library\opt0.4\optparse.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\opt0.4\optparse.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\library\http\pkgIndex.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\http2.4\pkgIndex.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\library\http\http.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\http2.4\http.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\library\safe.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\safe.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\library\history.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\history.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\msgbox.tcl
- Destination=%MAINDIR%\lib\tk%VER%\msgbox.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\optMenu.tcl
- Destination=%MAINDIR%\lib\tk%VER%\optMenu.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\clrpick.tcl
- Destination=%MAINDIR%\lib\tk%VER%\clrpick.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\entry.tcl
- Destination=%MAINDIR%\lib\tk%VER%\entry.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\comdlg.tcl
- Destination=%MAINDIR%\lib\tk%VER%\comdlg.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\bgerror.tcl
- Destination=%MAINDIR%\lib\tk%VER%\bgerror.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\obsolete.tcl
- Destination=%MAINDIR%\lib\tk%VER%\obsolete.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\button.tcl
- Destination=%MAINDIR%\lib\tk%VER%\button.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\xmfbox.tcl
- Destination=%MAINDIR%\lib\tk%VER%\xmfbox.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\console.tcl
- Destination=%MAINDIR%\lib\tk%VER%\console.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\listbox.tcl
- Destination=%MAINDIR%\lib\tk%VER%\listbox.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\menu.tcl
- Destination=%MAINDIR%\lib\tk%VER%\menu.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\dialog.tcl
- Destination=%MAINDIR%\lib\tk%VER%\dialog.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\focus.tcl
- Destination=%MAINDIR%\lib\tk%VER%\focus.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\palette.tcl
- Destination=%MAINDIR%\lib\tk%VER%\palette.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\tkfbox.tcl
- Destination=%MAINDIR%\lib\tk%VER%\tkfbox.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\tk.tcl
- Destination=%MAINDIR%\lib\tk%VER%\tk.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\text.tcl
- Destination=%MAINDIR%\lib\tk%VER%\text.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\tearoff.tcl
- Destination=%MAINDIR%\lib\tk%VER%\tearoff.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\tclIndex
- Destination=%MAINDIR%\lib\tk%VER%\tclIndex
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\scrlbar.tcl
- Destination=%MAINDIR%\lib\tk%VER%\scrlbar.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\scale.tcl
- Destination=%MAINDIR%\lib\tk%VER%\scale.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\library\safetk.tcl
- Destination=%MAINDIR%\lib\tk%VER%\safetk.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\library\http1.0\pkgIndex.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\http1.0\pkgIndex.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\library\http1.0\http.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\http1.0\http.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\win\pkgIndex.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\reg1.0\pkgIndex.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\win\tclreg80.dll
- Destination=%MAINDIR%\lib\tcl%VER%\reg1.0\tclreg80.dll
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\win\Tcl1680.dll
- Destination=%SYS32%\Tcl1680.dll
- Flags=0000001000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\win\tcl80.dll
- Destination=%SYS32%\tcl80.dll
- Flags=0000001000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\win\tclpip80.dll
- Destination=%SYS32%\tclpip80.dll
- Flags=0000001000000010
-end
-item: Install File
- Source=n:\dist\Bc45\Bin\cw3215.dll
- Destination=%SYS32%\cw3215.dll
- Flags=0000001000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\win\tk80.dll
- Destination=%SYS32%\tk80.dll
- Flags=0000001000000010
-end
-item: Install File
- Source=n:\dist\tk8.0\win\wish80.exe
- Destination=%MAINDIR%\bin\wish80.exe
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\win\tclsh80.exe
- Destination=%MAINDIR%\bin\tclsh80.exe
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\library\tclIndex
- Destination=%MAINDIR%\lib\tcl%VER%\tclIndex
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\library\init.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\init.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\library\parray.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\parray.tcl
- Flags=0000000000000010
-end
-item: Install File
- Source=n:\dist\tcl8.0\library\word.tcl
- Destination=%MAINDIR%\lib\tcl%VER%\word.tcl
- Flags=0000000000000010
-end
diff --git a/tools/tcltk-man2html-utils.tcl b/tools/tcltk-man2html-utils.tcl
index 938a1af..8fd1245 100644
--- a/tools/tcltk-man2html-utils.tcl
+++ b/tools/tcltk-man2html-utils.tcl
@@ -35,7 +35,7 @@ proc fatal {msg} {
uplevel 1 [list manerror $msg]
exit 1
}
-
+
##
## templating
##
@@ -46,6 +46,7 @@ proc indexfile {} {
return "contents.htm"
}
}
+
proc copyright {copyright {level {}}} {
# We don't actually generate a separate copyright page anymore
#set page "${level}copyright.htm"
@@ -54,6 +55,7 @@ proc copyright {copyright {level {}}} {
set who [string map {@ (at)} [lrange $copyright 2 end]]
return "Copyright &copy; [htmlize-text $who]"
}
+
proc copyout {copyrights {level {}}} {
set out "<div class=\"copy\">"
foreach c $copyrights {
@@ -62,12 +64,15 @@ proc copyout {copyrights {level {}}} {
append out "</div>"
return $out
}
+
proc CSS {{level ""}} {
return "<link rel=\"stylesheet\" href=\"${level}$::CSSFILE\" type=\"text/css\" media=\"all\">\n"
}
+
proc DOCTYPE {} {
return "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"
}
+
proc htmlhead {title header args} {
set level ""
if {[lindex $args end] eq "../[indexfile]"} {
@@ -93,7 +98,7 @@ proc htmlhead {title header args} {
}
return $out
}
-
+
##
## parsing
##
@@ -110,6 +115,7 @@ proc htmlize-text {text {charmap {}}} {
# contains some extras for use in nroff->html processing
# build on the list passed in, if any
lappend charmap \
+ "&ndash;" "&ndash;" \
{&} {&amp;} \
{\\} "&#92;" \
{\e} "&#92;" \
@@ -136,6 +142,7 @@ proc process-text {text} {
{\(+-} "&#177;" \
{\(co} "&copy;" \
{\(em} "&#8212;" \
+ {\(en} "&#8211;" \
{\(fm} "&#8242;" \
{\(mu} "&#215;" \
{\(mi} "&#8722;" \
@@ -143,8 +150,8 @@ proc process-text {text} {
{\fP} {\fR} \
{\.} . \
{\(bu} "&#8226;" \
+ {\*(qo} "&ocirc;" \
]
- lappend charmap {\o'o^'} {&ocirc;} ; # o-circumflex in re_syntax.n
lappend charmap {\-\|\-} -- ; # two hyphens
lappend charmap {\-} - ; # a hyphen
@@ -186,6 +193,7 @@ proc process-text {text} {
}
return $text
}
+
##
## pass 2 text input and matching
##
@@ -194,10 +202,12 @@ proc open-text {} {
set manual(text-length) [llength $manual(text)]
set manual(text-pointer) 0
}
+
proc more-text {} {
global manual
return [expr {$manual(text-pointer) < $manual(text-length)}]
}
+
proc next-text {} {
global manual
if {[more-text]} {
@@ -208,14 +218,17 @@ proc next-text {} {
manerror "read past end of text"
error "fatal"
}
+
proc is-a-directive {line} {
return [string match .* $line]
}
+
proc split-directive {line opname restname} {
upvar 1 $opname op $restname rest
set op [string range $line 0 2]
set rest [string trim [string range $line 3 end]]
}
+
proc next-op-is {op restname} {
global manual
upvar 1 $restname rest
@@ -229,12 +242,14 @@ proc next-op-is {op restname} {
}
return 0
}
+
proc backup-text {n} {
global manual
if {$manual(text-pointer)-$n >= 0} {
incr manual(text-pointer) -$n
}
}
+
proc match-text args {
global manual
set nargs [llength $args]
@@ -274,11 +289,13 @@ proc match-text args {
}
return 1
}
+
proc expand-next-text {n} {
global manual
return [join [lrange $manual(text) $manual(text-pointer) \
[expr {$manual(text-pointer)+$n-1}]] \n\n]
}
+
##
## pass 2 output
##
@@ -286,7 +303,7 @@ proc man-puts {text} {
global manual
lappend manual(output-$manual(wing-file)-$manual(name)) $text
}
-
+
##
## build hypertext links to tables of contents
##
@@ -299,6 +316,7 @@ proc long-toc {text} {
"<DD><A HREF=\"$manual(name).htm#$here\" NAME=\"$there\">$text</A>"
return "<A NAME=\"$here\">$text</A>"
}
+
proc option-toc {name class switch} {
global manual
# Special case handling, oh we hate it but must do it
@@ -326,6 +344,7 @@ proc option-toc {name class switch} {
"<DD><A HREF=\"$manual(name).htm#$here\" NAME=\"$there\">$switch, $name, $class</A>"
return "<A NAME=\"$here\">$switch</A>"
}
+
proc std-option-toc {name page} {
global manual
if {[info exists manual(standard-option-$page-$name)]} {
@@ -339,6 +358,7 @@ proc std-option-toc {name page} {
lappend manual(section-toc) "<DD><A HREF=\"$page.htm#$other\">$name</A>"
return "<A HREF=\"$page.htm#$other\">$name</A>"
}
+
##
## process the widget option section
## in widget and options man pages
@@ -410,7 +430,7 @@ proc output-widget-options {rest} {
man-puts </DL>
lappend manual(section-toc) </DL>
}
-
+
##
## process .RS lists
##
@@ -454,7 +474,7 @@ proc output-RS-list {} {
}
man-puts </DL>
}
-
+
##
## process .IP lists which may be plain indents,
## numeric lists, or definition lists
@@ -593,6 +613,7 @@ proc output-IP-list {context code rest} {
}
}
}
+
##
## handle the NAME section lines
## there's only one line in the NAME section,
@@ -616,7 +637,9 @@ proc output-name {line} {
lappend manual(wing-toc) $name
lappend manual(name-$name) $manual(wing-file)/$manual(name)
}
+ set manual(tooltip-$manual(wing-file)/$manual(name).htm) $line
}
+
##
## build a cross-reference link if appropriate
##
@@ -725,6 +748,7 @@ proc cross-reference {ref} {
##
return "<A HREF=\"../$manref.htm\">$ref</A>"
}
+
##
## reference generation errors
##
@@ -733,6 +757,7 @@ proc reference-error {msg text} {
puts stderr "$manual(tail): $msg: {$text}"
return $text
}
+
##
## insert as many cross references into this text string as are appropriate
##
@@ -876,7 +901,7 @@ proc insert-cross-references {text} {
append result [string range $text 0 [expr {$off-1}]]
regexp -indices -start $off {http://[\w/.]+} $text range
set url [string range $text {*}$range]
- append result "<A HREF=\"$url\">" $url "</A>"
+ append result "<A HREF=\"[string trimright $url .]\">$url</A>"
set text [string range $text[set text ""] \
[expr {[lindex $range 1]+1}] end]
continue
@@ -887,6 +912,7 @@ proc insert-cross-references {text} {
}
}
}
+
##
## process formatting directives
##
@@ -919,7 +945,9 @@ proc output-directive {line} {
set line [next-text]
if {[is-a-directive $line]} {
backup-text 1
- output-name [join $names { }]
+ if {[llength $names]} {
+ output-name [join $names { }]
+ }
return
}
lappend names [string trim $line]
@@ -1063,25 +1091,17 @@ proc output-directive {line} {
output-IP-list .IP .IP $rest
return
}
- .PP {
+ .PP - .sp {
man-puts <P>
}
.RS {
output-RS-list
return
}
- .RE {
- manerror "unexpected .RE"
- return
- }
.br {
man-puts <BR>
return
}
- .DE {
- manerror "unexpected .DE"
- return
- }
.DS {
if {[next-op-is .ta rest]} {
# skip the leading .ta directive if it is there
@@ -1109,16 +1129,6 @@ proc output-directive {line} {
}
return
}
- .CE {
- manerror "unexpected .CE"
- return
- }
- .sp {
- man-puts <P>
- }
- .ta {
- manerror "ignoring $line"
- }
.nf {
if {[match-text @more .fi]} {
foreach more [split $more \n] {
@@ -1174,13 +1184,11 @@ proc output-directive {line} {
manerror "ignoring $line"
}
}
- .fi {
- manerror "ignoring $line"
+ .RE - .DE - .CE {
+ manerror "unexpected $code"
+ return
}
- .na -
- .ad -
- .UL -
- .ne {
+ .ta - .fi - .na - .ad - .UL - .ie - .el - .ne {
manerror "ignoring $line"
}
default {
@@ -1188,6 +1196,7 @@ proc output-directive {line} {
}
}
}
+
##
## merge copyright listings
##
@@ -1225,7 +1234,373 @@ proc merge-copyrights {l1 l2} {
}
return [lsort -dictionary $merge]
}
+
+##
+## foreach of the man pages in the section specified by
+## sectionDescriptor, convert manpages into hypertext in
+## the directory specified by outputDir.
+##
+proc make-manpage-section {outputDir sectionDescriptor} {
+ global manual overall_title tcltkdesc verbose
+ global excluded_pages forced_index_pages process_first_patterns
+
+ set LQ \u201c
+ set RQ \u201d
+
+ lassign $sectionDescriptor \
+ manual(wing-glob) \
+ manual(wing-name) \
+ manual(wing-file) \
+ manual(wing-description)
+ set manual(wing-copyrights) {}
+ makedirhier $outputDir/$manual(wing-file)
+ set manual(wing-toc-fp) [open $outputDir/$manual(wing-file)/[indexfile] w]
+ # whistle
+ puts stderr "scanning section $manual(wing-name)"
+ # put the entry for this section into the short table of contents
+ if {[regexp {^(.+), version (.+)$} $manual(wing-name) -> name version]} {
+ puts $manual(short-toc-fp) "<DT><A HREF=\"$manual(wing-file)/[indexfile]\" TITLE=\"version $version\">$name</A></DT><DD>$manual(wing-description)</DD>"
+ } else {
+ puts $manual(short-toc-fp) "<DT><A HREF=\"$manual(wing-file)/[indexfile]\">$manual(wing-name)</A></DT><DD>$manual(wing-description)</DD>"
+ }
+ # initialize the wing table of contents
+ puts $manual(wing-toc-fp) [htmlhead $manual(wing-name) \
+ $manual(wing-name) $overall_title "../[indexfile]"]
+ # initialize the short table of contents for this section
+ set manual(wing-toc) {}
+ # initialize the man directory for this section
+ makedirhier $outputDir/$manual(wing-file)
+ # initialize the long table of contents for this section
+ set manual(long-toc-n) 1
+ # get the manual pages for this section
+ set manual(pages) [lsort -dictionary [glob -nocomplain $manual(wing-glob)]]
+ # Some pages have to go first so that their links override others
+ foreach pat $process_first_patterns {
+ set n [lsearch -glob $manual(pages) $pat]
+ if {$n >= 0} {
+ set f [lindex $manual(pages) $n]
+ puts stderr "shuffling [file tail $f] to front of processing queue"
+ set manual(pages) \
+ [linsert [lreplace $manual(pages) $n $n] 0 $f]
+ }
+ }
+ # set manual(pages) [lrange $manual(pages) 0 5]
+ foreach manual_page $manual(pages) {
+ set manual(page) [file normalize $manual_page]
+ # whistle
+ if {$verbose} {
+ puts stderr "scanning page $manual(page)"
+ } else {
+ puts -nonewline stderr .
+ }
+ set manual(tail) [file tail $manual(page)]
+ set manual(name) [file root $manual(tail)]
+ set manual(section) {}
+ if {$manual(name) in $excluded_pages} {
+ # obsolete
+ if {!$verbose} {
+ puts stderr ""
+ }
+ manerror "discarding $manual(name)"
+ continue
+ }
+ set manual(infp) [open $manual(page)]
+ set manual(text) {}
+ set manual(partial-text) {}
+ foreach p {.RS .DS .CS .SO} {
+ set manual($p) 0
+ }
+ set manual(stack) {}
+ set manual(section) {}
+ set manual(section-toc) {}
+ set manual(section-toc-n) 1
+ set manual(copyrights) {}
+ lappend manual(all-pages) $manual(wing-file)/$manual(tail)
+ lappend manual(all-page-domains) $manual(wing-name)
+ manreport 100 $manual(name)
+ while {[gets $manual(infp) line] >= 0} {
+ manreport 100 $line
+ if {[regexp {^[`'][/\\]} $line]} {
+ if {[regexp {Copyright (?:\(c\)|\\\(co).*$} $line copyright]} {
+ lappend manual(copyrights) $copyright
+ }
+ # comment
+ continue
+ }
+ if {"$line" eq {'}} {
+ # comment
+ continue
+ }
+ if {![parse-directive $line code rest]} {
+ addbuffer $line
+ continue
+ }
+ switch -exact -- $code {
+ .if - .nr - .ti - .in - .ie - .el -
+ .ad - .na - .so - .ne - .AS - .HS - .VE - .VS - . {
+ # ignore
+ continue
+ }
+ }
+ switch -exact -- $code {
+ .SH - .SS {
+ flushbuffer
+ if {[llength $rest] == 0} {
+ gets $manual(infp) rest
+ }
+ lappend manual(text) "$code [unquote $rest]"
+ }
+ .TH {
+ flushbuffer
+ lappend manual(text) "$code [unquote $rest]"
+ }
+ .QW {
+ lassign [regexp -all -inline {\"(?:[^""]+)\"|\S+} $rest] \
+ inQuote afterwards
+ addbuffer $LQ [unquote $inQuote] $RQ [unquote $afterwards]
+ }
+ .PQ {
+ lassign [regexp -all -inline {\"(?:[^""]+)\"|\S+} $rest] \
+ inQuote punctuation afterwards
+ addbuffer ( $LQ [unquote $inQuote] $RQ \
+ [unquote $punctuation] ) [unquote $afterwards]
+ }
+ .QR {
+ lassign [regexp -all -inline {\"(?:[^""]+)\"|\S+} $rest] \
+ rangeFrom rangeTo afterwards
+ addbuffer $LQ [unquote $rangeFrom] "&ndash;" \
+ [unquote $rangeTo] $RQ [unquote $afterwards]
+ }
+ .MT {
+ addbuffer $LQ$RQ
+ }
+ .HS - .UL - .ta {
+ flushbuffer
+ lappend manual(text) "$code [unquote $rest]"
+ }
+ .BS - .BE - .br - .fi - .sp - .nf {
+ flushbuffer
+ if {$rest ne ""} {
+ if {!$verbose} {
+ puts stderr ""
+ }
+ manerror "unexpected argument: $line"
+ }
+ lappend manual(text) $code
+ }
+ .AP {
+ flushbuffer
+ lappend manual(text) [concat .IP [process-text \
+ "[lindex $rest 0] \\fB[lindex $rest 1]\\fR ([lindex $rest 2])"]]
+ }
+ .IP {
+ flushbuffer
+ regexp {^(.*) +\d+$} $rest all rest
+ lappend manual(text) ".IP [process-text \
+ [unquote [string trim $rest]]]"
+ }
+ .TP {
+ flushbuffer
+ while {[is-a-directive [set next [gets $manual(infp)]]]} {
+ if {!$verbose} {
+ puts stderr ""
+ }
+ manerror "ignoring $next after .TP"
+ }
+ if {"$next" ne {'}} {
+ lappend manual(text) ".IP [process-text $next]"
+ }
+ }
+ .OP {
+ flushbuffer
+ lassign $rest cmdName dbName dbClass
+ lappend manual(text) [concat .OP [process-text \
+ "\\fB$cmdName\\fR \\fB$dbName\\fR \\fB$dbClass\\fR"]]
+ }
+ .PP - .LP {
+ flushbuffer
+ lappend manual(text) {.PP}
+ }
+ .RS {
+ flushbuffer
+ incr manual(.RS)
+ lappend manual(text) $code
+ }
+ .RE {
+ flushbuffer
+ incr manual(.RS) -1
+ lappend manual(text) $code
+ }
+ .SO {
+ flushbuffer
+ incr manual(.SO)
+ if {[llength $rest] == 0} {
+ lappend manual(text) "$code options"
+ } else {
+ lappend manual(text) "$code [unquote $rest]"
+ }
+ }
+ .SE {
+ flushbuffer
+ incr manual(.SO) -1
+ lappend manual(text) $code
+ }
+ .DS {
+ flushbuffer
+ incr manual(.DS)
+ lappend manual(text) $code
+ }
+ .DE {
+ flushbuffer
+ incr manual(.DS) -1
+ lappend manual(text) $code
+ }
+ .CS {
+ flushbuffer
+ incr manual(.CS)
+ lappend manual(text) $code
+ }
+ .CE {
+ flushbuffer
+ incr manual(.CS) -1
+ lappend manual(text) $code
+ }
+ .de {
+ while {[gets $manual(infp) line] >= 0} {
+ if {[string match "..*" $line]} {
+ break
+ }
+ }
+ }
+ .. {
+ if {!$verbose} {
+ puts stderr ""
+ }
+ error "found .. outside of .de"
+ }
+ default {
+ if {!$verbose} {
+ puts stderr ""
+ }
+ flushbuffer
+ manerror "unrecognized format directive: $line"
+ }
+ }
+ }
+ flushbuffer
+ close $manual(infp)
+ # fixups
+ if {$manual(.RS) != 0} {
+ if {!$verbose} {
+ puts stderr ""
+ }
+ puts "unbalanced .RS .RE"
+ }
+ if {$manual(.DS) != 0} {
+ if {!$verbose} {
+ puts stderr ""
+ }
+ puts "unbalanced .DS .DE"
+ }
+ if {$manual(.CS) != 0} {
+ if {!$verbose} {
+ puts stderr ""
+ }
+ puts "unbalanced .CS .CE"
+ }
+ if {$manual(.SO) != 0} {
+ if {!$verbose} {
+ puts stderr ""
+ }
+ puts "unbalanced .SO .SE"
+ }
+ # output conversion
+ open-text
+ set haserror 0
+ if {[next-op-is .HS rest]} {
+ set manual($manual(wing-file)-$manual(name)-title) \
+ "[join [lrange $rest 1 end] { }] [lindex $rest 0] manual page"
+ } elseif {[next-op-is .TH rest]} {
+ set manual($manual(wing-file)-$manual(name)-title) \
+ "[lindex $rest 0] manual page - [join [lrange $rest 4 end] { }]"
+ } else {
+ set haserror 1
+ if {!$verbose} {
+ puts stderr ""
+ }
+ manerror "no .HS or .TH record found"
+ }
+ if {!$haserror} {
+ while {[more-text]} {
+ set line [next-text]
+ if {[is-a-directive $line]} {
+ output-directive $line
+ } else {
+ man-puts $line
+ }
+ }
+ man-puts [copyout $manual(copyrights) "../"]
+ set manual(wing-copyrights) [merge-copyrights \
+ $manual(wing-copyrights) $manual(copyrights)]
+ }
+ #
+ # make the long table of contents for this page
+ #
+ set manual(toc-$manual(wing-file)-$manual(name)) \
+ [concat <DL> $manual(section-toc) </DL>]
+ }
+ if {!$verbose} {
+ puts stderr ""
+ }
+
+ #
+ # make the wing table of contents for the section
+ #
+ set width 0
+ foreach name $manual(wing-toc) {
+ if {[string length $name] > $width} {
+ set width [string length $name]
+ }
+ }
+ set perline [expr {118 / $width}]
+ set nrows [expr {([llength $manual(wing-toc)]+$perline)/$perline}]
+ set n 0
+ catch {unset rows}
+ foreach name [lsort -dictionary $manual(wing-toc)] {
+ set tail $manual(name-$name)
+ if {[llength $tail] > 1} {
+ manerror "$name is defined in more than one file: $tail"
+ set tail [lindex $tail [expr {[llength $tail]-1}]]
+ }
+ set tail [file tail $tail]
+ if {[info exists manual(tooltip-$manual(wing-file)/$tail.htm)]} {
+ set tooltip $manual(tooltip-$manual(wing-file)/$tail.htm)
+ set tooltip [string map {[ {\[} ] {\]} $ {\$} \\ \\\\} $tooltip]
+ regsub {^[^-]+-\s*(.)} $tooltip {[string totitle \1]} tooltip
+ append rows([expr {$n%$nrows}]) \
+ "<td> <a href=\"$tail.htm\" title=\"[subst $tooltip]\">$name</a> </td>"
+ } else {
+ append rows([expr {$n%$nrows}]) \
+ "<td> <a href=\"$tail.htm\">$name</a> </td>"
+ }
+ incr n
+ }
+ puts $manual(wing-toc-fp) <table>
+ foreach row [lsort -integer [array names rows]] {
+ puts $manual(wing-toc-fp) <tr>$rows($row)</tr>
+ }
+ puts $manual(wing-toc-fp) </table>
+ #
+ # insert wing copyrights
+ #
+ puts $manual(wing-toc-fp) [copyout $manual(wing-copyrights) "../"]
+ puts $manual(wing-toc-fp) "</BODY></HTML>"
+ close $manual(wing-toc-fp)
+ set manual(merge-copyrights) \
+ [merge-copyrights $manual(merge-copyrights) $manual(wing-copyrights)]
+}
+
proc makedirhier {dir} {
try {
if {![file isdirectory $dir]} {
diff --git a/tools/tcltk-man2html.tcl b/tools/tcltk-man2html.tcl
index b347abf..89e8e5c 100755
--- a/tools/tcltk-man2html.tcl
+++ b/tools/tcltk-man2html.tcl
@@ -1,8 +1,12 @@
-#!/bin/sh
-# The next line is executed by /bin/sh, but not tcl \
-exec tclsh "$0" ${1+"$@"}
+#!/usr/bin/env tclsh
-package require Tcl 8.6
+if {[catch {package require Tcl 8.6} msg]} {
+ puts stderr "ERROR: $msg"
+ puts stderr "If running this script from 'make html', set the\
+ NATIVE_TCLSH environment\nvariable to point to an installed\
+ tclsh8.6 (or the equivalent tclsh86.exe\non Windows)."
+ exit 1
+}
# Convert Ousterhout format man pages into highly crosslinked hypertext.
#
@@ -18,7 +22,7 @@ package require Tcl 8.6
# Copyright (c) 1995-1997 Roger E. Critchlow Jr
# Copyright (c) 2004-2010 Donal K. Fellows
-regexp {\d+\.\d+} {$Revision: 1.49 $} ::Version
+set ::Version "50/8.6"
set ::CSSFILE "docs.css"
##
@@ -261,362 +265,36 @@ proc make-man-pages {html args} {
puts $manual(short-toc-fp) "<DL class=\"keylist\">"
set manual(merge-copyrights) {}
- set LQ \u201c
- set RQ \u201d
-
foreach arg $args {
# preprocess to set up subheader for the rest of the files
if {![llength $arg]} {
continue
}
- set name [lindex $arg 1]
- set file [lindex $arg 2]
+ lassign $arg -> name file
+ if {[regexp {(.*)(?: Package)? Commands(?:, version .*)?} $name -> pkg]} {
+ set name "$pkg Commands"
+ } elseif {[regexp {(.*)(?: Package)? C API(?:, version .*)?} $name -> pkg]} {
+ set name "$pkg C API"
+ }
lappend manual(subheader) $name $file
}
- foreach arg $args {
- if {![llength $arg]} {
- continue
- }
- set manual(wing-glob) [lindex $arg 0]
- set manual(wing-name) [lindex $arg 1]
- set manual(wing-file) [lindex $arg 2]
- set manual(wing-description) [lindex $arg 3]
- set manual(wing-copyrights) {}
- makedirhier $html/$manual(wing-file)
- set manual(wing-toc-fp) [open $html/$manual(wing-file)/[indexfile] w]
- # whistle
- puts stderr "scanning section $manual(wing-name)"
- # put the entry for this section into the short table of contents
- puts $manual(short-toc-fp) "<DT><A HREF=\"$manual(wing-file)/[indexfile]\">$manual(wing-name)</A></DT><DD>$manual(wing-description)</DD>"
- # initialize the wing table of contents
- puts $manual(wing-toc-fp) [htmlhead $manual(wing-name) \
- $manual(wing-name) $overall_title "../[indexfile]"]
- # initialize the short table of contents for this section
- set manual(wing-toc) {}
- # initialize the man directory for this section
- makedirhier $html/$manual(wing-file)
- # initialize the long table of contents for this section
- set manual(long-toc-n) 1
- # get the manual pages for this section
- set manual(pages) [lsort -dictionary [glob -nocomplain $manual(wing-glob)]]
- # Some pages have to go first so that their links override others
- foreach pat $process_first_patterns {
- set n [lsearch -glob $manual(pages) $pat]
- if {$n >= 0} {
- set f [lindex $manual(pages) $n]
- puts stderr "shuffling [file tail $f] to front of processing queue"
- set manual(pages) \
- [linsert [lreplace $manual(pages) $n $n] 0 $f]
- }
- }
- # set manual(pages) [lrange $manual(pages) 0 5]
- foreach manual_page $manual(pages) {
- set manual(page) [file normalize $manual_page]
- # whistle
- if {$verbose} {
- puts stderr "scanning page $manual(page)"
- } else {
- puts -nonewline stderr .
- }
- set manual(tail) [file tail $manual(page)]
- set manual(name) [file root $manual(tail)]
- set manual(section) {}
- if {$manual(name) in $excluded_pages} {
- # obsolete
- if {!$verbose} {
- puts stderr ""
- }
- manerror "discarding $manual(name)"
- continue
- }
- set manual(infp) [open $manual(page)]
- set manual(text) {}
- set manual(partial-text) {}
- foreach p {.RS .DS .CS .SO} {
- set manual($p) 0
- }
- set manual(stack) {}
- set manual(section) {}
- set manual(section-toc) {}
- set manual(section-toc-n) 1
- set manual(copyrights) {}
- lappend manual(all-pages) $manual(wing-file)/$manual(tail)
- manreport 100 $manual(name)
- while {[gets $manual(infp) line] >= 0} {
- manreport 100 $line
- if {[regexp {^[`'][/\\]} $line]} {
- if {[regexp {Copyright (?:\(c\)|\\\(co).*$} $line copyright]} {
- lappend manual(copyrights) $copyright
- }
- # comment
- continue
- }
- if {"$line" eq {'}} {
- # comment
- continue
- }
- if {![parse-directive $line code rest]} {
- addbuffer $line
- continue
- }
- switch -exact -- $code {
- .if - .nr - .ti - .in -
- .ad - .na - .so - .ne - .AS - .VE - .VS - . {
- # ignore
- continue
- }
- }
- switch -exact -- $code {
- .SH - .SS {
- flushbuffer
- if {[llength $rest] == 0} {
- gets $manual(infp) rest
- }
- lappend manual(text) "$code [unquote $rest]"
- }
- .TH {
- flushbuffer
- lappend manual(text) "$code [unquote $rest]"
- }
- .QW {
- set rest [regexp -all -inline {\"(?:[^""]+)\"|\S+} $rest]
- addbuffer $LQ [unquote [lindex $rest 0]] $RQ \
- [unquote [lindex $rest 1]]
- }
- .PQ {
- set rest [regexp -all -inline {\"(?:[^""]+)\"|\S+} $rest]
- addbuffer ( $LQ [unquote [lindex $rest 0]] $RQ \
- [unquote [lindex $rest 1]] ) \
- [unquote [lindex $rest 2]]
- }
- .QR {
- set rest [regexp -all -inline {\"(?:[^""]+)\"|\S+} $rest]
- addbuffer $LQ [unquote [lindex $rest 0]] - \
- [unquote [lindex $rest 1]] $RQ \
- [unquote [lindex $rest 2]]
- }
- .MT {
- addbuffer $LQ$RQ
- }
- .HS - .UL - .ta {
- flushbuffer
- lappend manual(text) "$code [unquote $rest]"
- }
- .BS - .BE - .br - .fi - .sp - .nf {
- flushbuffer
- if {"$rest" ne {}} {
- if {!$verbose} {
- puts stderr ""
- }
- manerror "unexpected argument: $line"
- }
- lappend manual(text) $code
- }
- .AP {
- flushbuffer
- lappend manual(text) [concat .IP [process-text "[lindex $rest 0] \\fB[lindex $rest 1]\\fR ([lindex $rest 2])"]]
- }
- .IP {
- flushbuffer
- regexp {^(.*) +\d+$} $rest all rest
- lappend manual(text) ".IP [process-text [unquote [string trim $rest]]]"
- }
- .TP {
- flushbuffer
- while {[is-a-directive [set next [gets $manual(infp)]]]} {
- if {!$verbose} {
- puts stderr ""
- }
- manerror "ignoring $next after .TP"
- }
- if {"$next" ne {'}} {
- lappend manual(text) ".IP [process-text $next]"
- }
- }
- .OP {
- flushbuffer
- lappend manual(text) [concat .OP [process-text \
- "\\fB[lindex $rest 0]\\fR \\fB[lindex $rest 1]\\fR \\fB[lindex $rest 2]\\fR"]]
- }
- .PP - .LP {
- flushbuffer
- lappend manual(text) {.PP}
- }
- .RS {
- flushbuffer
- incr manual(.RS)
- lappend manual(text) $code
- }
- .RE {
- flushbuffer
- incr manual(.RS) -1
- lappend manual(text) $code
- }
- .SO {
- flushbuffer
- incr manual(.SO)
- if {[llength $rest] == 0} {
- lappend manual(text) "$code options"
- } else {
- lappend manual(text) "$code [unquote $rest]"
- }
- }
- .SE {
- flushbuffer
- incr manual(.SO) -1
- lappend manual(text) $code
- }
- .DS {
- flushbuffer
- incr manual(.DS)
- lappend manual(text) $code
- }
- .DE {
- flushbuffer
- incr manual(.DS) -1
- lappend manual(text) $code
- }
- .CS {
- flushbuffer
- incr manual(.CS)
- lappend manual(text) $code
- }
- .CE {
- flushbuffer
- incr manual(.CS) -1
- lappend manual(text) $code
- }
- .de {
- while {[gets $manual(infp) line] >= 0} {
- if {[string match "..*" $line]} {
- break
- }
- }
- }
- .. {
- if {!$verbose} {
- puts stderr ""
- }
- error "found .. outside of .de"
- }
- default {
- if {!$verbose} {
- puts stderr ""
- }
- flushbuffer
- manerror "unrecognized format directive: $line"
- }
- }
- }
- flushbuffer
- close $manual(infp)
- # fixups
- if {$manual(.RS) != 0} {
- if {!$verbose} {
- puts stderr ""
- }
- puts "unbalanced .RS .RE"
- }
- if {$manual(.DS) != 0} {
- if {!$verbose} {
- puts stderr ""
- }
- puts "unbalanced .DS .DE"
- }
- if {$manual(.CS) != 0} {
- if {!$verbose} {
- puts stderr ""
- }
- puts "unbalanced .CS .CE"
- }
- if {$manual(.SO) != 0} {
- if {!$verbose} {
- puts stderr ""
- }
- puts "unbalanced .SO .SE"
- }
- # output conversion
- open-text
- set haserror 0
- if {[next-op-is .HS rest]} {
- set manual($manual(wing-file)-$manual(name)-title) \
- "[join [lrange $rest 1 end] { }] [lindex $rest 0] manual page"
- } elseif {[next-op-is .TH rest]} {
- set manual($manual(wing-file)-$manual(name)-title) \
- "[lindex $rest 0] manual page - [join [lrange $rest 4 end] { }]"
- } else {
- set haserror 1
- if {!$verbose} {
- puts stderr ""
- }
- manerror "no .HS or .TH record found"
- }
- if {!$haserror} {
- while {[more-text]} {
- set line [next-text]
- if {[is-a-directive $line]} {
- output-directive $line
- } else {
- man-puts $line
- }
- }
- man-puts [copyout $manual(copyrights) "../"]
- set manual(wing-copyrights) [merge-copyrights \
- $manual(wing-copyrights) $manual(copyrights)]
- }
- #
- # make the long table of contents for this page
- #
- set manual(toc-$manual(wing-file)-$manual(name)) \
- [concat <DL> $manual(section-toc) </DL>]
- }
- if {!$verbose} {
- puts stderr ""
- }
- #
- # make the wing table of contents for the section
- #
- set width 0
- foreach name $manual(wing-toc) {
- if {[string length $name] > $width} {
- set width [string length $name]
- }
- }
- set perline [expr {118 / $width}]
- set nrows [expr {([llength $manual(wing-toc)]+$perline)/$perline}]
- set n 0
- catch {unset rows}
- foreach name [lsort -dictionary $manual(wing-toc)] {
- set tail $manual(name-$name)
- if {[llength $tail] > 1} {
- manerror "$name is defined in more than one file: $tail"
- set tail [lindex $tail [expr {[llength $tail]-1}]]
- }
- set tail [file tail $tail]
- append rows([expr {$n%$nrows}]) \
- "<td> <a href=\"$tail.htm\">$name</a> </td>"
- incr n
- }
- puts $manual(wing-toc-fp) <table>
- foreach row [lsort -integer [array names rows]] {
- puts $manual(wing-toc-fp) <tr>$rows($row)</tr>
+ ##
+ ## parse the manpages in a section of the docs (split by
+ ## package) and construct formatted manpages
+ ##
+ foreach arg $args {
+ if {[llength $arg]} {
+ make-manpage-section $html $arg
}
- puts $manual(wing-toc-fp) </table>
-
- #
- # insert wing copyrights
- #
- puts $manual(wing-toc-fp) [copyout $manual(wing-copyrights) "../"]
- puts $manual(wing-toc-fp) "</BODY></HTML>"
- close $manual(wing-toc-fp)
- set manual(merge-copyrights) [merge-copyrights \
- $manual(merge-copyrights) $manual(wing-copyrights)]
}
##
## build the keyword index.
##
+ if {!$verbose} {
+ puts stderr "Assembling index"
+ }
file delete -force -- $html/Keywords
makedirhier $html/Keywords
set keyfp [open $html/Keywords/[indexfile] w]
@@ -656,7 +334,15 @@ proc make-man-pages {html args} {
foreach man $manual(keyword-$k) {
set name [lindex $man 0]
set file [lindex $man 1]
- lappend refs "<A HREF=\"../$file\">$name</A>"
+ if {[info exists manual(tooltip-$file)]} {
+ set tooltip $manual(tooltip-$file)
+ if {[string match {*[<>""]*} $tooltip]} {
+ manerror "bad tooltip for $file: \"$tooltip\""
+ }
+ lappend refs "<A HREF=\"../$file\" TITLE=\"$tooltip\">$name</A>"
+ } else {
+ lappend refs "<A HREF=\"../$file\">$name</A>"
+ }
}
puts $afp "[join $refs {, }]</DD>"
}
@@ -686,9 +372,9 @@ proc make-man-pages {html args} {
##
unset manual(section)
if {!$verbose} {
- puts stderr "Rescanning [llength $manual(all-pages)] pages to build cross links"
+ puts stderr "Rescanning [llength $manual(all-pages)] pages to build cross links and write out"
}
- foreach path $manual(all-pages) {
+ foreach path $manual(all-pages) wing_name $manual(all-page-domains) {
set manual(wing-file) [file dirname $path]
set manual(tail) [file tail $path]
set manual(name) [file root $manual(tail)]
@@ -712,7 +398,7 @@ proc make-man-pages {html args} {
}
set outfd [open $html/$manual(wing-file)/$manual(name).htm w]
puts $outfd [htmlhead "$manual($manual(wing-file)-$manual(name)-title)" \
- $manual(name) $manual(wing-file) "[indexfile]" \
+ $manual(name) $wing_name "[indexfile]" \
$overall_title "../[indexfile]"]
if {($ntext > 60) && ($ntoc > 32)} {
foreach item $toc {
@@ -748,9 +434,18 @@ proc make-man-pages {html args} {
##
## Helper for assembling the descriptions of base packages (i.e., Tcl and Tk).
##
-proc plus-base {var glob name dir desc} {
+proc plus-base {var root glob name dir desc} {
global tcltkdir
if {$var} {
+ if {[file exists $tcltkdir/$root/README]} {
+ set f [open $tcltkdir/$root/README]
+ set d [read $f]
+ close $f
+ if {[regexp {This is the \w+ (\S+) source distribution} $d -> version]} {
+ append name ", version $version"
+ }
+ }
+ set glob $root/$glob
return [list $tcltkdir/$glob $name $dir $desc]
}
}
@@ -765,17 +460,17 @@ proc plus-pkgs {type args} {
}
if {!$build_tcl} return
set result {}
- foreach {dir name} $args {
- set globpat $tcltkdir/$tcldir/pkgs/$dir*/doc/*.$type
- if {![llength [glob -nocomplain $globpat]]} {
+ set pkgsdir $tcltkdir/$tcldir/pkgs
+ foreach {dir name version} $args {
+ set globpat $pkgsdir/$dir/doc/*.$type
+ if {![llength [glob -type f -nocomplain $globpat]]} {
# Fallback for manpages generated using doctools
- set globpat $tcltkdir/$tcldir/pkgs/$dir*/doc/man/*.$type
- if {![llength [glob -nocomplain $globpat]]} {
+ set globpat $pkgsdir/$dir/doc/man/*.$type
+ if {![llength [glob -type f -nocomplain $globpat]]} {
continue
}
}
- regexp "pkgs/${dir}(.*)/doc$" [glob $tcltkdir/$tcldir/pkgs/$dir*/doc] \
- -> version
+ set dir [string trimright $dir "0123456789-."]
switch $type {
n {
set title "$name Package Commands"
@@ -787,7 +482,7 @@ proc plus-pkgs {type args} {
"The additional commands provided by the $name package."
}
3 {
- set title "$name Package Library"
+ set title "$name Package C API"
if {$version ne ""} {
append title ", version $version"
}
@@ -953,6 +648,44 @@ try {
append appdir "$tkdir"
}
+ apply {{} {
+ global packageBuildList tcltkdir tcldir build_tcl
+
+ # When building docs for Tcl, try to build docs for bundled packages too
+ set packageBuildList {}
+ if {$build_tcl} {
+ set pkgsDir [file join $tcltkdir $tcldir pkgs]
+ set subdirs [glob -nocomplain -types d -tails -directory $pkgsDir *]
+
+ foreach dir [lsort $subdirs] {
+ # Parse the subdir name into (name, version) as fallback...
+ set description [split $dir -]
+ if {2 != [llength $description]} {
+ regexp {([^0-9]*)(.*)} $dir -> n v
+ set description [list $n $v]
+ }
+
+ # ... but try to extract (name, version) from subdir contents
+ try {
+ set f [open [file join $pkgsDir $dir configure.in]]
+ foreach line [split [read $f] \n] {
+ if {2 == [scan $line \
+ { AC_INIT ( [%[^]]] , [%[^]]] ) } n v]} {
+ set description [list $n $v]
+ break
+ }
+ }
+ } finally {
+ catch {close $f; unset f}
+ }
+
+ if {[file exists [file join $pkgsDir $dir configure]]} {
+ # Looks like a package, record our best extraction attempt
+ lappend packageBuildList $dir {*}$description
+ }
+ }
+ }
+
# Get the list of packages to try, and what their human-readable names
# are. Note that the package directory list should be version-less.
try {
@@ -963,7 +696,8 @@ try {
foreach line [split [read $f] \n] {
if {[string trim $line] eq ""} continue
if {[string match #* $line]} continue
- lappend packageDirNameMap {*}$line
+ lassign $line dir name
+ lappend packageDirNameMap $dir $name
}
} finally {
close $f
@@ -977,29 +711,38 @@ try {
}
}
+ # Convert to human readable names, if applicable
+ for {set idx 0} {$idx < [llength $packageBuildList]} {incr idx 3} {
+ lassign [lrange $packageBuildList $idx $idx+2] d n v
+ if {[dict exists $packageDirNameMap $n]} {
+ lset packageBuildList $idx+1 [dict get $packageDirNameMap $n]
+ }
+ }
+ }}
+
#
# Invoke the scraper/converter engine.
#
make-man-pages $webdir \
[list $tcltkdir/{$appdir}/doc/*.1 "$tcltkdesc Applications" UserCmd \
"The interpreters which implement $cmdesc."] \
- [plus-base $build_tcl $tcldir/doc/*.n {Tcl Commands} TclCmd \
+ [plus-base $build_tcl $tcldir doc/*.n {Tcl Commands} TclCmd \
"The commands which the <B>tclsh</B> interpreter implements."] \
- [plus-base $build_tk $tkdir/doc/*.n {Tk Commands} TkCmd \
+ [plus-base $build_tk $tkdir doc/*.n {Tk Commands} TkCmd \
"The additional commands which the <B>wish</B> interpreter implements."] \
- {*}[plus-pkgs n {*}$packageDirNameMap] \
- [plus-base $build_tcl $tcldir/doc/*.3 {Tcl Library} TclLib \
+ {*}[plus-pkgs n {*}$packageBuildList] \
+ [plus-base $build_tcl $tcldir doc/*.3 {Tcl C API} TclLib \
"The C functions which a Tcl extended C program may use."] \
- [plus-base $build_tk $tkdir/doc/*.3 {Tk Library} TkLib \
+ [plus-base $build_tk $tkdir doc/*.3 {Tk C API} TkLib \
"The additional C functions which a Tk extended C program may use."] \
- {*}[plus-pkgs 3 {*}$packageDirNameMap]
+ {*}[plus-pkgs 3 {*}$packageBuildList]
} on error {msg opts} {
# On failure make sure we show what went wrong. We're not supposed
# to get here though; it represents a bug in the script.
puts $msg\n[dict get $opts -errorinfo]
exit 1
}
-
+
# Local-Variables:
# mode: tcl
# End:
diff --git a/tools/uniClass.tcl b/tools/uniClass.tcl
index 9a1bf13..9b4819d 100644
--- a/tools/uniClass.tcl
+++ b/tools/uniClass.tcl
@@ -13,22 +13,36 @@ exec tclsh "$0" ${1+"$@"}
#
proc emitRange {first last} {
- global ranges numranges chars numchars
+ global ranges numranges chars numchars extchars extranges
if {$first < ($last-1)} {
- append ranges [format "{0x%04x, 0x%04x}, " \
+ if {!$extranges && ($first) > 0xffff} {
+ 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 [format "{0x%x, 0x%x}, " \
$first $last]
if {[incr numranges] % 4 == 0} {
+ set ranges [string trimright $ranges]
append ranges "\n "
}
} else {
- append chars [format "0x%04x, " $first]
+ if {!$extchars && ($first) > 0xffff} {
+ 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 [format "0x%x, " $first]
incr numchars
if {$numchars % 9 == 0} {
+ set chars [string trimright $chars]
append chars "\n "
}
if {$first != $last} {
- append chars [format "0x%04x, " $last]
+ append chars [format "0x%x, " $last]
incr numchars
if {$numchars % 9 == 0} {
append chars "\n "
@@ -38,7 +52,7 @@ proc emitRange {first last} {
}
proc genTable {type} {
- global first last ranges numranges chars numchars
+ global first last ranges numranges chars numchars extchars extranges
set first -2
set last -2
@@ -46,13 +60,19 @@ proc genTable {type} {
set numranges 0
set chars " "
set numchars 0
+ set extchars 0
+ set extranges 0
- for {set i 0} {$i <= 0xFFFF} {incr i} {
+ for {set i 0} {$i <= 0x10ffff} {incr i} {
+ if {$i == 0xd800} {
+ # Skip surrogates
+ set i 0xdc00
+ }
if {[string is $type [format %c $i]]} {
if {$i == ($last + 1)} {
set last $i
} else {
- if {$first > 0} {
+ if {$first >= 0} {
emitRange $first $last
}
set first $i
@@ -63,7 +83,13 @@ proc genTable {type} {
emitRange $first $last
set ranges [string trimright $ranges "\t\n ,"]
+ if {$extranges} {
+ append ranges "\n#endif"
+ }
set chars [string trimright $chars "\t\n ,"]
+ if {$extchars} {
+ append chars "\n#endif"
+ }
if {$ranges ne ""} {
puts "static const crange ${type}RangeTable\[\] = {\n$ranges\n};\n"
puts "#define NUM_[string toupper $type]_RANGE (sizeof(${type}RangeTable)/sizeof(crange))\n"
@@ -87,6 +113,7 @@ puts "/*
foreach {type desc} {
alpha "alphabetic characters"
+ control "control characters"
digit "decimal digit characters"
punct "punctuation characters"
space "white space characters"
diff --git a/tools/uniParse.tcl b/tools/uniParse.tcl
index 99ecf40..e33b3c7 100644
--- a/tools/uniParse.tcl
+++ b/tools/uniParse.tcl
@@ -30,45 +30,38 @@ namespace eval uni {
Cc Cf Co Cs Pc Pd Ps Pe Pi Pf Po Sm Sc Sk So
}; # Ordered list of character categories, must
# match the enumeration in the header file.
-
- variable titleCount 0; # Count of the number of title case
- # characters. This value is used in the
- # regular expression code to allocate enough
- # space for the title case variants.
}
proc uni::getValue {items index} {
variable categories
- variable titleCount
# Extract character info
set category [lindex $items 2]
- if {[scan [lindex $items 12] %4x toupper] == 1} {
+ if {[scan [lindex $items 12] %x toupper] == 1} {
set toupper [expr {$index - $toupper}]
} else {
- set toupper {}
+ set toupper 0
}
- if {[scan [lindex $items 13] %4x tolower] == 1} {
+ if {[scan [lindex $items 13] %x tolower] == 1} {
set tolower [expr {$tolower - $index}]
} else {
- set tolower {}
+ set tolower 0
}
- if {[scan [lindex $items 14] %4x totitle] == 1} {
+ if {[scan [lindex $items 14] %x totitle] == 1} {
set totitle [expr {$index - $totitle}]
+ } elseif {$tolower} {
+ set totitle 0
} else {
- set totitle {}
+ set totitle $toupper
}
set categoryIndex [lsearch -exact $categories $category]
if {$categoryIndex < 0} {
- puts "Unexpected character category: $index($category)"
- set categoryIndex 0
- } elseif {$category eq "Lt"} {
- incr titleCount
+ error "Unexpected character category: $index($category)"
}
- return "$categoryIndex,$toupper,$tolower,$totitle"
+ return [list $categoryIndex $toupper $tolower $totitle]
}
proc uni::getGroup {value} {
@@ -85,13 +78,14 @@ proc uni::getGroup {value} {
proc uni::addPage {info} {
variable pMap
variable pages
+ variable shift
set pIndex [lsearch -exact $pages $info]
if {$pIndex == -1} {
set pIndex [llength $pages]
lappend pages $info
}
- lappend pMap $pIndex
+ lappend pMap [expr {$pIndex << $shift}]
return
}
@@ -100,26 +94,31 @@ proc uni::buildTables {data} {
variable pMap {}
variable pages {}
- variable groups {{0,,,}}
+ variable groups {{0 0 0 0}}
+ variable next 0
set info {} ;# temporary page info
set mask [expr {(1 << $shift) - 1}]
- set next 0
-
foreach line [split $data \n] {
if {$line eq ""} {
- set line "FFFF;;Cn;0;ON;;;;;N;;;;;\n"
+ if {!($next & $mask)} {
+ # next character is already on page boundary
+ continue
+ }
+ # fill remaining page
+ set line [format %X [expr {($next-1)|$mask}]]
+ append line ";;Cn;0;ON;;;;;N;;;;;\n"
}
set items [split $line \;]
scan [lindex $items 0] %x index
- if {$index > 0xFFFF} then {
+ if {$index > 0x2ffff} then {
# Ignore non-BMP characters, as long as Tcl doesn't support them
continue
}
- set index [format 0x%0.4x $index]
+ set index [format %d $index]
set gIndex [getGroup [getValue $items $index]]
@@ -142,15 +141,11 @@ proc uni::buildTables {data} {
# Enter all assigned characters up to the current character
for {set i $next} {$i <= $index} {incr i} {
- # Split character index into offset and page number
- set offset [expr {$i & $mask}]
- set page [expr {($i >> $shift)}]
-
# Add the group index to the info for the current page
lappend info $gIndex
# If this is the last entry in the page, add the page
- if {$offset == $mask} {
+ if {($i & $mask) == $mask} {
addPage $info
set info {}
}
@@ -166,7 +161,7 @@ proc uni::main {} {
variable pages
variable groups
variable shift
- variable titleCount
+ variable next
if {$argc != 2} {
puts stderr "\nusage: $argv0 <datafile> <outdir>\n"
@@ -178,9 +173,8 @@ proc uni::main {} {
buildTables $data
puts "X = [llength $pMap] Y= [llength $pages] A= [llength $groups]"
- set size [expr {[llength $pMap] + [llength $pages]*(1<<$shift)}]
- puts "shift = 6, space = $size"
- puts "title case count = $titleCount"
+ set size [expr {[llength $pMap]*2 + ([llength $pages]<<$shift)}]
+ puts "shift = $shift, space = $size"
set f [open [file join [lindex $argv 1] tclUniData.c] w]
fconfigure $f -translation lf
@@ -213,6 +207,14 @@ static const unsigned short pageMap\[\] = {"
set line " "
set last [expr {[llength $pMap] - 1}]
for {set i 0} {$i <= $last} {incr i} {
+ if {$i == [expr {0x10000 >> $shift}]} {
+ set line [string trimright $line " \t,"]
+ puts $f $line
+ set lastpage [expr {[lindex $line end] >> $shift}]
+ puts stdout "lastpage: $lastpage"
+ puts $f "#if TCL_UTF_MAX > 3"
+ set line " ,"
+ }
append line [lindex $pMap $i]
if {$i != $last} {
append line ", "
@@ -223,6 +225,7 @@ static const unsigned short pageMap\[\] = {"
}
}
puts $f $line
+ puts $f "#endif /* TCL_UTF_MAX > 3 */"
puts $f "};
/*
@@ -237,6 +240,11 @@ static const unsigned char groupMap\[\] = {"
for {set i 0} {$i <= $lasti} {incr i} {
set page [lindex $pages $i]
set lastj [expr {[llength $page] - 1}]
+ if {$i == ($lastpage + 1)} {
+ puts $f [string trimright $line " \t,"]
+ puts $f "#if TCL_UTF_MAX > 3"
+ set line " ,"
+ }
for {set j 0} {$j <= $lastj} {incr j} {
append line [lindex $page $j]
if {$j != $lastj || $i != $lasti} {
@@ -249,6 +257,7 @@ static const unsigned char groupMap\[\] = {"
}
}
puts $f $line
+ puts $f "#endif /* TCL_UTF_MAX > 3 */"
puts $f "};
/*
@@ -264,9 +273,7 @@ static const unsigned char groupMap\[\] = {"
* 101 = sub delta for upper, sub 1 for title
* 110 = sub delta for upper, add delta for lower
*
- * Bits 8-21 Reserved for future use.
- *
- * Bits 22-31 Case delta: delta for case conversions. This should be the
+ * Bits 8-31 Case delta: delta for case conversions. This should be the
* highest field so we can easily sign extend.
*/
@@ -274,29 +281,41 @@ static const int groups\[\] = {"
set line " "
set last [expr {[llength $groups] - 1}]
for {set i 0} {$i <= $last} {incr i} {
- foreach {type toupper tolower totitle} [split [lindex $groups $i] ,] {}
+ foreach {type toupper tolower totitle} [lindex $groups $i] {}
# Compute the case conversion type and delta
- if {$totitle ne ""} {
+ if {$totitle} {
if {$totitle == $toupper} {
# subtract delta for title or upper
set case 4
set delta $toupper
- } elseif {$toupper ne ""} {
+ if {$tolower} {
+ error "New case conversion type needed: $toupper $tolower $totitle"
+ }
+ } elseif {$toupper} {
# subtract delta for upper, subtract 1 for title
set case 5
set delta $toupper
+ if {($totitle != 1) || $tolower} {
+ error "New case conversion type needed: $toupper $tolower $totitle"
+ }
} else {
# add delta for lower, add 1 for title
set case 3
set delta $tolower
+ if {$totitle != -1} {
+ error "New case conversion type needed: $toupper $tolower $totitle"
+ }
}
- } elseif {$toupper ne ""} {
+ } elseif {$toupper} {
# subtract delta for upper, add delta for lower
set case 6
set delta $toupper
- } elseif {$tolower ne ""} {
+ if {$tolower != $toupper} {
+ error "New case conversion type needed: $toupper $tolower $totitle"
+ }
+ } elseif {$tolower} {
# add delta for lower
set case 2
set delta $tolower
@@ -306,9 +325,7 @@ static const int groups\[\] = {"
set delta 0
}
- set val [expr {($delta << 22) | ($case << 5) | $type}]
-
- append line [format "%d" $val]
+ append line [expr {($delta << 8) | ($case << 5) | $type}]
if {$i != $last} {
append line ", "
}
@@ -318,15 +335,19 @@ static const int groups\[\] = {"
}
}
puts $f $line
- puts $f "};
+ puts -nonewline $f "};
+
+#if TCL_UTF_MAX > 3
+# define UNICODE_OUT_OF_RANGE(ch) (((ch) & 0x1fffff) >= [format 0x%x $next])
+#else
+# define UNICODE_OUT_OF_RANGE(ch) (((ch) & 0x1f0000) != 0)
+#endif
/*
* The following constants are used to determine the category of a
* Unicode character.
*/
-#define UNICODE_CATEGORY_MASK 0X1F
-
enum {
UNASSIGNED,
UPPERCASE_LETTER,
@@ -366,16 +387,16 @@ enum {
* to do sign extension on right shifts.
*/
-#define GetCaseType(info) (((info) & 0xE0) >> 5)
-#define GetCategory(info) ((info) & 0x1F)
-#define GetDelta(info) (((info) > 0) ? ((info) >> 22) : (~(~((info)) >> 22)))
+#define GetCaseType(info) (((info) & 0xe0) >> 5)
+#define GetCategory(ch) (GetUniCharInfo(ch) & 0x1f)
+#define GetDelta(info) ((info) >> 8)
/*
* This macro extracts the information about a character from the
* Unicode character tables.
*/
-#define GetUniCharInfo(ch) (groups\[groupMap\[(pageMap\[(((int)(ch)) & 0xffff) >> OFFSET_BITS\] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1))\]\])
+#define GetUniCharInfo(ch) (groups\[groupMap\[pageMap\[((ch) & 0xffff) >> OFFSET_BITS\] | ((ch) & ((1 << OFFSET_BITS)-1))\]\])
"
close $f
diff --git a/unix/Makefile.in b/unix/Makefile.in
index b3507ba..69dd14f 100644
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -47,6 +47,7 @@ BIN_INSTALL_DIR = $(INSTALL_ROOT)$(bindir)
# Directory in which to install libtcl.so or libtcl.a:
LIB_INSTALL_DIR = $(INSTALL_ROOT)$(libdir)
+DLL_INSTALL_DIR = @DLL_INSTALL_DIR@
# Path name to use when installing library scripts.
SCRIPT_INSTALL_DIR = $(INSTALL_ROOT)$(TCL_LIBRARY)
@@ -237,7 +238,7 @@ DLTEST_DIR = @TCL_SRC_DIR@/unix/dltest
# Must be absolute to so the corresponding tcltest's tcl_library is absolute.
TCL_BUILDTIME_LIBRARY = @TCL_SRC_DIR@/library
-ZLIB_DIR = @ZLIB_DIR@
+ZLIB_DIR = ${COMPAT_DIR}/zlib
ZLIB_INCLUDE = @ZLIB_INCLUDE@
CC = @CC@
@@ -290,24 +291,24 @@ XTTEST_OBJS = xtTestInit.o tclTest.o tclTestObj.o tclTestProcBodyObj.o \
tclThreadTest.o tclUnixTest.o tclXtNotify.o tclXtTest.o
GENERIC_OBJS = regcomp.o regexec.o regfree.o regerror.o tclAlloc.o \
- tclAsync.o tclBasic.o tclBinary.o tclCkalloc.o tclClock.o \
- tclCmdAH.o tclCmdIL.o tclCmdMZ.o tclCompCmds.o tclCompCmdsSZ.o \
- tclCompExpr.o tclCompile.o tclConfig.o tclDate.o tclDictObj.o \
+ tclAssembly.o tclAsync.o tclBasic.o tclBinary.o tclCkalloc.o \
+ tclClock.o tclCmdAH.o tclCmdIL.o tclCmdMZ.o \
+ tclCompCmds.o tclCompCmdsGR.o tclCompCmdsSZ.o tclCompExpr.o \
+ tclCompile.o tclConfig.o tclDate.o tclDictObj.o \
tclEncoding.o tclEnsemble.o \
tclEnv.o tclEvent.o tclExecute.o tclFCmd.o tclFileName.o tclGet.o \
tclHash.o tclHistory.o tclIndexObj.o tclInterp.o tclIO.o tclIOCmd.o \
tclIORChan.o tclIORTrans.o tclIOGT.o tclIOSock.o tclIOUtil.o \
tclLink.o tclListObj.o \
tclLiteral.o tclLoad.o tclMain.o tclNamesp.o tclNotify.o \
- tclObj.o tclPanic.o tclParse.o tclPathObj.o tclPipe.o \
+ tclObj.o tclOptimize.o tclPanic.o tclParse.o tclPathObj.o tclPipe.o \
tclPkg.o tclPkgConfig.o tclPosixStr.o \
tclPreserve.o tclProc.o tclRegexp.o \
tclResolve.o tclResult.o tclScan.o tclStringObj.o \
tclStrToD.o tclThread.o \
tclThreadAlloc.o tclThreadJoin.o tclThreadStorage.o tclStubInit.o \
tclTimer.o tclTrace.o tclUtf.o tclUtil.o tclVar.o tclZlib.o \
- tclTomMathInterface.o \
- tclAssembly.o
+ tclTomMathInterface.o
OO_OBJS = tclOO.o tclOOBasic.o tclOOCall.o tclOODefineCmds.o tclOOInfo.o \
tclOOMethod.o tclOOStubInit.o
@@ -334,7 +335,10 @@ TOMMATH_OBJS = bncore.o bn_reverse.o bn_fast_s_mp_mul_digs.o \
bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_zero.o bn_s_mp_add.o \
bn_s_mp_mul_digs.o bn_s_mp_sqr.o bn_s_mp_sub.o
-STUB_LIB_OBJS = tclStubLib.o tclTomMathStubLib.o tclOOStubLib.o ${COMPAT_OBJS}
+STUB_LIB_OBJS = tclStubLib.o \
+ tclTomMathStubLib.o \
+ tclOOStubLib.o \
+ ${COMPAT_OBJS}
UNIX_OBJS = tclUnixChan.o tclUnixEvent.o tclUnixFCmd.o \
tclUnixFile.o tclUnixPipe.o tclUnixSock.o \
@@ -345,6 +349,8 @@ NOTIFY_OBJS = tclUnixNotfy.o
MAC_OSX_OBJS = tclMacOSXBundle.o tclMacOSXFCmd.o tclMacOSXNotify.o
+CYGWIN_OBJS = tclWinError.o
+
DTRACE_OBJ = tclDTrace.o
ZLIB_OBJS = Zadler32.o Zcompress.o Zcrc32.o Zdeflate.o Zinfback.o \
@@ -394,6 +400,7 @@ GENERIC_SRCS = \
$(GENERIC_DIR)/tclCmdIL.c \
$(GENERIC_DIR)/tclCmdMZ.c \
$(GENERIC_DIR)/tclCompCmds.c \
+ $(GENERIC_DIR)/tclCompCmdsGR.c \
$(GENERIC_DIR)/tclCompCmdsSZ.c \
$(GENERIC_DIR)/tclCompExpr.c \
$(GENERIC_DIR)/tclCompile.c \
@@ -427,6 +434,7 @@ GENERIC_SRCS = \
$(GENERIC_DIR)/tclNamesp.c \
$(GENERIC_DIR)/tclNotify.c \
$(GENERIC_DIR)/tclObj.c \
+ $(GENERIC_DIR)/tclOptimize.c \
$(GENERIC_DIR)/tclParse.c \
$(GENERIC_DIR)/tclPathObj.c \
$(GENERIC_DIR)/tclPipe.c \
@@ -468,7 +476,7 @@ OO_SRCS = \
STUB_SRCS = \
$(GENERIC_DIR)/tclStubLib.c \
$(GENERIC_DIR)/tclTomMathStubLib.c \
- $(GENERIC_DIR)/tclOOStubLib.o
+ $(GENERIC_DIR)/tclOOStubLib.c
TOMMATH_SRCS = \
$(TOMMATH_DIR)/bncore.c \
@@ -572,6 +580,9 @@ MAC_OSX_SRCS = \
$(MAC_OSX_DIR)/tclMacOSXFCmd.c \
$(MAC_OSX_DIR)/tclMacOSXNotify.c
+CYGWIN_SRCS = \
+ $(TOP_DIR)/win/tclWinError.c
+
DTRACE_HDR = tclDTrace.h
DTRACE_SRC = $(GENERIC_DIR)/tclDTrace.d
@@ -602,7 +613,7 @@ SRCS = $(GENERIC_SRCS) $(TOMMATH_SRCS) $(UNIX_SRCS) $(NOTIFY_SRCS) \
all: binaries libraries doc packages
-binaries: ${LIB_FILE} $(STUB_LIB_FILE) ${TCL_EXE}
+binaries: ${LIB_FILE} ${TCL_EXE}
libraries:
@@ -610,11 +621,14 @@ doc:
# The following target is configured by autoconf to generate either a shared
# library or non-shared library for Tcl.
-${LIB_FILE}: ${OBJS} ${STUB_LIB_FILE}
+${LIB_FILE}: ${STUB_LIB_FILE} ${OBJS}
rm -f $@
@MAKE_LIB@
${STUB_LIB_FILE}: ${STUB_LIB_OBJS}
+ @if test "x${LIB_FILE}" = "xlibtcl${MAJOR_VERSION}.${MINOR_VERSION}.dll"; then \
+ (cd ${TOP_DIR}/win; ${MAKE} tcldde14.dll tclreg13.dll); \
+ fi
rm -f $@
@MAKE_STUB_LIB@
@@ -628,9 +642,9 @@ tclLibObjs:
# This targets actually build the objects needed for the lib in the above case
objs: ${OBJS}
-${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE}
+${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE}
${CC} ${CFLAGS} ${LDFLAGS} ${TCLSH_OBJS} \
- @TCL_BUILD_LIB_SPEC@ ${LIBS} @EXTRA_TCLSH_LIBS@ \
+ @TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \
${CC_SEARCH_FLAGS} -o ${TCL_EXE}
# Must be empty so it doesn't conflict with rule for ${TCL_EXE} above
@@ -738,7 +752,7 @@ gdb: ${TCL_EXE}
$(SHELL_ENV) $(GDB) ./${TCL_EXE}
valgrind: ${TCL_EXE} ${TCLTEST_EXE}
- $(SHELL_ENV) $(VALGRIND) $(VALGRINDARGS) ./${TCLTEST_EXE} $(TOP_DIR)/tests/all.tcl -singleproc 1 $(TESTFLAGS)
+ $(SHELL_ENV) $(VALGRIND) $(VALGRINDARGS) ./${TCLTEST_EXE} $(TOP_DIR)/tests/all.tcl -singleproc 1 -constraints valgrind $(TESTFLAGS)
valgrindshell: ${TCL_EXE}
$(SHELL_ENV) $(VALGRIND) $(VALGRINDARGS) ./${TCL_EXE} $(SCRIPT)
@@ -782,16 +796,16 @@ install-binaries: binaries
else true; \
fi; \
done;
- @echo "Installing $(LIB_FILE) to @DLL_INSTALL_DIR@/"
+ @echo "Installing $(LIB_FILE) to $(DLL_INSTALL_DIR)/"
@@INSTALL_LIB@
- @chmod 555 "@DLL_INSTALL_DIR@"/$(LIB_FILE)
+ @chmod 555 "$(DLL_INSTALL_DIR)/$(LIB_FILE)"
@echo "Installing ${TCL_EXE} as $(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}"
- @$(INSTALL_PROGRAM) ${TCL_EXE} "$(BIN_INSTALL_DIR)"/tclsh$(VERSION)${EXE_SUFFIX}
+ @$(INSTALL_PROGRAM) ${TCL_EXE} "$(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}"
@echo "Installing tclConfig.sh to $(CONFIG_INSTALL_DIR)/"
- @$(INSTALL_DATA) tclConfig.sh "$(CONFIG_INSTALL_DIR)"/tclConfig.sh
+ @$(INSTALL_DATA) tclConfig.sh "$(CONFIG_INSTALL_DIR)/tclConfig.sh"
@echo "Installing tclooConfig.sh to $(CONFIG_INSTALL_DIR)/"
@$(INSTALL_DATA) $(UNIX_DIR)/tclooConfig.sh \
- "$(CONFIG_INSTALL_DIR)"/tclooConfig.sh
+ "$(CONFIG_INSTALL_DIR)/tclooConfig.sh"
@if test "$(STUB_LIB_FILE)" != "" ; then \
echo "Installing $(STUB_LIB_FILE) to $(LIB_INSTALL_DIR)/"; \
@INSTALL_STUB_LIB@ ; \
@@ -810,7 +824,7 @@ install-libraries: libraries
else true; \
fi; \
done;
- @for i in opt0.4 http1.0 encoding ../tcl8 ../tcl8/8.3 ../tcl8/8.4 ../tcl8/8.4/platform ../tcl8/8.5 ../tcl8/8.6; \
+ @for i in opt0.4 http1.0 encoding ../tcl8 ../tcl8/8.4 ../tcl8/8.4/platform ../tcl8/8.5 ../tcl8/8.6; \
do \
if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \
echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \
@@ -829,24 +843,24 @@ install-libraries: libraries
do \
$(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/http1.0; \
done;
- @echo "Installing package http 2.8.2 as a Tcl Module";
- @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.8.2.tm;
+ @echo "Installing package http 2.8.8 as a Tcl Module";
+ @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.8.8.tm;
@echo "Installing package opt0.4 files to $(SCRIPT_INSTALL_DIR)/opt0.4/";
@for i in $(TOP_DIR)/library/opt/*.tcl ; \
do \
$(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/opt0.4; \
done;
- @echo "Installing package msgcat 1.4.4 as a Tcl Module";
- @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.4.4.tm;
- @echo "Installing package tcltest 2.3.3 as a Tcl Module";
- @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.3.3.tm;
+ @echo "Installing package msgcat 1.5.2 as a Tcl Module";
+ @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.5.2.tm;
+ @echo "Installing package tcltest 2.3.7 as a Tcl Module";
+ @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.3.7.tm;
- @echo "Installing package platform 1.0.10 as a Tcl Module";
- @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.10.tm;
+ @echo "Installing package platform 1.0.12 as a Tcl Module";
+ @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.12.tm;
@echo "Installing package platform::shell 1.1.4 as a Tcl Module";
@$(INSTALL_DATA) $(TOP_DIR)/library/platform/shell.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform/shell-1.1.4.tm;
- @echo "Installing library encoding files to $(SCRIPT_INSTALL_DIR)/encoding/";
+ @echo "Installing encoding files to $(SCRIPT_INSTALL_DIR)/encoding/";
@for i in $(TOP_DIR)/library/encoding/*.enc ; do \
$(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/encoding; \
done;
@@ -856,10 +870,39 @@ install-libraries: libraries
"$(SCRIPT_INSTALL_DIR)"/tm.tcl; \
fi
-install-tzdata: ${NATIVE_TCLSH}
- @echo "Installing time zone data"
- @${NATIVE_TCLSH} $(TOOL_DIR)/installData.tcl \
- $(TOP_DIR)/library/tzdata "$(SCRIPT_INSTALL_DIR)"/tzdata
+install-tzdata:
+ @for i in tzdata; \
+ do \
+ if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \
+ echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \
+ $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/$$i; \
+ else true; \
+ fi; \
+ done;
+ @echo "Installing time zone files to $(SCRIPT_INSTALL_DIR)/tzdata/"
+ @for i in $(TOP_DIR)/library/tzdata/* ; do \
+ if [ -d $$i ] ; then \
+ ii=`basename $$i`; \
+ if [ ! -d "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii ] ; then \
+ $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii; \
+ fi; \
+ for j in $$i/* ; do \
+ if [ -d $$j ] ; then \
+ jj=`basename $$j`; \
+ if [ ! -d "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii/$$jj ] ; then \
+ $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii/$$jj; \
+ fi; \
+ for k in $$j/* ; do \
+ $(INSTALL_DATA) $$k "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii/$$jj; \
+ done; \
+ else \
+ $(INSTALL_DATA) $$j "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii; \
+ fi; \
+ done; \
+ else \
+ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/tzdata; \
+ fi; \
+ done;
install-msgs:
@for i in msgs; \
@@ -884,17 +927,17 @@ install-doc: doc
else true; \
fi; \
done;
- @echo "Installing and cross-linking top-level (.1) docs";
+ @echo "Installing and cross-linking top-level (.1) docs to $(MAN1_INSTALL_DIR)/";
@for i in $(TOP_DIR)/doc/*.1; do \
$(SHELL) $(UNIX_DIR)/installManPage $(MAN_FLAGS) $$i "$(MAN1_INSTALL_DIR)"; \
done
- @echo "Installing and cross-linking C API (.3) docs";
+ @echo "Installing and cross-linking C API (.3) docs to $(MAN3_INSTALL_DIR)/";
@for i in $(TOP_DIR)/doc/*.3; do \
$(SHELL) $(UNIX_DIR)/installManPage $(MAN_FLAGS) $$i "$(MAN3_INSTALL_DIR)"; \
done
- @echo "Installing and cross-linking command (.n) docs";
+ @echo "Installing and cross-linking command (.n) docs to $(MANN_INSTALL_DIR)/";
@for i in $(TOP_DIR)/doc/*.n; do \
$(SHELL) $(UNIX_DIR)/installManPage $(MAN_FLAGS) $$i "$(MANN_INSTALL_DIR)"; \
done
@@ -990,7 +1033,9 @@ COMPILEHDR=$(GENERIC_DIR)/tclCompile.h
FSHDR=$(GENERIC_DIR)/tclFileSystem.h
IOHDR=$(GENERIC_DIR)/tclIO.h
MATHHDRS=$(GENERIC_DIR)/tommath.h $(GENERIC_DIR)/tclTomMath.h
+PARSEHDR=$(GENERIC_DIR)/tclParse.h
NREHDR=$(GENERIC_DIR)/tclInt.h
+TRIMHDR=$(GENERIC_DIR)/tclStringTrim.h
regcomp.o: $(REGHDRS) $(GENERIC_DIR)/regcomp.c $(GENERIC_DIR)/regc_lex.c \
$(GENERIC_DIR)/regc_color.c $(GENERIC_DIR)/regc_locale.c \
@@ -1036,7 +1081,7 @@ tclCmdAH.o: $(GENERIC_DIR)/tclCmdAH.c
tclCmdIL.o: $(GENERIC_DIR)/tclCmdIL.c $(TCLREHDRS)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCmdIL.c
-tclCmdMZ.o: $(GENERIC_DIR)/tclCmdMZ.c $(TCLREHDRS)
+tclCmdMZ.o: $(GENERIC_DIR)/tclCmdMZ.c $(TCLREHDRS) $(TRIMHDR)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCmdMZ.c
tclDate.o: $(GENERIC_DIR)/tclDate.c
@@ -1045,7 +1090,10 @@ tclDate.o: $(GENERIC_DIR)/tclDate.c
tclCompCmds.o: $(GENERIC_DIR)/tclCompCmds.c $(COMPILEHDR)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompCmds.c
-tclCompCmdsSZ.o: $(GENERIC_DIR)/tclCompCmdsSZ.c $(COMPILEHDR)
+tclCompCmdsGR.o: $(GENERIC_DIR)/tclCompCmdsGR.c $(COMPILEHDR)
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompCmdsGR.c
+
+tclCompCmdsSZ.o: $(GENERIC_DIR)/tclCompCmdsSZ.c $(COMPILEHDR) $(TRIMHDR)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompCmdsSZ.c
tclCompExpr.o: $(GENERIC_DIR)/tclCompExpr.c $(COMPILEHDR)
@@ -1129,6 +1177,9 @@ tclLiteral.o: $(GENERIC_DIR)/tclLiteral.c $(COMPILEHDR)
tclObj.o: $(GENERIC_DIR)/tclObj.c $(COMPILEHDR) $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclObj.c
+tclOptimize.o: $(GENERIC_DIR)/tclOptimize.c $(COMPILEHDR)
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclOptimize.c
+
tclLoad.o: $(GENERIC_DIR)/tclLoad.c
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclLoad.c
@@ -1145,6 +1196,7 @@ tclLoadDld.o: $(UNIX_DIR)/tclLoadDld.c
$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDld.c
tclLoadDyld.o: $(UNIX_DIR)/tclLoadDyld.c
+ @echo Warnings are expected from compiling tclLoadDyld.c: deprecated API use
$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDyld.c
tclLoadNone.o: $(GENERIC_DIR)/tclLoadNone.c
@@ -1186,7 +1238,7 @@ tclOOMethod.o: $(GENERIC_DIR)/tclOOMethod.c
tclOOStubInit.o: $(GENERIC_DIR)/tclOOStubInit.c
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclOOStubInit.c
-tclParse.o: $(GENERIC_DIR)/tclParse.c
+tclParse.o: $(GENERIC_DIR)/tclParse.c $(PARSEHDR)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclParse.c
tclPanic.o: $(GENERIC_DIR)/tclPanic.c
@@ -1210,7 +1262,7 @@ tclPkg.o: $(GENERIC_DIR)/tclPkg.c
# prefix/exec_prefix but all the different paths individually.
tclPkgConfig.o: $(GENERIC_DIR)/tclPkgConfig.c
- $(CC) -c $(CC_SWITCHES) \
+ $(CC) -c $(CC_SWITCHES) \
-DCFG_INSTALL_LIBDIR="\"$(LIB_INSTALL_DIR)\"" \
-DCFG_INSTALL_BINDIR="\"$(BIN_INSTALL_DIR)\"" \
-DCFG_INSTALL_SCRDIR="\"$(SCRIPT_INSTALL_DIR)\"" \
@@ -1258,7 +1310,7 @@ tclStubInit.o: $(GENERIC_DIR)/tclStubInit.c
tclTrace.o: $(GENERIC_DIR)/tclTrace.c
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTrace.c
-tclUtil.o: $(GENERIC_DIR)/tclUtil.c
+tclUtil.o: $(GENERIC_DIR)/tclUtil.c $(PARSEHDR) $(TRIMHDR)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclUtil.c
tclUtf.o: $(GENERIC_DIR)/tclUtf.c $(GENERIC_DIR)/tclUniData.c
@@ -1268,7 +1320,7 @@ tclVar.o: $(GENERIC_DIR)/tclVar.c
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclVar.c
tclZlib.o: $(GENERIC_DIR)/tclZlib.c
- $(CC) -c $(ZLIB_INCLUDE) $(CC_SWITCHES) $(GENERIC_DIR)/tclZlib.c
+ $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) $(GENERIC_DIR)/tclZlib.c
tclTest.o: $(GENERIC_DIR)/tclTest.c $(IOHDR) $(TCLREHDRS)
$(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tclTest.c
@@ -1540,6 +1592,10 @@ tclMacOSXFCmd.o: $(MAC_OSX_DIR)/tclMacOSXFCmd.c
tclMacOSXNotify.o: $(MAC_OSX_DIR)/tclMacOSXNotify.c
$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tclMacOSXNotify.c
+# The following is a CYGWIN only source:
+tclWinError.o: $(TOP_DIR)/win/tclWinError.c
+ $(CC) -c $(CC_SWITCHES) $(TOP_DIR)/win/tclWinError.c
+
# DTrace support
$(TCL_OBJS) $(STUB_LIB_OBJS) $(TCLSH_OBJS) $(TCLTEST_OBJS) $(XTTEST_OBJS): @DTRACE_HDR@
@@ -1556,7 +1612,7 @@ $(DTRACE_OBJ): $(DTRACE_SRC) $(TCL_OBJS)
# notifier can modify them to suit their own installation.
#--------------------------------------------------------------------------
-xttest: ${XTTEST_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${BUILD_DLTEST}
+xttest: ${XTTEST_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${BUILD_DLTEST}
${CC} ${CFLAGS} ${LDFLAGS} ${XTTEST_OBJS} \
@TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \
${CC_SEARCH_FLAGS} -L/usr/openwin/lib -lXt -o xttest
@@ -1639,7 +1695,7 @@ Zzutil.o: $(ZLIB_DIR)/zutil.c
#--------------------------------------------------------------------------
tclStubLib.o: $(GENERIC_DIR)/tclStubLib.c
- $(CC) -c $(STUB_CC_SWITCHES) $(GENERIC_DIR)/tclStubLib.c
+ $(CC) -c $(STUB_CC_SWITCHES) -DSTATIC_BUILD $(GENERIC_DIR)/tclStubLib.c
tclTomMathStubLib.o: $(GENERIC_DIR)/tclTomMathStubLib.c
$(CC) -c $(STUB_CC_SWITCHES) $(GENERIC_DIR)/tclTomMathStubLib.c
@@ -1686,7 +1742,7 @@ packages: configure-packages ${STUB_LIB_FILE}
pkg=`basename $$i`; \
if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \
echo "Building package '$$pkg'"; \
- ( cd $(PKG_DIR)/$$pkg; $(MAKE) --no-print-directory; ) || exit $$?; \
+ ( cd $(PKG_DIR)/$$pkg; $(MAKE); ) || exit $$?; \
fi; \
fi; \
done
@@ -1697,21 +1753,19 @@ install-packages: packages
pkg=`basename $$i`; \
if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \
echo "Installing package '$$pkg'"; \
- ( cd $(PKG_DIR)/$$pkg; $(MAKE) --no-print-directory install \
+ ( cd $(PKG_DIR)/$$pkg; $(MAKE) install \
"DESTDIR=$(INSTALL_ROOT)"; ) || exit $$?; \
fi; \
fi; \
done
-test-packages: tcltest packages
+test-packages: ${TCLTEST_EXE} packages
@for i in $(PKGS_DIR)/*; do \
if [ -d $$i ]; then \
pkg=`basename $$i`; \
if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \
- echo ""; \
- echo ""; \
echo "Testing package '$$pkg'"; \
- ( cd $(PKG_DIR)/$$pkg; $(MAKE) --no-print-directory \
+ ( cd $(PKG_DIR)/$$pkg; $(MAKE) \
"@LD_LIBRARY_PATH_VAR@=../..:$${@LD_LIBRARY_PATH_VAR@}" \
"TCL_LIBRARY=${TCL_BUILDTIME_LIBRARY}" \
"TCLLIBPATH=../../pkgs" test \
@@ -1725,7 +1779,7 @@ clean-packages:
if [ -d $$i ]; then \
pkg=`basename $$i`; \
if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \
- ( cd $(PKG_DIR)/$$pkg; $(MAKE) --no-print-directory clean; ) \
+ ( cd $(PKG_DIR)/$$pkg; $(MAKE) clean; ) \
fi; \
fi; \
done
@@ -1735,7 +1789,7 @@ distclean-packages:
if [ -d $$i ]; then \
pkg=`basename $$i`; \
if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \
- ( cd $(PKG_DIR)/$$pkg; $(MAKE) --no-print-directory distclean; ) \
+ ( cd $(PKG_DIR)/$$pkg; $(MAKE) distclean; ) \
fi; \
rm -rf $(PKG_DIR)/$$pkg; \
fi; \
@@ -1749,7 +1803,7 @@ dist-packages: configure-packages
if [ -d $$i ]; then \
pkg=`basename $$i`; \
if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \
- ( cd $(PKG_DIR)/$$pkg; $(MAKE) --no-print-directory dist \
+ ( cd $(PKG_DIR)/$$pkg; $(MAKE) dist \
"DIST_ROOT=$(DISTROOT)/pkgs"; ) || exit $$?; \
fi; \
fi; \
@@ -1900,6 +1954,7 @@ $(MAC_OSX_DIR)/configure: $(MAC_OSX_DIR)/configure.ac $(UNIX_DIR)/configure
$(UNIX_DIR)/tclConfig.h.in: $(MAC_OSX_DIR)/configure
cd $(MAC_OSX_DIR); autoheader; touch $@
+EOLFIX=$(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl
dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(MAC_OSX_DIR)/configure genstubs dist-packages ${NATIVE_TCLSH}
rm -rf $(DISTDIR)
mkdir -p $(DISTDIR)/unix
@@ -1915,8 +1970,7 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M
$(UNIX_DIR)/tcl.pc.in $(DISTDIR)/unix
chmod 775 $(DISTDIR)/unix/configure $(DISTDIR)/unix/configure.in
chmod 775 $(DISTDIR)/unix/ldAix
- chmod +x $(DISTDIR)/unix/install-sh
- mkdir $(DISTDIR)/generic
+ @mkdir $(DISTDIR)/generic
cp -p $(GENERIC_DIR)/*.[cdh] $(DISTDIR)/generic
cp -p $(GENERIC_DIR)/*.decls $(DISTDIR)/generic
cp -p $(GENERIC_DIR)/README $(DISTDIR)/generic
@@ -1924,7 +1978,7 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M
cp -p $(TOP_DIR)/changes $(TOP_DIR)/ChangeLog $(TOP_DIR)/README* \
$(TOP_DIR)/ChangeLog.[12]??? $(TOP_DIR)/license.terms \
$(DISTDIR)
- mkdir $(DISTDIR)/library
+ @mkdir $(DISTDIR)/library
cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/library/*.tcl \
$(TOP_DIR)/library/tclIndex $(DISTDIR)/library
for i in http1.0 http opt msgcat reg dde tcltest platform; \
@@ -1932,31 +1986,32 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M
mkdir $(DISTDIR)/library/$$i ;\
cp -p $(TOP_DIR)/library/$$i/*.tcl $(DISTDIR)/library/$$i; \
done;
- mkdir $(DISTDIR)/library/encoding
+ @mkdir $(DISTDIR)/library/encoding
cp -p $(TOP_DIR)/library/encoding/*.enc $(DISTDIR)/library/encoding
- mkdir $(DISTDIR)/library/msgs
+ @mkdir $(DISTDIR)/library/msgs
cp -p $(TOP_DIR)/library/msgs/*.msg $(DISTDIR)/library/msgs
- ( cd $(TOP_DIR); \
+ @echo cp -r $(TOP_DIR)/library/tzdata $(DISTDIR)/library/tzdata
+ @( cd $(TOP_DIR); \
find library/tzdata -name CVS -prune -o -type f -print ) \
| ( cd $(TOP_DIR) ; xargs tar cf - ) \
| ( cd $(DISTDIR) ; tar xfp - )
- mkdir $(DISTDIR)/doc
+ @mkdir $(DISTDIR)/doc
cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/doc/*.[13n] \
$(TOP_DIR)/doc/man.macros $(DISTDIR)/doc
- mkdir $(DISTDIR)/compat
+ @mkdir $(DISTDIR)/compat
cp -p $(TOP_DIR)/license.terms $(COMPAT_DIR)/*.[ch] \
$(COMPAT_DIR)/README $(DISTDIR)/compat
- mkdir $(DISTDIR)/compat/zlib
+ @mkdir $(DISTDIR)/compat/zlib
( cd $(COMPAT_DIR)/zlib; \
find . -name CVS -prune -o -type f -print ) \
| ( cd $(COMPAT_DIR)/zlib ; xargs tar cf - ) \
| ( cd $(DISTDIR)/compat/zlib ; tar xfp - )
- mkdir $(DISTDIR)/tests
+ @mkdir $(DISTDIR)/tests
cp -p $(TOP_DIR)/license.terms $(DISTDIR)/tests
cp -p $(TOP_DIR)/tests/*.test $(TOP_DIR)/tests/README \
$(TOP_DIR)/tests/httpd $(TOP_DIR)/tests/*.tcl \
$(DISTDIR)/tests
- mkdir $(DISTDIR)/win
+ @mkdir $(DISTDIR)/win
cp $(TOP_DIR)/win/Makefile.in $(DISTDIR)/win
cp $(TOP_DIR)/win/configure.in $(TOP_DIR)/win/configure \
$(TOP_DIR)/win/tclConfig.sh.in $(TOP_DIR)/win/tclooConfig.sh \
@@ -1965,51 +2020,48 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M
cp -p $(TOP_DIR)/win/*.[ch] $(TOP_DIR)/win/*.ico $(TOP_DIR)/win/*.rc \
$(DISTDIR)/win
cp -p $(TOP_DIR)/win/*.bat $(DISTDIR)/win
- $(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/*.bat
+ @$(EOLFIX) -crlf $(DISTDIR)/win/*.bat
cp -p $(TOP_DIR)/win/makefile.* $(DISTDIR)/win
- $(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/makefile.*
+ @$(EOLFIX) -crlf $(DISTDIR)/win/makefile.bc $(DISTDIR)/win/makefile.vc
cp -p $(TOP_DIR)/win/rules.vc $(DISTDIR)/win
- $(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/rules.vc
+ @$(EOLFIX) -crlf $(DISTDIR)/win/rules.vc
cp -p $(TOP_DIR)/win/coffbase.txt $(DISTDIR)/win
- $(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/coffbase.txt
+ @$(EOLFIX) -crlf $(DISTDIR)/win/coffbase.txt
cp -p $(TOP_DIR)/win/tcl.hpj.in $(DISTDIR)/win
- $(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/tcl.hpj.in
+ @$(EOLFIX) -crlf $(DISTDIR)/win/tcl.hpj.in
cp -p $(TOP_DIR)/win/tcl.ds* $(DISTDIR)/win
- $(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/tcl.ds*
+ @$(EOLFIX) -crlf $(DISTDIR)/win/tcl.ds*
cp -p $(TOP_DIR)/win/README $(DISTDIR)/win
cp -p $(TOP_DIR)/license.terms $(DISTDIR)/win
- mkdir $(DISTDIR)/macosx
+ @mkdir $(DISTDIR)/macosx
cp -p $(MAC_OSX_DIR)/GNUmakefile $(MAC_OSX_DIR)/README \
$(MAC_OSX_DIR)/*.c $(MAC_OSX_DIR)/*.in \
$(MAC_OSX_DIR)/*.ac $(MAC_OSX_DIR)/*.xcconfig \
$(MAC_OSX_DIR)/configure $(DISTDIR)/macosx
cp -p $(TOP_DIR)/license.terms $(DISTDIR)/macosx
- mkdir $(DISTDIR)/macosx/Tcl.xcode
+ @mkdir $(DISTDIR)/macosx/Tcl.xcode
cp -p $(MAC_OSX_DIR)/Tcl.xcode/project.pbxproj \
$(MAC_OSX_DIR)/Tcl.xcode/default.pbxuser \
$(DISTDIR)/macosx/Tcl.xcode
- mkdir $(DISTDIR)/macosx/Tcl.xcodeproj
+ @mkdir $(DISTDIR)/macosx/Tcl.xcodeproj
cp -p $(MAC_OSX_DIR)/Tcl.xcodeproj/project.pbxproj \
$(MAC_OSX_DIR)/Tcl.xcodeproj/default.pbxuser \
$(DISTDIR)/macosx/Tcl.xcodeproj
- mkdir $(DISTDIR)/unix/dltest
+ @mkdir $(DISTDIR)/unix/dltest
cp -p $(UNIX_DIR)/dltest/*.c $(UNIX_DIR)/dltest/Makefile.in \
- $(UNIX_DIR)/dltest/README \
- $(DISTDIR)/unix/dltest
- mkdir $(DISTDIR)/tools
+ $(UNIX_DIR)/dltest/README $(DISTDIR)/unix/dltest
+ @mkdir $(DISTDIR)/tools
cp -p $(TOOL_DIR)/Makefile.in $(TOOL_DIR)/README \
$(TOOL_DIR)/configure $(TOOL_DIR)/configure.in \
$(TOOL_DIR)/*.tcl $(TOOL_DIR)/man2tcl.c \
- $(TOOL_DIR)/tcl.wse.in $(TOOL_DIR)/*.bmp \
- $(TOOL_DIR)/tcl.hpj.in \
+ $(TOOL_DIR)/*.bmp $(TOOL_DIR)/tcl.hpj.in \
$(DISTDIR)/tools
- $(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/tools/tcl.hpj.in \
- $(DISTDIR)/tools/tcl.wse.in
- mkdir $(DISTDIR)/libtommath
- cp -p $(TOMMATH_SRCS) $(TOMMATH_DIR)/*.h \
- $(DISTDIR)/libtommath
- mkdir $(DISTDIR)/pkgs
+ @$(EOLFIX) -crlf $(DISTDIR)/tools/tcl.hpj.in
+ @mkdir $(DISTDIR)/libtommath
+ cp -p $(TOMMATH_SRCS) $(TOMMATH_DIR)/*.h $(DISTDIR)/libtommath
+ @mkdir $(DISTDIR)/pkgs
cp $(TOP_DIR)/pkgs/README $(DISTDIR)/pkgs
+ cp $(TOP_DIR)/pkgs/package.list.txt $(DISTDIR)/pkgs
for i in `ls $(DISTROOT)/pkgs/*.tar.gz 2> /dev/null`; do \
tar -C $(DISTDIR)/pkgs -xzf "$$i"; \
done
@@ -2029,6 +2081,9 @@ alldist: dist
# build of this HTML documentation that has already been placed online. As
# such, this rule is not guaranteed to work well on all systems; it only needs
# to function on those of the Tcl/Tk maintainers.
+#
+# Also note that the 8.6 tool build requires an installed 8.6 native Tcl
+# interpreter in order to be able to run.
#--------------------------------------------------------------------------
html: ${NATIVE_TCLSH}
@@ -2041,9 +2096,12 @@ html-tk: ${NATIVE_TCLSH}
$(BUILD_HTML) --tk
@EXTRA_BUILD_HTML@
+# You'd better have these programs or you will have problems creating Makefile
+# from Makefile.in in the first place...
+HTML_VERSION = `basename $(TOP_DIR) | sed s/tcl//`
BUILD_HTML = \
@${NATIVE_TCLSH} $(TOOL_DIR)/tcltk-man2html.tcl \
- --htmldir="$(HTML_INSTALL_DIR)" \
+ --useversion=$(HTML_VERSION) --htmldir="$(HTML_INSTALL_DIR)" \
--srcdir=$(TOP_DIR)/.. $(BUILD_HTML_FLAGS)
#--------------------------------------------------------------------------
diff --git a/unix/README b/unix/README
index 87b151a..d8f1090 100644
--- a/unix/README
+++ b/unix/README
@@ -163,6 +163,7 @@ you'll see a much more substantial printout for each error. See the README
file in the "tests" directory for more information on the test suite. Note:
don't run the tests as superuser: this will cause several of them to fail. If
a test is failing consistently, please send us a bug report with as much
-detail as you can manage. Please use the online database at
- http://tcl.sourceforge.net/
+detail as you can manage to our tracker:
+
+ http://core.tcl.tk/tcl/reportlist
diff --git a/unix/configure b/unix/configure
index 72d704d..cfa8451 100755
--- a/unix/configure
+++ b/unix/configure
@@ -308,7 +308,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS MAN_FLAGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP TCL_THREADS TCLSH_PROG ZLIB_DIR ZLIB_OBJS ZLIB_SRCS ZLIB_INCLUDE RANLIB ac_ct_RANLIB AR ac_ct_AR LIBOBJS TCL_LIBS DL_LIBS DL_OBJS PLAT_OBJS PLAT_SRCS LDAIX_SRC CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING LDFLAGS_DEBUG LDFLAGS_OPTIMIZE CC_SEARCH_FLAGS LD_SEARCH_FLAGS STLIB_LD SHLIB_LD TCL_SHLIB_LD_EXTRAS TK_SHLIB_LD_EXTRAS SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX MAKE_LIB MAKE_STUB_LIB INSTALL_LIB DLL_INSTALL_DIR INSTALL_STUB_LIB CFLAGS_DEFAULT LDFLAGS_DEFAULT DTRACE TCL_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL TCL_YEAR PKG_CFG_ARGS TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_INCLUDE_SPEC TCL_BUILD_STUB_LIB_SPEC TCL_BUILD_STUB_LIB_PATH TCL_SRC_DIR CFG_TCL_SHARED_LIB_SUFFIX CFG_TCL_UNSHARED_LIB_SUFFIX TCL_SHARED_BUILD LD_LIBRARY_PATH_VAR TCL_BUILD_LIB_SPEC TCL_LIB_VERSIONS_OK TCL_SHARED_LIB_SUFFIX TCL_UNSHARED_LIB_SUFFIX TCL_HAS_LONGLONG INSTALL_TZDATA DTRACE_SRC DTRACE_HDR DTRACE_OBJ MAKEFILE_SHELL BUILD_DLTEST TCL_PACKAGE_PATH TCL_MODULE_PATH TCL_LIBRARY PRIVATE_INCLUDE_DIR HTML_DIR PACKAGE_DIR EXTRA_CC_SWITCHES EXTRA_APP_CC_SWITCHES EXTRA_INSTALL EXTRA_INSTALL_BINARIES EXTRA_BUILD_HTML EXTRA_TCLSH_LIBS DLTEST_LD DLTEST_SUFFIX'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS MAN_FLAGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP TCL_THREADS TCLSH_PROG ZLIB_OBJS ZLIB_SRCS ZLIB_INCLUDE RANLIB ac_ct_RANLIB AR ac_ct_AR LIBOBJS TCL_LIBS DL_LIBS DL_OBJS PLAT_OBJS PLAT_SRCS LDAIX_SRC CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING LDFLAGS_DEBUG LDFLAGS_OPTIMIZE CC_SEARCH_FLAGS LD_SEARCH_FLAGS STLIB_LD SHLIB_LD TCL_SHLIB_LD_EXTRAS TK_SHLIB_LD_EXTRAS SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX MAKE_LIB MAKE_STUB_LIB INSTALL_LIB DLL_INSTALL_DIR INSTALL_STUB_LIB CFLAGS_DEFAULT LDFLAGS_DEFAULT DTRACE TCL_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL TCL_YEAR PKG_CFG_ARGS TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_INCLUDE_SPEC TCL_BUILD_STUB_LIB_SPEC TCL_BUILD_STUB_LIB_PATH TCL_SRC_DIR CFG_TCL_SHARED_LIB_SUFFIX CFG_TCL_UNSHARED_LIB_SUFFIX TCL_SHARED_BUILD LD_LIBRARY_PATH_VAR TCL_BUILD_LIB_SPEC TCL_LIB_VERSIONS_OK TCL_SHARED_LIB_SUFFIX TCL_UNSHARED_LIB_SUFFIX TCL_HAS_LONGLONG INSTALL_TZDATA DTRACE_SRC DTRACE_HDR DTRACE_OBJ MAKEFILE_SHELL BUILD_DLTEST TCL_PACKAGE_PATH TCL_MODULE_PATH TCL_LIBRARY PRIVATE_INCLUDE_DIR HTML_DIR PACKAGE_DIR EXTRA_CC_SWITCHES EXTRA_APP_CC_SWITCHES EXTRA_INSTALL EXTRA_INSTALL_BINARIES EXTRA_BUILD_HTML EXTRA_TCLSH_LIBS DLTEST_LD DLTEST_SUFFIX'
ac_subst_files=''
# Initialize some variables set by options.
@@ -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="b2"
+TCL_PATCH_LEVEL=".1"
VERSION=${TCL_VERSION}
#------------------------------------------------------------------------
@@ -1353,6 +1353,14 @@ if test -r "$cache_file" -a -f "$cache_file"; then
fi
#------------------------------------------------------------------------
+# Empty slate for bundled packages, to avoid stale configuration
+#------------------------------------------------------------------------
+#rm -Rf pkgs
+if test -f Makefile; then
+ make distclean-packages
+fi
+
+#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------
@@ -4813,7 +4821,11 @@ echo "$as_me: WARNING: Don't know how to find pthread lib on your system - you m
# Does the pthread-implementation provide
# 'pthread_attr_setstacksize' ?
-for ac_func in pthread_attr_setstacksize
+ ac_saved_libs=$LIBS
+ LIBS="$LIBS $THREADS_LIBS"
+
+
+for ac_func in pthread_attr_setstacksize pthread_atfork
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -4914,6 +4926,7 @@ _ACEOF
fi
done
+ LIBS=$ac_saved_libs
else
TCL_THREADS=0
fi
@@ -6332,8 +6345,6 @@ fi
if test $zlib_ok = no; then
- ZLIB_DIR=\${COMPAT_DIR}/zlib
-
ZLIB_OBJS=\${ZLIB_OBJS}
ZLIB_SRCS=\${ZLIB_SRCS}
@@ -6479,80 +6490,6 @@ if test "${tcl_cv_cc_visibility_hidden+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- if test "$SHARED_BUILD" = 1; then
-
- hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -fvisibility=hidden -Werror"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-#if !defined(__GNUC__) || __GNUC__ < 4
-#error visibility hidden is not supported for this compiler
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- tcl_cv_cc_visibility_hidden=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cc_visibility_hidden=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- CFLAGS=$hold_cflags
-
-else
-
- tcl_cv_cc_visibility_hidden=no
-
-fi
-
-
-fi
-echo "$as_me:$LINENO: result: $tcl_cv_cc_visibility_hidden" >&5
-echo "${ECHO_T}$tcl_cv_cc_visibility_hidden" >&6
- if test $tcl_cv_cc_visibility_hidden = yes; then
-
- CFLAGS="$CFLAGS -fvisibility=hidden"
-
-cat >>confdefs.h <<\_ACEOF
-#define MODULE_SCOPE extern
-_ACEOF
-
-
-else
-
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -6603,7 +6540,10 @@ fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
CFLAGS=$hold_cflags
- if test $tcl_cv_cc_visibility_hidden = yes; then
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_visibility_hidden" >&5
+echo "${ECHO_T}$tcl_cv_cc_visibility_hidden" >&6
+ if test $tcl_cv_cc_visibility_hidden = yes; then
cat >>confdefs.h <<\_ACEOF
@@ -6611,7 +6551,9 @@ cat >>confdefs.h <<\_ACEOF
_ACEOF
-fi
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_HIDDEN 1
+_ACEOF
fi
@@ -7053,14 +6995,98 @@ fi
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
;;
- CYGWIN_*)
+ CYGWIN_*|MINGW32*)
SHLIB_CFLAGS=""
SHLIB_LD='${CC} -shared'
SHLIB_SUFFIX=".dll"
DL_OBJS="tclLoadDl.o"
+ PLAT_OBJS='${CYGWIN_OBJS}'
+ PLAT_SRCS='${CYGWIN_SRCS}'
DL_LIBS="-ldl"
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
+ TCL_NEEDS_EXP_FILE=1
+ TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.dll.a'
+ TCL_SHLIB_LD_EXTRAS='-Wl,--out-implib,$@.a'
+ TK_SHLIB_LD_EXTRAS='-Wl,--out-implib,$@.a'
+ echo "$as_me:$LINENO: checking for Cygwin version of gcc" >&5
+echo $ECHO_N "checking for Cygwin version of gcc... $ECHO_C" >&6
+if test "${ac_cv_cygwin+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+ #ifdef __CYGWIN__
+ #error cygwin
+ #endif
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_cygwin=no
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_cygwin=yes
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cygwin" >&5
+echo "${ECHO_T}$ac_cv_cygwin" >&6
+ if test "$ac_cv_cygwin" = "no"; then
+ { { echo "$as_me:$LINENO: error: ${CC} is not a cygwin compiler." >&5
+echo "$as_me: error: ${CC} is not a cygwin compiler." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ if test "x${TCL_THREADS}" = "x0"; then
+ { { echo "$as_me:$LINENO: error: CYGWIN compile is only supported with --enable-threads" >&5
+echo "$as_me: error: CYGWIN compile is only supported with --enable-threads" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ do64bit_ok=yes
+ if test "x${SHARED_BUILD}" = "x1"; then
+ echo "running cd ../win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args"
+ # The eval makes quoting arguments work.
+ if cd ../win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix
+ then :
+ else
+ { echo "configure: error: configure failed for ../win" 1>&2; exit 1; }
+ fi
+ fi
;;
dgux*)
SHLIB_CFLAGS="-K PIC"
@@ -7495,7 +7521,7 @@ fi
fi
;;
- Linux*)
+ Linux*|GNU*|NetBSD-Debian)
SHLIB_CFLAGS="-fPIC"
SHLIB_SUFFIX=".so"
@@ -7601,21 +7627,6 @@ fi
fi
;;
- GNU*)
- SHLIB_CFLAGS="-fPIC"
- SHLIB_SUFFIX=".so"
-
- SHLIB_LD='${CC} -shared'
- DL_OBJS=""
- DL_LIBS="-ldl"
- LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- if test "`uname -m`" = "alpha"; then
- CFLAGS="$CFLAGS -mieee"
-fi
-
- ;;
Lynx*)
SHLIB_CFLAGS="-fPIC"
SHLIB_SUFFIX=".so"
@@ -7652,71 +7663,15 @@ fi
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
;;
- NetBSD-1.*|FreeBSD-[1-2].*)
- SHLIB_CFLAGS="-fPIC"
- SHLIB_LD="ld -Bshareable -x"
- SHLIB_SUFFIX=".so"
- DL_OBJS="tclLoadDl.o"
- DL_LIBS=""
- if test $doRpath = yes; then
-
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
-fi
-
- echo "$as_me:$LINENO: checking for ELF" >&5
-echo $ECHO_N "checking for ELF... $ECHO_C" >&6
-if test "${tcl_cv_ld_elf+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-#ifdef __ELF__
- yes
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "yes" >/dev/null 2>&1; then
- tcl_cv_ld_elf=yes
-else
- tcl_cv_ld_elf=no
-fi
-rm -f conftest*
-
-fi
-echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5
-echo "${ECHO_T}$tcl_cv_ld_elf" >&6
- if test $tcl_cv_ld_elf = yes; then
-
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
-
-else
-
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
-
-fi
-
-
- # Ancient FreeBSD doesn't handle version numbers with dots.
-
- UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
- TCL_LIB_VERSIONS_OK=nodots
- ;;
OpenBSD-*)
arch=`arch -s`
case "$arch" in
- m88k|vax)
+ vax)
# Equivalent using configure option --disable-load
# Step 4 will set the necessary variables
DL_OBJS=""
SHLIB_LD_LIBS=""
+ LDFLAGS=""
;;
*)
SHLIB_CFLAGS="-fPIC"
@@ -7731,10 +7686,11 @@ fi
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
+ LDFLAGS="-Wl,-export-dynamic"
;;
esac
case "$arch" in
- m88k|vax)
+ vax)
CFLAGS_OPTIMIZE="-O1"
;;
sh)
@@ -7744,43 +7700,6 @@ fi
CFLAGS_OPTIMIZE="-O2"
;;
esac
- echo "$as_me:$LINENO: checking for ELF" >&5
-echo $ECHO_N "checking for ELF... $ECHO_C" >&6
-if test "${tcl_cv_ld_elf+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-#ifdef __ELF__
- yes
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "yes" >/dev/null 2>&1; then
- tcl_cv_ld_elf=yes
-else
- tcl_cv_ld_elf=no
-fi
-rm -f conftest*
-
-fi
-echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5
-echo "${ECHO_T}$tcl_cv_ld_elf" >&6
- if test $tcl_cv_ld_elf = yes; then
-
- LDFLAGS=-Wl,-export-dynamic
-
-else
- LDFLAGS=""
-fi
-
if test "${TCL_THREADS}" = "1"; then
# On OpenBSD: Compile with -pthread
@@ -7794,9 +7713,8 @@ fi
UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
TCL_LIB_VERSIONS_OK=nodots
;;
- NetBSD-*|FreeBSD-[3-4].*)
- # FreeBSD 3.* and greater have ELF.
- # NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs
+ 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"
@@ -7818,20 +7736,13 @@ fi
fi
- case $system in
- FreeBSD-3.*)
- # FreeBSD-3 doesn't handle version numbers with dots.
- UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
- TCL_LIB_VERSIONS_OK=nodots
- ;;
- esac
;;
FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
- TCL_SHLIB_LD_EXTRAS="-soname \$@"
+ TCL_SHLIB_LD_EXTRAS="-Wl,-soname=\$@"
+ TK_SHLIB_LD_EXTRAS="-Wl,-soname,\$@"
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS=""
@@ -7839,7 +7750,7 @@ fi
if test $doRpath = yes; then
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
if test "${TCL_THREADS}" = "1"; then
@@ -7850,11 +7761,15 @@ fi
LDFLAGS="$LDFLAGS $PTHREAD_LIBS"
fi
- # Version numbers are dot-stripped by system policy.
- TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
- UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
- TCL_LIB_VERSIONS_OK=nodots
+ case $system in
+ FreeBSD-3.*)
+ # Version numbers are dot-stripped by system policy.
+ TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ esac
;;
Darwin-*)
CFLAGS_OPTIMIZE="-Os"
@@ -8167,7 +8082,6 @@ cat >>confdefs.h <<\_ACEOF
#define MODULE_SCOPE __private_extern__
_ACEOF
- tcl_cv_cc_visibility_hidden=yes
fi
@@ -8678,7 +8592,7 @@ else
arch=`isainfo`
echo "$as_me:$LINENO: checking whether to use -lsunmath for fp rounding control" >&5
echo $ECHO_N "checking whether to use -lsunmath for fp rounding control... $ECHO_C" >&6
- if test "$arch" = "amd64 i386"; then
+ if test "$arch" = "amd64 i386" -o "$arch" = "i386"; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
@@ -8877,7 +8791,7 @@ else
fi
case $system in
- SunOS-5.[1-9][0-9]*)
+ SunOS-5.[1-9][0-9]*|SunOS-5.[7-9])
SHLIB_LD="\${CC} -G -z $textmode \${LDFLAGS}";;
*)
SHLIB_LD="/usr/ccs/bin/ld -G -z $textmode";;
@@ -9030,7 +8944,7 @@ fi
case $system in
AIX-*) ;;
BSD/OS*) ;;
- CYGWIN_*) ;;
+ CYGWIN_*|MINGW32_*) ;;
IRIX*) ;;
NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
@@ -9048,11 +8962,6 @@ cat >>confdefs.h <<\_ACEOF
_ACEOF
-cat >>confdefs.h <<\_ACEOF
-#define NO_VIZ
-_ACEOF
-
-
fi
@@ -9066,20 +8975,20 @@ fi
UNSHARED_LIB_SUFFIX='${VERSION}.a'
fi
- DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)"
+ DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)"
if test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""; then
LIB_SUFFIX=${SHARED_LIB_SUFFIX}
- MAKE_LIB='${SHLIB_LD} -o $@ ${OBJS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}'
+ MAKE_LIB='${SHLIB_LD} -o $@ ${OBJS} ${TCL_SHLIB_LD_EXTRAS} ${SHLIB_LD_LIBS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}'
if test "${SHLIB_SUFFIX}" = ".dll"; then
- INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)"/$(LIB_FILE)'
+ INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)"'
DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)"
else
- INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)"/$(LIB_FILE)'
+ INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'
fi
@@ -9091,12 +9000,12 @@ else
if test "$RANLIB" = ""; then
MAKE_LIB='$(STLIB_LD) $@ ${OBJS}'
- INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)"/$(LIB_FILE)'
+ INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'
else
MAKE_LIB='${STLIB_LD} $@ ${OBJS} ; ${RANLIB} $@'
- INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)"/$(LIB_FILE) ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(LIB_FILE))'
+ INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(LIB_FILE))'
fi
@@ -9113,7 +9022,7 @@ fi
else
MAKE_STUB_LIB='${STLIB_LD} $@ ${STUB_LIB_OBJS} ; ${RANLIB} $@'
- INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)"/$(STUB_LIB_FILE) ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(STUB_LIB_FILE))'
+ INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(STUB_LIB_FILE))'
fi
@@ -9128,6 +9037,75 @@ fi
+ # See if the compiler supports casting to a union type.
+ # This is used to stop gcc from printing a compiler
+ # warning when initializing a union member.
+
+ echo "$as_me:$LINENO: checking for cast to union support" >&5
+echo $ECHO_N "checking for cast to union support... $ECHO_C" >&6
+if test "${tcl_cv_cast_to_union+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ union foo { int i; double d; };
+ union foo f = (union foo) (int) 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ tcl_cv_cast_to_union=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cast_to_union=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cast_to_union" >&5
+echo "${ECHO_T}$tcl_cv_cast_to_union" >&6
+ if test "$tcl_cv_cast_to_union" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_CAST_TO_UNION 1
+_ACEOF
+
+ fi
+
# FIXME: This subst was left in only because the TCL_DL_LIBS
# entry in tclConfig.sh uses it. It is not clear why someone
# would use TCL_DL_LIBS instead of TCL_LIBS.
@@ -9184,6 +9162,11 @@ fi;
if test "$tcl_ok" = "no"; then
CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
+
+cat >>confdefs.h <<\_ACEOF
+#define NDEBUG 1
+_ACEOF
+
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
@@ -9201,12 +9184,6 @@ echo "${ECHO_T}yes (standard debugging)" >&6
fi
- ### FIXME: Surely TCL_CFG_DEBUG should be set to whether we're debugging?
-
-cat >>confdefs.h <<\_ACEOF
-#define TCL_CFG_DEBUG 1
-_ACEOF
-
if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
@@ -9719,7 +9696,7 @@ cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <sys/types.h>
-#include <sys/dirent.h>
+#include <dirent.h>
int
main ()
{
@@ -13089,14 +13066,16 @@ fi
fi
#---------------------------------------------------------------------------
-# 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.
+# Check for serial port interface.
+#
+# termios.h is present on all POSIX systems.
+# sys/ioctl.h is almost always present, though what it contains
+# is system-specific.
+# sys/modem.h is needed on HP-UX.
#---------------------------------------------------------------------------
-
-for ac_header in sys/modem.h
+for ac_header in termios.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -13245,310 +13224,305 @@ fi
done
- echo "$as_me:$LINENO: checking termios vs. termio vs. sgtty" >&5
-echo $ECHO_N "checking termios vs. termio vs. sgtty... $ECHO_C" >&6
-if test "${tcl_cv_api_serial+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- tcl_cv_api_serial=no
+for ac_header in sys/ioctl.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
else
- cat >conftest.$ac_ext <<_ACEOF
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-
-#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;
-}
+$ac_includes_default
+#include <$ac_header>
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+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='./conftest$ac_exeext'
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$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_api_serial=termios
-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_api_serial=no
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
- if test $tcl_cv_api_serial = no ; then
- if test "$cross_compiling" = yes; then
- tcl_cv_api_serial=no
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-#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;
-}
-_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'
+ (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_api_serial=termio
+ ac_header_compiler=yes
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+ echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-tcl_cv_api_serial=no
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ac_header_compiler=no
fi
- fi
- if test $tcl_cv_api_serial = no ; then
- if test "$cross_compiling" = yes; then
- tcl_cv_api_serial=no
-else
- cat >conftest.$ac_ext <<_ACEOF
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-
-#include <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;
-}
+#include <$ac_header>
_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
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- tcl_cv_api_serial=sgtty
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-tcl_cv_api_serial=no
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ ac_header_preproc=no
fi
- fi
- if test $tcl_cv_api_serial = no ; then
- if test "$cross_compiling" = yes; then
- tcl_cv_api_serial=no
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
-#include <termios.h>
-#include <errno.h>
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------ ##
+## Report this to the tcl lists. ##
+## ------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-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;
-}
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- tcl_cv_api_serial=termios
-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_api_serial=no
fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+
+done
+
+
+for ac_header in sys/modem.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
fi
- fi
- if test $tcl_cv_api_serial = no; then
- if test "$cross_compiling" = yes; then
- tcl_cv_api_serial=no
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
else
- cat >conftest.$ac_ext <<_ACEOF
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-
-#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;
- }
+$ac_includes_default
+#include <$ac_header>
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+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='./conftest$ac_exeext'
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&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_api_serial=termio
+ ac_header_compiler=yes
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+ echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-tcl_cv_api_serial=no
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ac_header_compiler=no
fi
- fi
- if test $tcl_cv_api_serial = no; then
- if test "$cross_compiling" = yes; then
- tcl_cv_api_serial=none
-else
- cat >conftest.$ac_ext <<_ACEOF
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-
-#include <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;
-}
+#include <$ac_header>
_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
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- tcl_cv_api_serial=sgtty
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-tcl_cv_api_serial=none
+ ac_header_preproc=no
fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------ ##
+## Report this to the tcl lists. ##
+## ------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
fi
- fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_serial" >&5
-echo "${ECHO_T}$tcl_cv_api_serial" >&6
- case $tcl_cv_api_serial in
- termios)
-cat >>confdefs.h <<\_ACEOF
-#define USE_TERMIOS 1
-_ACEOF
-;;
- termio)
-cat >>confdefs.h <<\_ACEOF
-#define USE_TERMIO 1
-_ACEOF
-;;
- sgtty)
-cat >>confdefs.h <<\_ACEOF
-#define USE_SGTTY 1
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
-;;
- esac
+
+fi
+
+done
#--------------------------------------------------------------------
@@ -14252,7 +14226,8 @@ _ACEOF
# lack blkcnt_t.
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking for struct stat.st_blocks" >&5
+if test "$ac_cv_cygwin" != "yes"; then
+ echo "$as_me:$LINENO: checking for struct stat.st_blocks" >&5
echo $ECHO_N "checking for struct stat.st_blocks... $ECHO_C" >&6
if test "${ac_cv_member_struct_stat_st_blocks+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -14471,6 +14446,7 @@ _ACEOF
fi
+fi
echo "$as_me:$LINENO: checking for blkcnt_t" >&5
echo $ECHO_N "checking for blkcnt_t... $ECHO_C" >&6
if test "${ac_cv_type_blkcnt_t+set}" = set; then
@@ -16550,112 +16526,12 @@ fi
# The code below deals with several issues related to gettimeofday:
# 1. Some systems don't provide a gettimeofday function at all
# (set NO_GETTOD if this is the case).
-# 2. SGI systems don't use the BSD form of the gettimeofday function,
-# but they have a BSDgettimeofday function that can be used instead.
-# 3. See if gettimeofday is declared in the <sys/time.h> header file.
+# 2. See if gettimeofday is declared in the <sys/time.h> header file.
# if not, set the GETTOD_NOT_DECLARED flag so that tclPort.h can
# declare it.
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking for BSDgettimeofday" >&5
-echo $ECHO_N "checking for BSDgettimeofday... $ECHO_C" >&6